a1c3309bc66f4be852af203b4f39a699d0a2798b
[ghc-hetmet.git] / ghc / compiler / main / DriverPhases.hs
1 -----------------------------------------------------------------------------
2 -- $Id: DriverPhases.hs,v 1.34 2005/01/31 16:59:37 simonpj Exp $
3 --
4 -- GHC Driver
5 --
6 -- (c) The University of Glasgow 2002
7 --
8 -----------------------------------------------------------------------------
9
10 module DriverPhases (
11    HscSource(..), isHsBoot, hscSourceString,
12    HscTarget(..), Phase(..),
13    happensBefore, eqPhase, anyHsc, isStopLn,
14    startPhase,          -- :: String -> Phase
15    phaseInputExt,       -- :: Phase -> String
16
17    isHaskellishFilename, 
18    isHaskellSrcFilename,
19    isObjectFilename,
20    isCishFilename,
21    isExtCoreFilename,
22    isDynLibFilename,
23    isHaskellUserSrcFilename,
24    isSourceFilename         -- :: FilePath -> Bool
25  ) where
26
27 import DriverUtil
28 import Panic            ( panic )
29
30 -----------------------------------------------------------------------------
31 -- Phases
32
33 {-
34    Phase of the           | Suffix saying | Flag saying   | (suffix of)
35    compilation system     | ``start here''| ``stop after''| output file
36    
37    literate pre-processor | .lhs          | -             | -
38    C pre-processor (opt.) | -             | -E            | -
39    Haskell compiler       | .hs           | -C, -S        | .hc, .s
40    C compiler (opt.)      | .hc or .c     | -S            | .s
41    assembler              | .s  or .S     | -c            | .o
42    linker                 | other         | -             | a.out
43 -}
44
45 data HscSource
46    = HsSrcFile | HsBootFile | ExtCoreFile
47      deriving( Eq, Ord, Show )
48         -- Ord needed for the finite maps we build in CompManager
49
50
51 hscSourceString :: HscSource -> String
52 hscSourceString HsSrcFile   = ""
53 hscSourceString HsBootFile  = "[boot]"
54 hscSourceString ExtCoreFile = "[ext core]"
55
56 isHsBoot :: HscSource -> Bool
57 isHsBoot HsBootFile = True
58 isHsBoot other      = False
59
60 data HscTarget
61   = HscC
62   | HscAsm
63   | HscJava
64   | HscILX
65   | HscInterpreted
66   | HscNothing
67   deriving (Eq, Show)
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 #ifdef ILX
83         | Ilx2Il
84         | Ilasm
85 #endif
86
87         -- The final phase is a pseudo-phase that tells the pipeline to stop.
88         -- There is no runPhase case for it.
89         | StopLn        -- Stop, but linking will follow, so generate .o file
90
91   deriving (Show)
92
93 anyHsc :: Phase
94 anyHsc = Hsc (panic "anyHsc")
95
96 isStopLn :: Phase -> Bool
97 isStopLn StopLn = True
98 isStopLn other  = 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 Cc          Cc          = True
108 eqPhase HCc         HCc         = True
109 eqPhase Mangle      Mangle      = True
110 eqPhase SplitMangle SplitMangle = True
111 eqPhase SplitAs     SplitAs     = True
112 eqPhase As          As          = True
113 eqPhase CmmCpp      CmmCpp      = True
114 eqPhase Cmm         Cmm         = True
115 eqPhase StopLn      StopLn      = True
116 eqPhase _           _           = False
117
118 -- Partial ordering on phases: we want to know which phases will occur before 
119 -- which others.  This is used for sanity checking, to ensure that the
120 -- pipeline will stop at some point (see DriverPipeline.runPipeline).
121 StopLn `happensBefore` y = 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   sf)    = HCc
132 nextPhase HCc           = Mangle
133 nextPhase Mangle        = SplitMangle
134 nextPhase SplitMangle   = As
135 nextPhase As            = SplitAs
136 nextPhase SplitAs       = StopLn
137 nextPhase Cc            = As
138 nextPhase CmmCpp        = Cmm
139 nextPhase Cmm           = HCc
140 nextPhase StopLn        = panic "nextPhase: nothing after StopLn"
141
142 -- the first compilation phase for a given file is determined
143 -- by its suffix.
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"      = Cc
154 startPhase "C"        = Cc
155 startPhase "cc"       = Cc
156 startPhase "cxx"      = Cc
157 startPhase "raw_s"    = Mangle
158 startPhase "s"        = As
159 startPhase "S"        = As
160 startPhase "o"        = StopLn
161 startPhase "cmm"      = CmmCpp
162 startPhase "cmmcpp"   = Cmm
163 startPhase _          = StopLn     -- all unknown file types
164
165 -- This is used to determine the extension for the output from the
166 -- current phase (if it generates a new file).  The extension depends
167 -- on the next phase in the pipeline.
168 phaseInputExt (Unlit HsSrcFile)   = "lhs"
169 phaseInputExt (Unlit HsBootFile)  = "lhs-boot"
170 phaseInputExt (Unlit ExtCoreFile) = "lhcr"
171 phaseInputExt (Cpp   _)           = "lpp"       -- intermediate only
172 phaseInputExt (HsPp  _)           = "hscpp"     -- intermediate only
173 phaseInputExt (Hsc   _)           = "hspp"      -- intermediate only
174         -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
175         --     because runPipeline uses the StopBefore phase to pick the
176         --     output filename.  That could be fixed, but watch out.
177 phaseInputExt HCc                 = "hc"  
178 phaseInputExt Cc                  = "c"
179 phaseInputExt Mangle              = "raw_s"
180 phaseInputExt SplitMangle         = "split_s"   -- not really generated
181 phaseInputExt As                  = "s"
182 phaseInputExt SplitAs             = "split_s"   -- not really generated
183 phaseInputExt CmmCpp              = "cmm"
184 phaseInputExt Cmm                 = "cmmcpp"
185 phaseInputExt StopLn              = "o"
186 #ifdef ILX
187 phaseInputExt Ilx2Il              = "ilx"
188 phaseInputExt Ilasm               = "il"
189 #endif
190
191 haskellish_src_suffixes      = haskellish_user_src_suffixes ++
192                                [ "hspp", "hscpp", "hcr", "cmm" ]
193 haskellish_suffixes          = haskellish_src_suffixes ++ ["hc", "raw_s"]
194 cish_suffixes                = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ]
195 extcoreish_suffixes          = [ "hcr" ]
196 haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]   -- Will not be deleted as temp files
197
198 -- Use the appropriate suffix for the system on which 
199 -- the GHC-compiled code will run
200 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
201 objish_suffixes     = [ "o", "O", "obj", "OBJ" ]
202 #else
203 objish_suffixes     = [ "o" ]
204 #endif
205
206 #ifdef mingw32_TARGET_OS
207 dynlib_suffixes = ["dll", "DLL"]
208 #elif defined(darwin_TARGET_OS)
209 dynlib_suffixes = ["dylib"]
210 #else
211 dynlib_suffixes = ["so"]
212 #endif
213
214 isHaskellishFilename     f = getFileSuffix f `elem` haskellish_suffixes
215 isHaskellSrcFilename     f = getFileSuffix f `elem` haskellish_src_suffixes
216 isCishFilename           f = getFileSuffix f `elem` cish_suffixes
217 isExtCoreFilename        f = getFileSuffix f `elem` extcoreish_suffixes
218 isObjectFilename         f = getFileSuffix f `elem` objish_suffixes
219 isHaskellUserSrcFilename f = getFileSuffix f `elem` haskellish_user_src_suffixes
220 isDynLibFilename         f = getFileSuffix f `elem` dynlib_suffixes
221
222 isSourceFilename :: FilePath -> Bool
223 isSourceFilename f  =
224    isHaskellishFilename f ||
225    isCishFilename f