Remove ILX from the GHC altogether (although I left the source file IlxGen in case...
[ghc-hetmet.git] / compiler / main / DriverPhases.hs
1 -----------------------------------------------------------------------------
2 --  $Id: DriverPhases.hs,v 1.38 2005/05/17 11:01:59 simonmar Exp $
3 --
4 -- GHC Driver
5 --
6 -- (c) The University of Glasgow 2002
7 --
8 -----------------------------------------------------------------------------
9
10 module DriverPhases (
11    HscSource(..), isHsBoot, hscSourceString,
12    Phase(..),
13    happensBefore, eqPhase, anyHsc, isStopLn,
14    startPhase,          -- :: String -> Phase
15    phaseInputExt,       -- :: Phase -> String
16
17    isHaskellishSuffix, 
18    isHaskellSrcSuffix,
19    isObjectSuffix,
20    isCishSuffix,
21    isExtCoreSuffix,
22    isDynLibSuffix,
23    isHaskellUserSrcSuffix,
24    isSourceSuffix,
25
26    isHaskellishFilename, 
27    isHaskellSrcFilename,
28    isObjectFilename,
29    isCishFilename,
30    isExtCoreFilename,
31    isDynLibFilename,
32    isHaskellUserSrcFilename,
33    isSourceFilename         -- :: FilePath -> Bool
34  ) where
35
36 import Util             ( suffixOf )
37 import Panic            ( panic )
38
39 -----------------------------------------------------------------------------
40 -- Phases
41
42 {-
43    Phase of the           | Suffix saying | Flag saying   | (suffix of)
44    compilation system     | ``start here''| ``stop after''| output file
45    
46    literate pre-processor | .lhs          | -             | -
47    C pre-processor (opt.) | -             | -E            | -
48    Haskell compiler       | .hs           | -C, -S        | .hc, .s
49    C compiler (opt.)      | .hc or .c     | -S            | .s
50    assembler              | .s  or .S     | -c            | .o
51    linker                 | other         | -             | a.out
52 -}
53
54 data HscSource
55    = HsSrcFile | HsBootFile | ExtCoreFile
56      deriving( Eq, Ord, Show )
57         -- Ord needed for the finite maps we build in CompManager
58
59
60 hscSourceString :: HscSource -> String
61 hscSourceString HsSrcFile   = ""
62 hscSourceString HsBootFile  = "[boot]"
63 hscSourceString ExtCoreFile = "[ext core]"
64
65 isHsBoot :: HscSource -> Bool
66 isHsBoot HsBootFile = True
67 isHsBoot other      = False
68
69 data Phase 
70         = Unlit HscSource
71         | Cpp   HscSource
72         | HsPp  HscSource
73         | Hsc   HscSource
74         | Ccpp
75         | Cc
76         | HCc           -- Haskellised C (as opposed to vanilla C) compilation
77         | Mangle        -- assembly mangling, now done by a separate script.
78         | SplitMangle   -- after mangler if splitting
79         | SplitAs
80         | As
81         | CmmCpp        -- pre-process Cmm source
82         | Cmm           -- parse & compile Cmm code
83
84         -- The final phase is a pseudo-phase that tells the pipeline to stop.
85         -- There is no runPhase case for it.
86         | StopLn        -- Stop, but linking will follow, so generate .o file
87   deriving (Eq, Show)
88
89 anyHsc :: Phase
90 anyHsc = Hsc (panic "anyHsc")
91
92 isStopLn :: Phase -> Bool
93 isStopLn StopLn = True
94 isStopLn other  = False
95
96 eqPhase :: Phase -> Phase -> Bool
97 -- Equality of constructors, ignoring the HscSource field
98 -- NB: the HscSource field can be 'bot'; see anyHsc above
99 eqPhase (Unlit _)   (Unlit _)   = True
100 eqPhase (Cpp   _)   (Cpp   _)   = True
101 eqPhase (HsPp  _)   (HsPp  _)   = True
102 eqPhase (Hsc   _)   (Hsc   _)   = True
103 eqPhase Ccpp        Ccpp        = True
104 eqPhase Cc          Cc          = True
105 eqPhase HCc         HCc         = True
106 eqPhase Mangle      Mangle      = True
107 eqPhase SplitMangle SplitMangle = True
108 eqPhase SplitAs     SplitAs     = True
109 eqPhase As          As          = True
110 eqPhase CmmCpp      CmmCpp      = True
111 eqPhase Cmm         Cmm         = True
112 eqPhase StopLn      StopLn      = True
113 eqPhase _           _           = False
114
115 -- Partial ordering on phases: we want to know which phases will occur before 
116 -- which others.  This is used for sanity checking, to ensure that the
117 -- pipeline will stop at some point (see DriverPipeline.runPipeline).
118 StopLn `happensBefore` y = False
119 x      `happensBefore` y = after_x `eqPhase` y || after_x `happensBefore` y
120         where
121           after_x = nextPhase x
122
123 nextPhase :: Phase -> Phase
124 -- A conservative approximation the next phase, used in happensBefore
125 nextPhase (Unlit sf)    = Cpp  sf
126 nextPhase (Cpp   sf)    = HsPp sf
127 nextPhase (HsPp  sf)    = Hsc  sf
128 nextPhase (Hsc   sf)    = HCc
129 nextPhase HCc           = Mangle
130 nextPhase Mangle        = SplitMangle
131 nextPhase SplitMangle   = As
132 nextPhase As            = SplitAs
133 nextPhase SplitAs       = StopLn
134 nextPhase Ccpp          = As
135 nextPhase Cc            = As
136 nextPhase CmmCpp        = Cmm
137 nextPhase Cmm           = HCc
138 nextPhase StopLn        = panic "nextPhase: nothing after StopLn"
139
140 -- the first compilation phase for a given file is determined
141 -- by its suffix.
142 startPhase "lhs"      = Unlit HsSrcFile
143 startPhase "lhs-boot" = Unlit HsBootFile
144 startPhase "hs"       = Cpp   HsSrcFile
145 startPhase "hs-boot"  = Cpp   HsBootFile
146 startPhase "hscpp"    = HsPp  HsSrcFile
147 startPhase "hspp"     = Hsc   HsSrcFile
148 startPhase "hcr"      = Hsc   ExtCoreFile
149 startPhase "hc"       = HCc
150 startPhase "c"        = Cc
151 startPhase "cpp"      = Ccpp
152 startPhase "C"        = Cc
153 startPhase "cc"       = Ccpp
154 startPhase "cxx"      = Ccpp
155 startPhase "raw_s"    = Mangle
156 startPhase "split_s"  = SplitMangle
157 startPhase "s"        = As
158 startPhase "S"        = As
159 startPhase "o"        = StopLn
160 startPhase "cmm"      = CmmCpp
161 startPhase "cmmcpp"   = Cmm
162 startPhase _          = StopLn     -- all unknown file types
163
164 -- This is used to determine the extension for the output from the
165 -- current phase (if it generates a new file).  The extension depends
166 -- on the next phase in the pipeline.
167 phaseInputExt (Unlit HsSrcFile)   = "lhs"
168 phaseInputExt (Unlit HsBootFile)  = "lhs-boot"
169 phaseInputExt (Unlit ExtCoreFile) = "lhcr"
170 phaseInputExt (Cpp   _)           = "lpp"       -- intermediate only
171 phaseInputExt (HsPp  _)           = "hscpp"     -- intermediate only
172 phaseInputExt (Hsc   _)           = "hspp"      -- intermediate only
173         -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
174         --     because runPipeline uses the StopBefore phase to pick the
175         --     output filename.  That could be fixed, but watch out.
176 phaseInputExt HCc                 = "hc"  
177 phaseInputExt Ccpp                = "cpp"
178 phaseInputExt Cc                  = "c"
179 phaseInputExt Mangle              = "raw_s"
180 phaseInputExt SplitMangle         = "split_s"   -- not really generated
181 phaseInputExt As                  = "s"
182 phaseInputExt SplitAs             = "split_s"   -- not really generated
183 phaseInputExt CmmCpp              = "cmm"
184 phaseInputExt Cmm                 = "cmmcpp"
185 phaseInputExt StopLn              = "o"
186
187 haskellish_src_suffixes      = haskellish_user_src_suffixes ++
188                                [ "hspp", "hscpp", "hcr", "cmm" ]
189 haskellish_suffixes          = haskellish_src_suffixes ++ ["hc", "raw_s"]
190 cish_suffixes                = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ]
191 extcoreish_suffixes          = [ "hcr" ]
192 haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]   -- Will not be deleted as temp files
193
194 -- Use the appropriate suffix for the system on which 
195 -- the GHC-compiled code will run
196 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
197 objish_suffixes     = [ "o", "O", "obj", "OBJ" ]
198 #else
199 objish_suffixes     = [ "o" ]
200 #endif
201
202 #ifdef mingw32_TARGET_OS
203 dynlib_suffixes = ["dll", "DLL"]
204 #elif defined(darwin_TARGET_OS)
205 dynlib_suffixes = ["dylib"]
206 #else
207 dynlib_suffixes = ["so"]
208 #endif
209
210 isHaskellishSuffix     s = s `elem` haskellish_suffixes
211 isHaskellSrcSuffix     s = s `elem` haskellish_src_suffixes
212 isCishSuffix           s = s `elem` cish_suffixes
213 isExtCoreSuffix        s = s `elem` extcoreish_suffixes
214 isObjectSuffix         s = s `elem` objish_suffixes
215 isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes
216 isDynLibSuffix         s = s `elem` dynlib_suffixes
217
218 isSourceSuffix suff  = isHaskellishSuffix suff || isCishSuffix suff
219
220 isHaskellishFilename     f = isHaskellishSuffix     (suffixOf f)
221 isHaskellSrcFilename     f = isHaskellSrcSuffix     (suffixOf f)
222 isCishFilename           f = isCishSuffix           (suffixOf f)
223 isExtCoreFilename        f = isExtCoreSuffix        (suffixOf f)
224 isObjectFilename         f = isObjectSuffix         (suffixOf f)
225 isHaskellUserSrcFilename f = isHaskellUserSrcSuffix (suffixOf f)
226 isDynLibFilename         f = isDynLibSuffix         (suffixOf f)
227 isSourceFilename         f = isSourceSuffix         (suffixOf f)
228
229