1 -----------------------------------------------------------------------------
2 -- $Id: DriverPhases.hs,v 1.32 2005/01/27 10:44:27 simonpj Exp $
6 -- (c) The University of Glasgow 2002
8 -----------------------------------------------------------------------------
10 #include "../includes/ghcconfig.h"
13 HscSource(..), isHsBoot, hscSourceString,
14 HscTarget(..), Phase(..),
15 happensBefore, eqPhase, anyHsc, isStopPhase,
16 startPhase, -- :: String -> Phase
17 phaseInputExt, -- :: Phase -> String
25 isHaskellUserSrcFilename,
26 isSourceFilename -- :: FilePath -> Bool
30 import Panic ( panic )
32 -----------------------------------------------------------------------------
36 Phase of the | Suffix saying | Flag saying | (suffix of)
37 compilation system | ``start here''| ``stop after''| output file
39 literate pre-processor | .lhs | - | -
40 C pre-processor (opt.) | - | -E | -
41 Haskell compiler | .hs | -C, -S | .hc, .s
42 C compiler (opt.) | .hc or .c | -S | .s
43 assembler | .s or .S | -c | .o
44 linker | other | - | a.out
48 = HsSrcFile | HsBootFile | ExtCoreFile
49 deriving( Eq, Ord, Show )
50 -- Ord needed for the finite maps we build in CompManager
53 hscSourceString :: HscSource -> String
54 hscSourceString HsSrcFile = ""
55 hscSourceString HsBootFile = "[boot]"
56 hscSourceString ExtCoreFile = "[ext core]"
58 isHsBoot :: HscSource -> Bool
59 isHsBoot HsBootFile = True
60 isHsBoot other = False
77 | HCc -- Haskellised C (as opposed to vanilla C) compilation
78 | Mangle -- assembly mangling, now done by a separate script.
79 | SplitMangle -- after mangler if splitting
82 | CmmCpp -- pre-process Cmm source
83 | Cmm -- parse & compile Cmm code
89 -- The final phase is a pseudo-phase that tells the pipeline to stop.
90 -- There is no runPhase case for it.
91 | StopLn -- Stop, but linking will follow, so generate .o file
96 anyHsc = Hsc (panic "anyHsc")
98 isStopPhase :: Phase -> Bool
99 isStopPhase StopLn = True
100 isStopPhase other = False
102 eqPhase :: Phase -> Phase -> Bool
103 -- Equality of constructors, ignoring the HscSource field
104 eqPhase (Unlit _) (Unlit _) = True
105 eqPhase (Cpp _) (Cpp _) = True
106 eqPhase (HsPp _) (HsPp _) = True
107 eqPhase (Hsc _) (Hsc _) = True
109 eqPhase HCc HCc = True
110 eqPhase Mangle Mangle = True
111 eqPhase SplitMangle SplitMangle = True
112 eqPhase SplitAs SplitAs = True
114 eqPhase CmmCpp CmmCpp = True
115 eqPhase Cmm Cmm = True
116 eqPhase StopLn StopLn = True
119 -- Partial ordering on phases: we want to know which phases will occur before
120 -- which others. This is used for sanity checking, to ensure that the
121 -- pipeline will stop at some point (see DriverPipeline.runPipeline).
122 StopLn `happensBefore` y = False
123 x `happensBefore` y = after_x `eqPhase` y || after_x `happensBefore` y
125 after_x = nextPhase x
127 nextPhase :: Phase -> Phase
128 -- A conservative approximation the next phase, used in happensBefore
129 nextPhase (Unlit sf) = Cpp sf
130 nextPhase (Cpp sf) = HsPp sf
131 nextPhase (HsPp sf) = Hsc sf
132 nextPhase (Hsc sf) = HCc
133 nextPhase HCc = Mangle
134 nextPhase Mangle = SplitMangle
135 nextPhase SplitMangle = As
136 nextPhase As = SplitAs
137 nextPhase SplitAs = StopLn
139 nextPhase CmmCpp = Cmm
141 nextPhase StopLn = panic "nextPhase: nothing after StopLn"
143 -- the first compilation phase for a given file is determined
145 startPhase "lhs" = Unlit HsSrcFile
146 startPhase "lhs-boot" = Unlit HsBootFile
147 startPhase "hs" = Cpp HsSrcFile
148 startPhase "hs-boot" = Cpp HsBootFile
149 startPhase "hscpp" = HsPp HsSrcFile
150 startPhase "hspp" = Hsc HsSrcFile
151 startPhase "hcr" = Hsc ExtCoreFile
152 startPhase "hc" = HCc
154 startPhase "cpp" = Cc
157 startPhase "cxx" = Cc
158 startPhase "raw_s" = Mangle
161 startPhase "o" = StopLn
162 startPhase "cmm" = CmmCpp
163 startPhase "cmmcpp" = Cmm
164 startPhase _ = StopLn -- all unknown file types
166 -- This is used to determine the extension for the output from the
167 -- current phase (if it generates a new file). The extension depends
168 -- on the next phase in the pipeline.
169 phaseInputExt (Unlit HsSrcFile) = "lhs"
170 phaseInputExt (Unlit HsBootFile) = "lhs-boot"
171 phaseInputExt (Unlit ExtCoreFile) = "lhcr"
172 phaseInputExt (Cpp _) = "lpp" -- intermediate only
173 phaseInputExt (HsPp _) = "hscpp" -- intermediate only
174 phaseInputExt (Hsc _) = "hspp" -- intermediate only
175 -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
176 -- because runPipeline uses the StopBefore phase to pick the
177 -- output filename. That could be fixed, but watch out.
178 phaseInputExt HCc = "hc"
179 phaseInputExt Cc = "c"
180 phaseInputExt Mangle = "raw_s"
181 phaseInputExt SplitMangle = "split_s" -- not really generated
182 phaseInputExt As = "s"
183 phaseInputExt SplitAs = "split_s" -- not really generated
184 phaseInputExt CmmCpp = "cmm"
185 phaseInputExt Cmm = "cmmcpp"
186 phaseInputExt StopLn = "o"
188 phaseInputExt Ilx2Il = "ilx"
189 phaseInputExt Ilasm = "il"
192 haskellish_src_suffixes = haskellish_user_src_suffixes ++
193 [ "hspp", "hscpp", "hcr", "cmm" ]
194 haskellish_suffixes = haskellish_src_suffixes ++ ["hc", "raw_s"]
195 cish_suffixes = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ]
196 extcoreish_suffixes = [ "hcr" ]
197 haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ] -- Will not be deleted as temp files
199 -- Use the appropriate suffix for the system on which
200 -- the GHC-compiled code will run
201 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
202 objish_suffixes = [ "o", "O", "obj", "OBJ" ]
204 objish_suffixes = [ "o" ]
207 #ifdef mingw32_TARGET_OS
208 dynlib_suffixes = ["dll", "DLL"]
209 #elif defined(darwin_TARGET_OS)
210 dynlib_suffixes = ["dylib"]
212 dynlib_suffixes = ["so"]
215 isHaskellishFilename f = getFileSuffix f `elem` haskellish_suffixes
216 isHaskellSrcFilename f = getFileSuffix f `elem` haskellish_src_suffixes
217 isCishFilename f = getFileSuffix f `elem` cish_suffixes
218 isExtCoreFilename f = getFileSuffix f `elem` extcoreish_suffixes
219 isObjectFilename f = getFileSuffix f `elem` objish_suffixes
220 isHaskellUserSrcFilename f = getFileSuffix f `elem` haskellish_user_src_suffixes
221 isDynLibFilename f = getFileSuffix f `elem` dynlib_suffixes
223 isSourceFilename :: FilePath -> Bool
225 isHaskellishFilename f ||