Reorganisation of the source tree
[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 import Util             ( suffixOf )
37 import Panic            ( panic )
38
39 -----------------------------------------------------------------------------
40 -- Phases
41
42 {-
43    Phase of the           | Suffix saying | Flag saying   | (suffix of)
44    compilation system     | ``start here''| ``stop after''| output file
45    
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
52 -}
53
54 data HscSource
55    = HsSrcFile | HsBootFile | ExtCoreFile
56      deriving( Eq, Ord, Show )
57         -- Ord needed for the finite maps we build in CompManager
58
59
60 hscSourceString :: HscSource -> String
61 hscSourceString HsSrcFile   = ""
62 hscSourceString HsBootFile  = "[boot]"
63 hscSourceString ExtCoreFile = "[ext core]"
64
65 isHsBoot :: HscSource -> Bool
66 isHsBoot HsBootFile = True
67 isHsBoot other      = False
68
69 data Phase 
70         = Unlit HscSource
71         | Cpp   HscSource
72         | HsPp  HscSource
73         | Hsc   HscSource
74         | Cc
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
78         | SplitAs
79         | As
80         | CmmCpp        -- pre-process Cmm source
81         | Cmm           -- parse & compile Cmm code
82
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
86   deriving (Eq, Show)
87
88 anyHsc :: Phase
89 anyHsc = Hsc (panic "anyHsc")
90
91 isStopLn :: Phase -> Bool
92 isStopLn StopLn = True
93 isStopLn other  = False
94
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
102 eqPhase Cc          Cc          = True
103 eqPhase HCc         HCc         = True
104 eqPhase Mangle      Mangle      = True
105 eqPhase SplitMangle SplitMangle = True
106 eqPhase SplitAs     SplitAs     = True
107 eqPhase As          As          = True
108 eqPhase CmmCpp      CmmCpp      = True
109 eqPhase Cmm         Cmm         = True
110 eqPhase StopLn      StopLn      = True
111 eqPhase _           _           = False
112
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
118         where
119           after_x = nextPhase x
120
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
132 nextPhase Cc            = As
133 nextPhase CmmCpp        = Cmm
134 nextPhase Cmm           = HCc
135 nextPhase StopLn        = panic "nextPhase: nothing after StopLn"
136
137 -- the first compilation phase for a given file is determined
138 -- by its suffix.
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
147 startPhase "c"        = Cc
148 startPhase "cpp"      = Cc
149 startPhase "C"        = Cc
150 startPhase "cc"       = Cc
151 startPhase "cxx"      = Cc
152 startPhase "raw_s"    = Mangle
153 startPhase "split_s"  = SplitMangle
154 startPhase "s"        = As
155 startPhase "S"        = As
156 startPhase "o"        = StopLn
157 startPhase "cmm"      = CmmCpp
158 startPhase "cmmcpp"   = Cmm
159 startPhase _          = StopLn     -- all unknown file types
160
161 -- This is used to determine the extension for the output from the
162 -- current phase (if it generates a new file).  The extension depends
163 -- on the next phase in the pipeline.
164 phaseInputExt (Unlit HsSrcFile)   = "lhs"
165 phaseInputExt (Unlit HsBootFile)  = "lhs-boot"
166 phaseInputExt (Unlit ExtCoreFile) = "lhcr"
167 phaseInputExt (Cpp   _)           = "lpp"       -- intermediate only
168 phaseInputExt (HsPp  _)           = "hscpp"     -- intermediate only
169 phaseInputExt (Hsc   _)           = "hspp"      -- intermediate only
170         -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
171         --     because runPipeline uses the StopBefore phase to pick the
172         --     output filename.  That could be fixed, but watch out.
173 phaseInputExt HCc                 = "hc"  
174 phaseInputExt Cc                  = "c"
175 phaseInputExt Mangle              = "raw_s"
176 phaseInputExt SplitMangle         = "split_s"   -- not really generated
177 phaseInputExt As                  = "s"
178 phaseInputExt SplitAs             = "split_s"   -- not really generated
179 phaseInputExt CmmCpp              = "cmm"
180 phaseInputExt Cmm                 = "cmmcpp"
181 phaseInputExt StopLn              = "o"
182 #ifdef ILX
183 phaseInputExt Ilx2Il              = "ilx"
184 phaseInputExt Ilasm               = "il"
185 #endif
186
187 haskellish_src_suffixes      = haskellish_user_src_suffixes ++
188                                [ "hspp", "hscpp", "hcr", "cmm" ]
189 haskellish_suffixes          = haskellish_src_suffixes ++ ["hc", "raw_s"]
190 cish_suffixes                = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ]
191 extcoreish_suffixes          = [ "hcr" ]
192 haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]   -- Will not be deleted as temp files
193
194 -- Use the appropriate suffix for the system on which 
195 -- the GHC-compiled code will run
196 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
197 objish_suffixes     = [ "o", "O", "obj", "OBJ" ]
198 #else
199 objish_suffixes     = [ "o" ]
200 #endif
201
202 #ifdef mingw32_TARGET_OS
203 dynlib_suffixes = ["dll", "DLL"]
204 #elif defined(darwin_TARGET_OS)
205 dynlib_suffixes = ["dylib"]
206 #else
207 dynlib_suffixes = ["so"]
208 #endif
209
210 isHaskellishSuffix     s = s `elem` haskellish_suffixes
211 isHaskellSrcSuffix     s = s `elem` haskellish_src_suffixes
212 isCishSuffix           s = s `elem` cish_suffixes
213 isExtCoreSuffix        s = s `elem` extcoreish_suffixes
214 isObjectSuffix         s = s `elem` objish_suffixes
215 isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes
216 isDynLibSuffix         s = s `elem` dynlib_suffixes
217
218 isSourceSuffix suff  = isHaskellishSuffix suff || isCishSuffix suff
219
220 isHaskellishFilename     f = isHaskellishSuffix     (suffixOf f)
221 isHaskellSrcFilename     f = isHaskellSrcSuffix     (suffixOf f)
222 isCishFilename           f = isCishSuffix           (suffixOf f)
223 isExtCoreFilename        f = isExtCoreSuffix        (suffixOf f)
224 isObjectFilename         f = isObjectSuffix         (suffixOf f)
225 isHaskellUserSrcFilename f = isHaskellUserSrcSuffix (suffixOf f)
226 isDynLibFilename         f = isDynLibSuffix         (suffixOf f)
227 isSourceFilename         f = isSourceSuffix         (suffixOf f)
228
229