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