1 -----------------------------------------------------------------------------
2 -- $Id: DriverPhases.hs,v 1.38 2005/05/17 11:01:59 simonmar Exp $
6 -- (c) The University of Glasgow 2002
8 -----------------------------------------------------------------------------
11 -- The above warning supression flag is a temporary kludge.
12 -- While working on this module you are encouraged to remove it and fix
13 -- any warnings in the module. See
14 -- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
18 HscSource(..), isHsBoot, hscSourceString,
20 happensBefore, eqPhase, anyHsc, isStopLn,
21 startPhase, -- :: String -> Phase
22 phaseInputExt, -- :: Phase -> String
30 isHaskellUserSrcSuffix,
39 isHaskellUserSrcFilename,
40 isSourceFilename -- :: FilePath -> Bool
43 import Util ( suffixOf )
44 import Panic ( panic )
46 -----------------------------------------------------------------------------
50 Phase of the | Suffix saying | Flag saying | (suffix of)
51 compilation system | ``start here''| ``stop after''| output file
53 literate pre-processor | .lhs | - | -
54 C pre-processor (opt.) | - | -E | -
55 Haskell compiler | .hs | -C, -S | .hc, .s
56 C compiler (opt.) | .hc or .c | -S | .s
57 assembler | .s or .S | -c | .o
58 linker | other | - | a.out
62 = HsSrcFile | HsBootFile | ExtCoreFile
63 deriving( Eq, Ord, Show )
64 -- Ord needed for the finite maps we build in CompManager
67 hscSourceString :: HscSource -> String
68 hscSourceString HsSrcFile = ""
69 hscSourceString HsBootFile = "[boot]"
70 hscSourceString ExtCoreFile = "[ext core]"
72 isHsBoot :: HscSource -> Bool
73 isHsBoot HsBootFile = True
74 isHsBoot other = False
83 | HCc -- Haskellised C (as opposed to vanilla C) compilation
84 | Mangle -- assembly mangling, now done by a separate script.
85 | SplitMangle -- after mangler if splitting
88 | CmmCpp -- pre-process Cmm source
89 | Cmm -- parse & compile Cmm code
91 -- The final phase is a pseudo-phase that tells the pipeline to stop.
92 -- There is no runPhase case for it.
93 | StopLn -- Stop, but linking will follow, so generate .o file
97 anyHsc = Hsc (panic "anyHsc")
99 isStopLn :: Phase -> Bool
100 isStopLn StopLn = True
101 isStopLn other = False
103 eqPhase :: Phase -> Phase -> Bool
104 -- Equality of constructors, ignoring the HscSource field
105 -- NB: the HscSource field can be 'bot'; see anyHsc above
106 eqPhase (Unlit _) (Unlit _) = True
107 eqPhase (Cpp _) (Cpp _) = True
108 eqPhase (HsPp _) (HsPp _) = True
109 eqPhase (Hsc _) (Hsc _) = True
110 eqPhase Ccpp Ccpp = True
112 eqPhase HCc HCc = True
113 eqPhase Mangle Mangle = True
114 eqPhase SplitMangle SplitMangle = True
115 eqPhase SplitAs SplitAs = True
117 eqPhase CmmCpp CmmCpp = True
118 eqPhase Cmm Cmm = True
119 eqPhase StopLn StopLn = True
122 -- Partial ordering on phases: we want to know which phases will occur before
123 -- which others. This is used for sanity checking, to ensure that the
124 -- pipeline will stop at some point (see DriverPipeline.runPipeline).
125 StopLn `happensBefore` y = False
126 x `happensBefore` y = after_x `eqPhase` y || after_x `happensBefore` y
128 after_x = nextPhase x
130 nextPhase :: Phase -> Phase
131 -- A conservative approximation the next phase, used in happensBefore
132 nextPhase (Unlit sf) = Cpp sf
133 nextPhase (Cpp sf) = HsPp sf
134 nextPhase (HsPp sf) = Hsc sf
135 nextPhase (Hsc sf) = HCc
136 nextPhase HCc = Mangle
137 nextPhase Mangle = SplitMangle
138 nextPhase SplitMangle = As
139 nextPhase As = SplitAs
140 nextPhase SplitAs = StopLn
143 nextPhase CmmCpp = Cmm
145 nextPhase StopLn = panic "nextPhase: nothing after StopLn"
147 -- the first compilation phase for a given file is determined
149 startPhase "lhs" = Unlit HsSrcFile
150 startPhase "lhs-boot" = Unlit HsBootFile
151 startPhase "hs" = Cpp HsSrcFile
152 startPhase "hs-boot" = Cpp HsBootFile
153 startPhase "hscpp" = HsPp HsSrcFile
154 startPhase "hspp" = Hsc HsSrcFile
155 startPhase "hcr" = Hsc ExtCoreFile
156 startPhase "hc" = HCc
158 startPhase "cpp" = Ccpp
160 startPhase "cc" = Ccpp
161 startPhase "cxx" = Ccpp
162 startPhase "raw_s" = Mangle
163 startPhase "split_s" = SplitMangle
166 startPhase "o" = StopLn
167 startPhase "cmm" = CmmCpp
168 startPhase "cmmcpp" = Cmm
169 startPhase _ = StopLn -- all unknown file types
171 -- This is used to determine the extension for the output from the
172 -- current phase (if it generates a new file). The extension depends
173 -- on the next phase in the pipeline.
174 phaseInputExt (Unlit HsSrcFile) = "lhs"
175 phaseInputExt (Unlit HsBootFile) = "lhs-boot"
176 phaseInputExt (Unlit ExtCoreFile) = "lhcr"
177 phaseInputExt (Cpp _) = "lpp" -- intermediate only
178 phaseInputExt (HsPp _) = "hscpp" -- intermediate only
179 phaseInputExt (Hsc _) = "hspp" -- intermediate only
180 -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
181 -- because runPipeline uses the StopBefore phase to pick the
182 -- output filename. That could be fixed, but watch out.
183 phaseInputExt HCc = "hc"
184 phaseInputExt Ccpp = "cpp"
185 phaseInputExt Cc = "c"
186 phaseInputExt Mangle = "raw_s"
187 phaseInputExt SplitMangle = "split_s" -- not really generated
188 phaseInputExt As = "s"
189 phaseInputExt SplitAs = "split_s" -- not really generated
190 phaseInputExt CmmCpp = "cmm"
191 phaseInputExt Cmm = "cmmcpp"
192 phaseInputExt StopLn = "o"
194 haskellish_src_suffixes = haskellish_user_src_suffixes ++
195 [ "hspp", "hscpp", "hcr", "cmm" ]
196 haskellish_suffixes = haskellish_src_suffixes ++ ["hc", "raw_s"]
197 cish_suffixes = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ]
198 extcoreish_suffixes = [ "hcr" ]
199 haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ] -- Will not be deleted as temp files
201 -- Use the appropriate suffix for the system on which
202 -- the GHC-compiled code will run
203 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
204 objish_suffixes = [ "o", "O", "obj", "OBJ" ]
206 objish_suffixes = [ "o" ]
209 #ifdef mingw32_TARGET_OS
210 dynlib_suffixes = ["dll", "DLL"]
211 #elif defined(darwin_TARGET_OS)
212 dynlib_suffixes = ["dylib"]
214 dynlib_suffixes = ["so"]
217 isHaskellishSuffix s = s `elem` haskellish_suffixes
218 isHaskellSrcSuffix s = s `elem` haskellish_src_suffixes
219 isCishSuffix s = s `elem` cish_suffixes
220 isExtCoreSuffix s = s `elem` extcoreish_suffixes
221 isObjectSuffix s = s `elem` objish_suffixes
222 isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes
223 isDynLibSuffix s = s `elem` dynlib_suffixes
225 isSourceSuffix suff = isHaskellishSuffix suff || isCishSuffix suff
227 isHaskellishFilename f = isHaskellishSuffix (suffixOf f)
228 isHaskellSrcFilename f = isHaskellSrcSuffix (suffixOf f)
229 isCishFilename f = isCishSuffix (suffixOf f)
230 isExtCoreFilename f = isExtCoreSuffix (suffixOf f)
231 isObjectFilename f = isObjectSuffix (suffixOf f)
232 isHaskellUserSrcFilename f = isHaskellUserSrcSuffix (suffixOf f)
233 isDynLibFilename f = isDynLibSuffix (suffixOf f)
234 isSourceFilename f = isSourceSuffix (suffixOf f)