4e7c05e316eba310930944f7f30cf8e598e3d546
[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 Panic            ( panic )
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         | CmmCpp        -- pre-process Cmm source
86         | Cmm           -- parse & compile Cmm code
87
88         -- The final phase is a pseudo-phase that tells the pipeline to stop.
89         -- There is no runPhase case for it.
90         | StopLn        -- Stop, but linking will follow, so generate .o file
91   deriving (Eq, Show)
92
93 anyHsc :: Phase
94 anyHsc = Hsc (panic "anyHsc")
95
96 isStopLn :: Phase -> Bool
97 isStopLn StopLn = True
98 isStopLn _      = False
99
100 eqPhase :: Phase -> Phase -> Bool
101 -- Equality of constructors, ignoring the HscSource field
102 -- NB: the HscSource field can be 'bot'; see anyHsc above
103 eqPhase (Unlit _)   (Unlit _)   = True
104 eqPhase (Cpp   _)   (Cpp   _)   = True
105 eqPhase (HsPp  _)   (HsPp  _)   = True
106 eqPhase (Hsc   _)   (Hsc   _)   = True
107 eqPhase Ccpp        Ccpp        = True
108 eqPhase Cc          Cc          = True
109 eqPhase HCc         HCc         = True
110 eqPhase Mangle      Mangle      = True
111 eqPhase SplitMangle SplitMangle = True
112 eqPhase SplitAs     SplitAs     = True
113 eqPhase As          As          = True
114 eqPhase LlvmOpt     LlvmOpt     = True
115 eqPhase LlvmLlc     LlvmLlc     = True
116 eqPhase CmmCpp      CmmCpp      = True
117 eqPhase Cmm         Cmm         = True
118 eqPhase StopLn      StopLn      = True
119 eqPhase _           _           = False
120
121 -- Partial ordering on phases: we want to know which phases will occur before
122 -- which others.  This is used for sanity checking, to ensure that the
123 -- pipeline will stop at some point (see DriverPipeline.runPipeline).
124 happensBefore :: Phase -> Phase -> Bool
125 StopLn `happensBefore` _ = False
126 x      `happensBefore` y = after_x `eqPhase` y || after_x `happensBefore` y
127         where
128           after_x = nextPhase x
129
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   _)     = HCc
136 nextPhase HCc           = Mangle
137 nextPhase Mangle        = SplitMangle
138 nextPhase SplitMangle   = As
139 nextPhase As            = SplitAs
140 nextPhase LlvmOpt       = LlvmLlc
141 nextPhase LlvmLlc       = As
142 nextPhase SplitAs       = StopLn
143 nextPhase Ccpp          = As
144 nextPhase Cc            = As
145 nextPhase CmmCpp        = Cmm
146 nextPhase Cmm           = HCc
147 nextPhase StopLn        = panic "nextPhase: nothing after StopLn"
148
149 -- the first compilation phase for a given file is determined
150 -- by its suffix.
151 startPhase :: String -> Phase
152 startPhase "lhs"      = Unlit HsSrcFile
153 startPhase "lhs-boot" = Unlit HsBootFile
154 startPhase "hs"       = Cpp   HsSrcFile
155 startPhase "hs-boot"  = Cpp   HsBootFile
156 startPhase "hscpp"    = HsPp  HsSrcFile
157 startPhase "hspp"     = Hsc   HsSrcFile
158 startPhase "hcr"      = Hsc   ExtCoreFile
159 startPhase "hc"       = HCc
160 startPhase "c"        = Cc
161 startPhase "cpp"      = Ccpp
162 startPhase "C"        = Cc
163 startPhase "cc"       = Ccpp
164 startPhase "cxx"      = Ccpp
165 startPhase "raw_s"    = Mangle
166 startPhase "split_s"  = SplitMangle
167 startPhase "s"        = As
168 startPhase "S"        = As
169 startPhase "ll"       = LlvmOpt
170 startPhase "bc"       = LlvmLlc
171 startPhase "o"        = StopLn
172 startPhase "cmm"      = CmmCpp
173 startPhase "cmmcpp"   = Cmm
174 startPhase _          = StopLn     -- all unknown file types
175
176 -- This is used to determine the extension for the output from the
177 -- current phase (if it generates a new file).  The extension depends
178 -- on the next phase in the pipeline.
179 phaseInputExt :: Phase -> String
180 phaseInputExt (Unlit HsSrcFile)   = "lhs"
181 phaseInputExt (Unlit HsBootFile)  = "lhs-boot"
182 phaseInputExt (Unlit ExtCoreFile) = "lhcr"
183 phaseInputExt (Cpp   _)           = "lpp"       -- intermediate only
184 phaseInputExt (HsPp  _)           = "hscpp"     -- intermediate only
185 phaseInputExt (Hsc   _)           = "hspp"      -- intermediate only
186         -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
187         --     because runPipeline uses the StopBefore phase to pick the
188         --     output filename.  That could be fixed, but watch out.
189 phaseInputExt HCc                 = "hc"
190 phaseInputExt Ccpp                = "cpp"
191 phaseInputExt Cc                  = "c"
192 phaseInputExt Mangle              = "raw_s"
193 phaseInputExt SplitMangle         = "split_s"   -- not really generated
194 phaseInputExt As                  = "s"
195 phaseInputExt LlvmOpt             = "ll"
196 phaseInputExt LlvmLlc             = "bc"
197 phaseInputExt SplitAs             = "split_s"   -- not really generated
198 phaseInputExt CmmCpp              = "cmm"
199 phaseInputExt Cmm                 = "cmmcpp"
200 phaseInputExt StopLn              = "o"
201
202 haskellish_src_suffixes, haskellish_suffixes, cish_suffixes,
203     extcoreish_suffixes, haskellish_user_src_suffixes
204  :: [String]
205 haskellish_src_suffixes      = haskellish_user_src_suffixes ++
206                                [ "hspp", "hscpp", "hcr", "cmm" ]
207 haskellish_suffixes          = haskellish_src_suffixes ++ ["hc", "raw_s"]
208 cish_suffixes                = [ "c", "cpp", "C", "cc", "cxx", "s", "S", "ll", "bc" ]
209 extcoreish_suffixes          = [ "hcr" ]
210 -- Will not be deleted as temp files:
211 haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]
212
213 objish_suffixes :: [String]
214 -- Use the appropriate suffix for the system on which
215 -- the GHC-compiled code will run
216 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
217 objish_suffixes     = [ "o", "O", "obj", "OBJ" ]
218 #else
219 objish_suffixes     = [ "o" ]
220 #endif
221
222 dynlib_suffixes :: [String]
223 #ifdef mingw32_TARGET_OS
224 dynlib_suffixes = ["dll", "DLL"]
225 #elif defined(darwin_TARGET_OS)
226 dynlib_suffixes = ["dylib"]
227 #else
228 dynlib_suffixes = ["so"]
229 #endif
230
231 isHaskellishSuffix, isHaskellSrcSuffix, isCishSuffix, isExtCoreSuffix,
232     isObjectSuffix, isHaskellUserSrcSuffix, isDynLibSuffix
233  :: String -> Bool
234 isHaskellishSuffix     s = s `elem` haskellish_suffixes
235 isHaskellSrcSuffix     s = s `elem` haskellish_src_suffixes
236 isCishSuffix           s = s `elem` cish_suffixes
237 isExtCoreSuffix        s = s `elem` extcoreish_suffixes
238 isObjectSuffix         s = s `elem` objish_suffixes
239 isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes
240 isDynLibSuffix         s = s `elem` dynlib_suffixes
241
242 isSourceSuffix :: String -> Bool
243 isSourceSuffix suff  = isHaskellishSuffix suff || isCishSuffix suff
244
245 isHaskellishFilename, isHaskellSrcFilename, isCishFilename,
246     isExtCoreFilename, isObjectFilename, isHaskellUserSrcFilename,
247     isDynLibFilename, isSourceFilename
248  :: FilePath -> Bool
249 -- takeExtension return .foo, so we drop 1 to get rid of the .
250 isHaskellishFilename     f = isHaskellishSuffix     (drop 1 $ takeExtension f)
251 isHaskellSrcFilename     f = isHaskellSrcSuffix     (drop 1 $ takeExtension f)
252 isCishFilename           f = isCishSuffix           (drop 1 $ takeExtension f)
253 isExtCoreFilename        f = isExtCoreSuffix        (drop 1 $ takeExtension f)
254 isObjectFilename         f = isObjectSuffix         (drop 1 $ takeExtension f)
255 isHaskellUserSrcFilename f = isHaskellUserSrcSuffix (drop 1 $ takeExtension f)
256 isDynLibFilename         f = isDynLibSuffix         (drop 1 $ takeExtension f)
257 isSourceFilename         f = isSourceSuffix         (drop 1 $ takeExtension f)
258
259