fix stage1_libs pseudo-target
[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 #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         | Mangle        -- assembly mangling, now done by a separate script.
80         | SplitMangle   -- after mangler if splitting
81         | SplitAs
82         | As
83         | LlvmOpt       -- Run LLVM opt tool over llvm assembly
84         | LlvmLlc       -- LLVM bitcode to native assembly
85         | LlvmMangle    -- Fix up TNTC by processing assembly produced by LLVM
86         | CmmCpp        -- pre-process Cmm source
87         | Cmm           -- parse & compile Cmm code
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 Mangle      Mangle      = True
115 eqPhase SplitMangle SplitMangle = True
116 eqPhase SplitAs     SplitAs     = True
117 eqPhase As          As          = True
118 eqPhase LlvmOpt     LlvmOpt     = True
119 eqPhase LlvmLlc     LlvmLlc     = True
120 eqPhase LlvmMangle  LlvmMangle  = True
121 eqPhase CmmCpp      CmmCpp      = True
122 eqPhase Cmm         Cmm         = 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 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 HCc           = Mangle
142 nextPhase Mangle        = SplitMangle
143 nextPhase SplitMangle   = As
144 nextPhase As            = SplitAs
145 nextPhase LlvmOpt       = LlvmLlc
146 #if darwin_TARGET_OS
147 nextPhase LlvmLlc       = LlvmMangle
148 #else
149 nextPhase LlvmLlc       = As
150 #endif
151 nextPhase LlvmMangle    = As
152 nextPhase SplitAs       = StopLn
153 nextPhase Ccpp          = As
154 nextPhase Cc            = As
155 nextPhase CmmCpp        = Cmm
156 nextPhase Cmm           = HCc
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 "raw_s"    = Mangle
176 startPhase "split_s"  = SplitMangle
177 startPhase "s"        = As
178 startPhase "S"        = As
179 startPhase "ll"       = LlvmOpt
180 startPhase "bc"       = LlvmLlc
181 startPhase "lm_s"     = LlvmMangle
182 startPhase "o"        = StopLn
183 startPhase "cmm"      = CmmCpp
184 startPhase "cmmcpp"   = Cmm
185 startPhase _          = StopLn     -- all unknown file types
186
187 -- This is used to determine the extension for the output from the
188 -- current phase (if it generates a new file).  The extension depends
189 -- on the next phase in the pipeline.
190 phaseInputExt :: Phase -> String
191 phaseInputExt (Unlit HsSrcFile)   = "lhs"
192 phaseInputExt (Unlit HsBootFile)  = "lhs-boot"
193 phaseInputExt (Unlit ExtCoreFile) = "lhcr"
194 phaseInputExt (Cpp   _)           = "lpp"       -- intermediate only
195 phaseInputExt (HsPp  _)           = "hscpp"     -- intermediate only
196 phaseInputExt (Hsc   _)           = "hspp"      -- intermediate only
197         -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
198         --     because runPipeline uses the StopBefore phase to pick the
199         --     output filename.  That could be fixed, but watch out.
200 phaseInputExt HCc                 = "hc"
201 phaseInputExt Ccpp                = "cpp"
202 phaseInputExt Cc                  = "c"
203 phaseInputExt Mangle              = "raw_s"
204 phaseInputExt SplitMangle         = "split_s"   -- not really generated
205 phaseInputExt As                  = "s"
206 phaseInputExt LlvmOpt             = "ll"
207 phaseInputExt LlvmLlc             = "bc"
208 phaseInputExt LlvmMangle          = "lm_s"
209 phaseInputExt SplitAs             = "split_s"   -- not really generated
210 phaseInputExt CmmCpp              = "cmm"
211 phaseInputExt Cmm                 = "cmmcpp"
212 phaseInputExt StopLn              = "o"
213
214 haskellish_src_suffixes, haskellish_suffixes, cish_suffixes,
215     extcoreish_suffixes, haskellish_user_src_suffixes
216  :: [String]
217 haskellish_src_suffixes      = haskellish_user_src_suffixes ++
218                                [ "hspp", "hscpp", "hcr", "cmm", "cmmcpp" ]
219 haskellish_suffixes          = haskellish_src_suffixes ++ ["hc", "raw_s"]
220 cish_suffixes                = [ "c", "cpp", "C", "cc", "cxx", "s", "S", "ll", "bc" ]
221 extcoreish_suffixes          = [ "hcr" ]
222 -- Will not be deleted as temp files:
223 haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]
224
225 objish_suffixes :: [String]
226 -- Use the appropriate suffix for the system on which
227 -- the GHC-compiled code will run
228 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
229 objish_suffixes     = [ "o", "O", "obj", "OBJ" ]
230 #else
231 objish_suffixes     = [ "o" ]
232 #endif
233
234 dynlib_suffixes :: [String]
235 #ifdef mingw32_TARGET_OS
236 dynlib_suffixes = ["dll", "DLL"]
237 #elif defined(darwin_TARGET_OS)
238 dynlib_suffixes = ["dylib"]
239 #else
240 dynlib_suffixes = ["so"]
241 #endif
242
243 isHaskellishSuffix, isHaskellSrcSuffix, isCishSuffix, isExtCoreSuffix,
244     isObjectSuffix, isHaskellUserSrcSuffix, isDynLibSuffix
245  :: String -> Bool
246 isHaskellishSuffix     s = s `elem` haskellish_suffixes
247 isHaskellSrcSuffix     s = s `elem` haskellish_src_suffixes
248 isCishSuffix           s = s `elem` cish_suffixes
249 isExtCoreSuffix        s = s `elem` extcoreish_suffixes
250 isObjectSuffix         s = s `elem` objish_suffixes
251 isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes
252 isDynLibSuffix         s = s `elem` dynlib_suffixes
253
254 isSourceSuffix :: String -> Bool
255 isSourceSuffix suff  = isHaskellishSuffix suff || isCishSuffix suff
256
257 isHaskellishFilename, isHaskellSrcFilename, isCishFilename,
258     isExtCoreFilename, isObjectFilename, isHaskellUserSrcFilename,
259     isDynLibFilename, isSourceFilename
260  :: FilePath -> Bool
261 -- takeExtension return .foo, so we drop 1 to get rid of the .
262 isHaskellishFilename     f = isHaskellishSuffix     (drop 1 $ takeExtension f)
263 isHaskellSrcFilename     f = isHaskellSrcSuffix     (drop 1 $ takeExtension f)
264 isCishFilename           f = isCishSuffix           (drop 1 $ takeExtension f)
265 isExtCoreFilename        f = isExtCoreSuffix        (drop 1 $ takeExtension f)
266 isObjectFilename         f = isObjectSuffix         (drop 1 $ takeExtension f)
267 isHaskellUserSrcFilename f = isHaskellUserSrcSuffix (drop 1 $ takeExtension f)
268 isDynLibFilename         f = isDynLibSuffix         (drop 1 $ takeExtension f)
269 isSourceFilename         f = isSourceSuffix         (drop 1 $ takeExtension f)
270
271