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