Merge branch 'master' of /home/simonmar/ghc-git/.
[ghc.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 #include "HsVersions.h"
37
38 import Outputable
39 import System.FilePath
40
41 -----------------------------------------------------------------------------
42 -- Phases
43
44 {-
45 Phase of the | Suffix saying | Flag saying | (suffix of)
46 compilation system | ``start here''| ``stop after''| output file
47
48 literate pre-processor | .lhs | - | -
49 C pre-processor (opt.) | - | -E | -
50 Haskell compiler | .hs | -C, -S | .hc, .s
51 C compiler (opt.) | .hc or .c | -S | .s
52 assembler | .s or .S | -c | .o
53 linker | other | - | a.out
54 -}
55
56 data HscSource
57 = HsSrcFile | HsBootFile | ExtCoreFile
58 deriving( Eq, Ord, Show )
59 -- Ord needed for the finite maps we build in CompManager
60
61
62 hscSourceString :: HscSource -> String
63 hscSourceString HsSrcFile = ""
64 hscSourceString HsBootFile = "[boot]"
65 hscSourceString ExtCoreFile = "[ext core]"
66
67 isHsBoot :: HscSource -> Bool
68 isHsBoot HsBootFile = True
69 isHsBoot _ = False
70
71 data Phase
72 = Unlit HscSource
73 | Cpp HscSource
74 | HsPp HscSource
75 | Hsc HscSource
76 | Ccpp
77 | Cc
78 | HCc -- Haskellised C (as opposed to vanilla C) compilation
79 | SplitMangle -- after mangler if splitting
80 | SplitAs
81 | As
82 | LlvmOpt -- Run LLVM opt tool over llvm assembly
83 | LlvmLlc -- LLVM bitcode to native assembly
84 | LlvmMangle -- Fix up TNTC by processing assembly produced by LLVM
85 | CmmCpp -- pre-process Cmm source
86 | Cmm -- parse & compile Cmm code
87 | MergeStub -- merge in the stub object file
88
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
92 deriving (Eq, Show)
93
94 instance Outputable Phase where
95 ppr p = text (show p)
96
97 anyHsc :: Phase
98 anyHsc = Hsc (panic "anyHsc")
99
100 isStopLn :: Phase -> Bool
101 isStopLn StopLn = True
102 isStopLn _ = False
103
104 eqPhase :: Phase -> Phase -> Bool
105 -- Equality of constructors, ignoring the HscSource field
106 -- NB: the HscSource field can be 'bot'; see anyHsc above
107 eqPhase (Unlit _) (Unlit _) = True
108 eqPhase (Cpp _) (Cpp _) = True
109 eqPhase (HsPp _) (HsPp _) = True
110 eqPhase (Hsc _) (Hsc _) = True
111 eqPhase Ccpp Ccpp = True
112 eqPhase Cc Cc = True
113 eqPhase HCc HCc = True
114 eqPhase SplitMangle SplitMangle = True
115 eqPhase SplitAs SplitAs = True
116 eqPhase As As = True
117 eqPhase LlvmOpt LlvmOpt = True
118 eqPhase LlvmLlc LlvmLlc = True
119 eqPhase LlvmMangle LlvmMangle = True
120 eqPhase CmmCpp CmmCpp = True
121 eqPhase Cmm Cmm = True
122 eqPhase MergeStub MergeStub = True
123 eqPhase StopLn StopLn = True
124 eqPhase _ _ = False
125
126 -- Partial ordering on phases: we want to know which phases will occur before
127 -- which others. This is used for sanity checking, to ensure that the
128 -- pipeline will stop at some point (see DriverPipeline.runPipeline).
129 happensBefore :: Phase -> Phase -> Bool
130 StopLn `happensBefore` _ = False
131 x `happensBefore` y = after_x `eqPhase` y || after_x `happensBefore` y
132 where
133 after_x = nextPhase x
134
135 nextPhase :: Phase -> Phase
136 -- A conservative approximation to the next phase, used in happensBefore
137 nextPhase (Unlit sf) = Cpp sf
138 nextPhase (Cpp sf) = HsPp sf
139 nextPhase (HsPp sf) = Hsc sf
140 nextPhase (Hsc _) = HCc
141 nextPhase SplitMangle = As
142 nextPhase As = SplitAs
143 nextPhase LlvmOpt = LlvmLlc
144 #if darwin_TARGET_OS
145 nextPhase LlvmLlc = LlvmMangle
146 #else
147 nextPhase LlvmLlc = As
148 #endif
149 nextPhase LlvmMangle = As
150 nextPhase SplitAs = MergeStub
151 nextPhase Ccpp = As
152 nextPhase Cc = As
153 nextPhase CmmCpp = Cmm
154 nextPhase Cmm = HCc
155 nextPhase HCc = As
156 nextPhase MergeStub = StopLn
157 nextPhase StopLn = panic "nextPhase: nothing after StopLn"
158
159 -- the first compilation phase for a given file is determined
160 -- by its suffix.
161 startPhase :: String -> Phase
162 startPhase "lhs" = Unlit HsSrcFile
163 startPhase "lhs-boot" = Unlit HsBootFile
164 startPhase "hs" = Cpp HsSrcFile
165 startPhase "hs-boot" = Cpp HsBootFile
166 startPhase "hscpp" = HsPp HsSrcFile
167 startPhase "hspp" = Hsc HsSrcFile
168 startPhase "hcr" = Hsc ExtCoreFile
169 startPhase "hc" = HCc
170 startPhase "c" = Cc
171 startPhase "cpp" = Ccpp
172 startPhase "C" = Cc
173 startPhase "cc" = Ccpp
174 startPhase "cxx" = Ccpp
175 startPhase "split_s" = SplitMangle
176 startPhase "s" = As
177 startPhase "S" = As
178 startPhase "ll" = LlvmOpt
179 startPhase "bc" = LlvmLlc
180 startPhase "lm_s" = LlvmMangle
181 startPhase "o" = StopLn
182 startPhase "cmm" = CmmCpp
183 startPhase "cmmcpp" = Cmm
184 startPhase _ = StopLn -- all unknown file types
185
186 -- This is used to determine the extension for the output from the
187 -- current phase (if it generates a new file). The extension depends
188 -- on the next phase in the pipeline.
189 phaseInputExt :: Phase -> String
190 phaseInputExt (Unlit HsSrcFile) = "lhs"
191 phaseInputExt (Unlit HsBootFile) = "lhs-boot"
192 phaseInputExt (Unlit ExtCoreFile) = "lhcr"
193 phaseInputExt (Cpp _) = "lpp" -- intermediate only
194 phaseInputExt (HsPp _) = "hscpp" -- intermediate only
195 phaseInputExt (Hsc _) = "hspp" -- intermediate only
196 -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
197 -- because runPipeline uses the StopBefore phase to pick the
198 -- output filename. That could be fixed, but watch out.
199 phaseInputExt HCc = "hc"
200 phaseInputExt Ccpp = "cpp"
201 phaseInputExt Cc = "c"
202 phaseInputExt SplitMangle = "split_s" -- not really generated
203 phaseInputExt As = "s"
204 phaseInputExt LlvmOpt = "ll"
205 phaseInputExt LlvmLlc = "bc"
206 phaseInputExt LlvmMangle = "lm_s"
207 phaseInputExt SplitAs = "split_s" -- not really generated
208 phaseInputExt CmmCpp = "cmm"
209 phaseInputExt Cmm = "cmmcpp"
210 phaseInputExt MergeStub = "o"
211 phaseInputExt StopLn = "o"
212
213 haskellish_src_suffixes, haskellish_suffixes, cish_suffixes,
214 extcoreish_suffixes, haskellish_user_src_suffixes
215 :: [String]
216 haskellish_src_suffixes = haskellish_user_src_suffixes ++
217 [ "hspp", "hscpp", "hcr", "cmm", "cmmcpp" ]
218 haskellish_suffixes = haskellish_src_suffixes ++ ["hc", "raw_s"]
219 cish_suffixes = [ "c", "cpp", "C", "cc", "cxx", "s", "S", "ll", "bc" ]
220 extcoreish_suffixes = [ "hcr" ]
221 -- Will not be deleted as temp files:
222 haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]
223
224 objish_suffixes :: [String]
225 -- Use the appropriate suffix for the system on which
226 -- the GHC-compiled code will run
227 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
228 objish_suffixes = [ "o", "O", "obj", "OBJ" ]
229 #else
230 objish_suffixes = [ "o" ]
231 #endif
232
233 dynlib_suffixes :: [String]
234 #ifdef mingw32_TARGET_OS
235 dynlib_suffixes = ["dll", "DLL"]
236 #elif defined(darwin_TARGET_OS)
237 dynlib_suffixes = ["dylib"]
238 #else
239 dynlib_suffixes = ["so"]
240 #endif
241
242 isHaskellishSuffix, isHaskellSrcSuffix, isCishSuffix, isExtCoreSuffix,
243 isObjectSuffix, isHaskellUserSrcSuffix, isDynLibSuffix
244 :: String -> Bool
245 isHaskellishSuffix s = s `elem` haskellish_suffixes
246 isHaskellSrcSuffix s = s `elem` haskellish_src_suffixes
247 isCishSuffix s = s `elem` cish_suffixes
248 isExtCoreSuffix s = s `elem` extcoreish_suffixes
249 isObjectSuffix s = s `elem` objish_suffixes
250 isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes
251 isDynLibSuffix s = s `elem` dynlib_suffixes
252
253 isSourceSuffix :: String -> Bool
254 isSourceSuffix suff = isHaskellishSuffix suff || isCishSuffix suff
255
256 isHaskellishFilename, isHaskellSrcFilename, isCishFilename,
257 isExtCoreFilename, isObjectFilename, isHaskellUserSrcFilename,
258 isDynLibFilename, isSourceFilename
259 :: FilePath -> Bool
260 -- takeExtension return .foo, so we drop 1 to get rid of the .
261 isHaskellishFilename f = isHaskellishSuffix (drop 1 $ takeExtension f)
262 isHaskellSrcFilename f = isHaskellSrcSuffix (drop 1 $ takeExtension f)
263 isCishFilename f = isCishSuffix (drop 1 $ takeExtension f)
264 isExtCoreFilename f = isExtCoreSuffix (drop 1 $ takeExtension f)
265 isObjectFilename f = isObjectSuffix (drop 1 $ takeExtension f)
266 isHaskellUserSrcFilename f = isHaskellUserSrcSuffix (drop 1 $ takeExtension f)
267 isDynLibFilename f = isDynLibSuffix (drop 1 $ takeExtension f)
268 isSourceFilename f = isSourceSuffix (drop 1 $ takeExtension f)
269
270