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 HscSource(..), isHsBoot, hscSourceString,
13 happensBefore, eqPhase, anyHsc, isStopLn,
14 startPhase, -- :: String -> Phase
15 phaseInputExt, -- :: Phase -> String
23 isHaskellUserSrcSuffix,
32 isHaskellUserSrcFilename,
33 isSourceFilename -- :: FilePath -> Bool
36 import Util ( suffixOf )
37 import Panic ( panic )
39 -----------------------------------------------------------------------------
43 Phase of the | Suffix saying | Flag saying | (suffix of)
44 compilation system | ``start here''| ``stop after''| output file
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
55 = HsSrcFile | HsBootFile | ExtCoreFile
56 deriving( Eq, Ord, Show )
57 -- Ord needed for the finite maps we build in CompManager
60 hscSourceString :: HscSource -> String
61 hscSourceString HsSrcFile = ""
62 hscSourceString HsBootFile = "[boot]"
63 hscSourceString ExtCoreFile = "[ext core]"
65 isHsBoot :: HscSource -> Bool
66 isHsBoot HsBootFile = True
67 isHsBoot other = False
75 | HCc -- Haskellised C (as opposed to vanilla C) compilation
76 | Mangle -- assembly mangling, now done by a separate script.
77 | SplitMangle -- after mangler if splitting
80 | CmmCpp -- pre-process Cmm source
81 | Cmm -- parse & compile Cmm code
83 -- The final phase is a pseudo-phase that tells the pipeline to stop.
84 -- There is no runPhase case for it.
85 | StopLn -- Stop, but linking will follow, so generate .o file
89 anyHsc = Hsc (panic "anyHsc")
91 isStopLn :: Phase -> Bool
92 isStopLn StopLn = True
93 isStopLn other = False
95 eqPhase :: Phase -> Phase -> Bool
96 -- Equality of constructors, ignoring the HscSource field
97 -- NB: the HscSource field can be 'bot'; see anyHsc above
98 eqPhase (Unlit _) (Unlit _) = True
99 eqPhase (Cpp _) (Cpp _) = True
100 eqPhase (HsPp _) (HsPp _) = True
101 eqPhase (Hsc _) (Hsc _) = True
103 eqPhase HCc HCc = True
104 eqPhase Mangle Mangle = True
105 eqPhase SplitMangle SplitMangle = True
106 eqPhase SplitAs SplitAs = True
108 eqPhase CmmCpp CmmCpp = True
109 eqPhase Cmm Cmm = True
110 eqPhase StopLn StopLn = True
113 -- Partial ordering on phases: we want to know which phases will occur before
114 -- which others. This is used for sanity checking, to ensure that the
115 -- pipeline will stop at some point (see DriverPipeline.runPipeline).
116 StopLn `happensBefore` y = False
117 x `happensBefore` y = after_x `eqPhase` y || after_x `happensBefore` y
119 after_x = nextPhase x
121 nextPhase :: Phase -> Phase
122 -- A conservative approximation the next phase, used in happensBefore
123 nextPhase (Unlit sf) = Cpp sf
124 nextPhase (Cpp sf) = HsPp sf
125 nextPhase (HsPp sf) = Hsc sf
126 nextPhase (Hsc sf) = HCc
127 nextPhase HCc = Mangle
128 nextPhase Mangle = SplitMangle
129 nextPhase SplitMangle = As
130 nextPhase As = SplitAs
131 nextPhase SplitAs = StopLn
133 nextPhase CmmCpp = Cmm
135 nextPhase StopLn = panic "nextPhase: nothing after StopLn"
137 -- the first compilation phase for a given file is determined
139 startPhase "lhs" = Unlit HsSrcFile
140 startPhase "lhs-boot" = Unlit HsBootFile
141 startPhase "hs" = Cpp HsSrcFile
142 startPhase "hs-boot" = Cpp HsBootFile
143 startPhase "hscpp" = HsPp HsSrcFile
144 startPhase "hspp" = Hsc HsSrcFile
145 startPhase "hcr" = Hsc ExtCoreFile
146 startPhase "hc" = HCc
148 startPhase "cpp" = Cc
151 startPhase "cxx" = Cc
152 startPhase "raw_s" = Mangle
155 startPhase "o" = StopLn
156 startPhase "cmm" = CmmCpp
157 startPhase "cmmcpp" = Cmm
158 startPhase _ = StopLn -- all unknown file types
160 -- This is used to determine the extension for the output from the
161 -- current phase (if it generates a new file). The extension depends
162 -- on the next phase in the pipeline.
163 phaseInputExt (Unlit HsSrcFile) = "lhs"
164 phaseInputExt (Unlit HsBootFile) = "lhs-boot"
165 phaseInputExt (Unlit ExtCoreFile) = "lhcr"
166 phaseInputExt (Cpp _) = "lpp" -- intermediate only
167 phaseInputExt (HsPp _) = "hscpp" -- intermediate only
168 phaseInputExt (Hsc _) = "hspp" -- intermediate only
169 -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
170 -- because runPipeline uses the StopBefore phase to pick the
171 -- output filename. That could be fixed, but watch out.
172 phaseInputExt HCc = "hc"
173 phaseInputExt Cc = "c"
174 phaseInputExt Mangle = "raw_s"
175 phaseInputExt SplitMangle = "split_s" -- not really generated
176 phaseInputExt As = "s"
177 phaseInputExt SplitAs = "split_s" -- not really generated
178 phaseInputExt CmmCpp = "cmm"
179 phaseInputExt Cmm = "cmmcpp"
180 phaseInputExt StopLn = "o"
182 phaseInputExt Ilx2Il = "ilx"
183 phaseInputExt Ilasm = "il"
186 haskellish_src_suffixes = haskellish_user_src_suffixes ++
187 [ "hspp", "hscpp", "hcr", "cmm" ]
188 haskellish_suffixes = haskellish_src_suffixes ++ ["hc", "raw_s"]
189 cish_suffixes = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ]
190 extcoreish_suffixes = [ "hcr" ]
191 haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ] -- Will not be deleted as temp files
193 -- Use the appropriate suffix for the system on which
194 -- the GHC-compiled code will run
195 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
196 objish_suffixes = [ "o", "O", "obj", "OBJ" ]
198 objish_suffixes = [ "o" ]
201 #ifdef mingw32_TARGET_OS
202 dynlib_suffixes = ["dll", "DLL"]
203 #elif defined(darwin_TARGET_OS)
204 dynlib_suffixes = ["dylib"]
206 dynlib_suffixes = ["so"]
209 isHaskellishSuffix s = s `elem` haskellish_suffixes
210 isHaskellSrcSuffix s = s `elem` haskellish_src_suffixes
211 isCishSuffix s = s `elem` cish_suffixes
212 isExtCoreSuffix s = s `elem` extcoreish_suffixes
213 isObjectSuffix s = s `elem` objish_suffixes
214 isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes
215 isDynLibSuffix s = s `elem` dynlib_suffixes
217 isSourceSuffix suff = isHaskellishSuffix suff || isCishSuffix suff
219 isHaskellishFilename f = isHaskellishSuffix (suffixOf f)
220 isHaskellSrcFilename f = isHaskellSrcSuffix (suffixOf f)
221 isCishFilename f = isCishSuffix (suffixOf f)
222 isExtCoreFilename f = isExtCoreSuffix (suffixOf f)
223 isObjectFilename f = isObjectSuffix (suffixOf f)
224 isHaskellUserSrcFilename f = isHaskellUserSrcSuffix (suffixOf f)
225 isDynLibFilename f = isDynLibSuffix (suffixOf f)
226 isSourceFilename f = isSourceSuffix (suffixOf f)