Haddock fix in the vectoriser
[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         | Cobjc
79         | HCc           -- Haskellised C (as opposed to vanilla C) compilation
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         | MergeStub     -- merge in the stub object file
89
90         -- The final phase is a pseudo-phase that tells the pipeline to stop.
91         -- There is no runPhase case for it.
92         | StopLn        -- Stop, but linking will follow, so generate .o file
93   deriving (Eq, Show)
94
95 instance Outputable Phase where
96     ppr p = text (show p)
97
98 anyHsc :: Phase
99 anyHsc = Hsc (panic "anyHsc")
100
101 isStopLn :: Phase -> Bool
102 isStopLn StopLn = True
103 isStopLn _      = False
104
105 eqPhase :: Phase -> Phase -> Bool
106 -- Equality of constructors, ignoring the HscSource field
107 -- NB: the HscSource field can be 'bot'; see anyHsc above
108 eqPhase (Unlit _)   (Unlit _)   = True
109 eqPhase (Cpp   _)   (Cpp   _)   = True
110 eqPhase (HsPp  _)   (HsPp  _)   = True
111 eqPhase (Hsc   _)   (Hsc   _)   = True
112 eqPhase Ccpp        Ccpp        = True
113 eqPhase Cc          Cc          = True
114 eqPhase Cobjc       Cobjc       = True
115 eqPhase HCc         HCc         = True
116 eqPhase SplitMangle SplitMangle = True
117 eqPhase SplitAs     SplitAs     = True
118 eqPhase As          As          = True
119 eqPhase LlvmOpt     LlvmOpt     = True
120 eqPhase LlvmLlc     LlvmLlc     = True
121 eqPhase LlvmMangle  LlvmMangle  = True
122 eqPhase CmmCpp      CmmCpp      = True
123 eqPhase Cmm         Cmm         = True
124 eqPhase MergeStub   MergeStub   = True
125 eqPhase StopLn      StopLn      = True
126 eqPhase _           _           = False
127
128 -- Partial ordering on phases: we want to know which phases will occur before
129 -- which others.  This is used for sanity checking, to ensure that the
130 -- pipeline will stop at some point (see DriverPipeline.runPipeline).
131 happensBefore :: Phase -> Phase -> Bool
132 StopLn `happensBefore` _ = False
133 x      `happensBefore` y = after_x `eqPhase` y || after_x `happensBefore` y
134         where
135           after_x = nextPhase x
136
137 nextPhase :: Phase -> Phase
138 -- A conservative approximation to the next phase, used in happensBefore
139 nextPhase (Unlit sf)    = Cpp  sf
140 nextPhase (Cpp   sf)    = HsPp sf
141 nextPhase (HsPp  sf)    = Hsc  sf
142 nextPhase (Hsc   _)     = HCc
143 nextPhase SplitMangle   = As
144 nextPhase As            = SplitAs
145 nextPhase LlvmOpt       = LlvmLlc
146 nextPhase LlvmLlc       = LlvmMangle
147 nextPhase LlvmMangle    = As
148 nextPhase SplitAs       = MergeStub
149 nextPhase Ccpp          = As
150 nextPhase Cc            = As
151 nextPhase Cobjc         = As
152 nextPhase CmmCpp        = Cmm
153 nextPhase Cmm           = HCc
154 nextPhase HCc           = As
155 nextPhase MergeStub     = StopLn
156 nextPhase StopLn        = panic "nextPhase: nothing after StopLn"
157
158 -- the first compilation phase for a given file is determined
159 -- by its suffix.
160 startPhase :: String -> Phase
161 startPhase "lhs"      = Unlit HsSrcFile
162 startPhase "lhs-boot" = Unlit HsBootFile
163 startPhase "hs"       = Cpp   HsSrcFile
164 startPhase "hs-boot"  = Cpp   HsBootFile
165 startPhase "hscpp"    = HsPp  HsSrcFile
166 startPhase "hspp"     = Hsc   HsSrcFile
167 startPhase "hcr"      = Hsc   ExtCoreFile
168 startPhase "hc"       = HCc
169 startPhase "c"        = Cc
170 startPhase "cpp"      = Ccpp
171 startPhase "C"        = Cc
172 startPhase "m"        = Cobjc
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 Cobjc               = "m"
202 phaseInputExt Cc                  = "c"
203 phaseInputExt SplitMangle         = "split_s"   -- not really generated
204 phaseInputExt As                  = "s"
205 phaseInputExt LlvmOpt             = "ll"
206 phaseInputExt LlvmLlc             = "bc"
207 phaseInputExt LlvmMangle          = "lm_s"
208 phaseInputExt SplitAs             = "split_s"   -- not really generated
209 phaseInputExt CmmCpp              = "cmm"
210 phaseInputExt Cmm                 = "cmmcpp"
211 phaseInputExt MergeStub           = "o"
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", "m" ]
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