[project @ 2005-01-27 10:44:00 by simonpj]
[ghc-hetmet.git] / ghc / compiler / main / DriverPhases.hs
1 -----------------------------------------------------------------------------
2 -- $Id: DriverPhases.hs,v 1.32 2005/01/27 10:44:27 simonpj Exp $
3 --
4 -- GHC Driver
5 --
6 -- (c) The University of Glasgow 2002
7 --
8 -----------------------------------------------------------------------------
9
10 #include "../includes/ghcconfig.h"
11
12 module DriverPhases (
13    HscSource(..), isHsBoot, hscSourceString,
14    HscTarget(..), Phase(..),
15    happensBefore, eqPhase, anyHsc, isStopPhase,
16    startPhase,          -- :: String -> Phase
17    phaseInputExt,       -- :: Phase -> String
18
19    isHaskellishFilename, 
20    isHaskellSrcFilename,
21    isObjectFilename,
22    isCishFilename,
23    isExtCoreFilename,
24    isDynLibFilename,
25    isHaskellUserSrcFilename,
26    isSourceFilename         -- :: FilePath -> Bool
27  ) where
28
29 import DriverUtil
30 import Panic            ( panic )
31
32 -----------------------------------------------------------------------------
33 -- Phases
34
35 {-
36    Phase of the           | Suffix saying | Flag saying   | (suffix of)
37    compilation system     | ``start here''| ``stop after''| output file
38    
39    literate pre-processor | .lhs          | -             | -
40    C pre-processor (opt.) | -             | -E            | -
41    Haskell compiler       | .hs           | -C, -S        | .hc, .s
42    C compiler (opt.)      | .hc or .c     | -S            | .s
43    assembler              | .s  or .S     | -c            | .o
44    linker                 | other         | -             | a.out
45 -}
46
47 data HscSource
48    = HsSrcFile | HsBootFile | ExtCoreFile
49      deriving( Eq, Ord, Show )
50         -- Ord needed for the finite maps we build in CompManager
51
52
53 hscSourceString :: HscSource -> String
54 hscSourceString HsSrcFile   = ""
55 hscSourceString HsBootFile  = "[boot]"
56 hscSourceString ExtCoreFile = "[ext core]"
57
58 isHsBoot :: HscSource -> Bool
59 isHsBoot HsBootFile = True
60 isHsBoot other      = False
61
62 data HscTarget
63   = HscC
64   | HscAsm
65   | HscJava
66   | HscILX
67   | HscInterpreted
68   | HscNothing
69   deriving (Eq, Show)
70
71 data Phase 
72         = Unlit HscSource
73         | Cpp   HscSource
74         | HsPp  HscSource
75         | Hsc   HscSource
76         | Cc
77         | HCc           -- Haskellised C (as opposed to vanilla C) compilation
78         | Mangle        -- assembly mangling, now done by a separate script.
79         | SplitMangle   -- after mangler if splitting
80         | SplitAs
81         | As
82         | CmmCpp        -- pre-process Cmm source
83         | Cmm           -- parse & compile Cmm code
84 #ifdef ILX
85         | Ilx2Il
86         | Ilasm
87 #endif
88
89         -- The final phase is a pseudo-phase that tells the pipeline to stop.
90         -- There is no runPhase case for it.
91         | StopLn        -- Stop, but linking will follow, so generate .o file
92
93   deriving (Show)
94
95 anyHsc :: Phase
96 anyHsc = Hsc (panic "anyHsc")
97
98 isStopPhase :: Phase -> Bool
99 isStopPhase StopLn = True
100 isStopPhase other  = False
101
102 eqPhase :: Phase -> Phase -> Bool
103 -- Equality of constructors, ignoring the HscSource field
104 eqPhase (Unlit _)   (Unlit _)   = True
105 eqPhase (Cpp   _)   (Cpp   _)   = True
106 eqPhase (HsPp  _)   (HsPp  _)   = True
107 eqPhase (Hsc   _)   (Hsc   _)   = 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 CmmCpp      CmmCpp      = True
115 eqPhase Cmm         Cmm         = True
116 eqPhase StopLn      StopLn      = True
117 eqPhase _           _           = False
118
119 -- Partial ordering on phases: we want to know which phases will occur before 
120 -- which others.  This is used for sanity checking, to ensure that the
121 -- pipeline will stop at some point (see DriverPipeline.runPipeline).
122 StopLn `happensBefore` y = False
123 x      `happensBefore` y = after_x `eqPhase` y || after_x `happensBefore` y
124         where
125           after_x = nextPhase x
126
127 nextPhase :: Phase -> Phase
128 -- A conservative approximation the next phase, used in happensBefore
129 nextPhase (Unlit sf)    = Cpp  sf
130 nextPhase (Cpp   sf)    = HsPp sf
131 nextPhase (HsPp  sf)    = Hsc  sf
132 nextPhase (Hsc   sf)    = HCc
133 nextPhase HCc           = Mangle
134 nextPhase Mangle        = SplitMangle
135 nextPhase SplitMangle   = As
136 nextPhase As            = SplitAs
137 nextPhase SplitAs       = StopLn
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 "lhs"      = Unlit HsSrcFile
146 startPhase "lhs-boot" = Unlit HsBootFile
147 startPhase "hs"       = Cpp   HsSrcFile
148 startPhase "hs-boot"  = Cpp   HsBootFile
149 startPhase "hscpp"    = HsPp  HsSrcFile
150 startPhase "hspp"     = Hsc   HsSrcFile
151 startPhase "hcr"      = Hsc   ExtCoreFile
152 startPhase "hc"       = HCc
153 startPhase "c"        = Cc
154 startPhase "cpp"      = Cc
155 startPhase "C"        = Cc
156 startPhase "cc"       = Cc
157 startPhase "cxx"      = Cc
158 startPhase "raw_s"    = Mangle
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 (Unlit HsSrcFile)   = "lhs"
170 phaseInputExt (Unlit HsBootFile)  = "lhs-boot"
171 phaseInputExt (Unlit ExtCoreFile) = "lhcr"
172 phaseInputExt (Cpp   _)           = "lpp"       -- intermediate only
173 phaseInputExt (HsPp  _)           = "hscpp"     -- intermediate only
174 phaseInputExt (Hsc   _)           = "hspp"      -- intermediate only
175         -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
176         --     because runPipeline uses the StopBefore phase to pick the
177         --     output filename.  That could be fixed, but watch out.
178 phaseInputExt HCc                 = "hc"  
179 phaseInputExt Cc                  = "c"
180 phaseInputExt Mangle              = "raw_s"
181 phaseInputExt SplitMangle         = "split_s"   -- not really generated
182 phaseInputExt As                  = "s"
183 phaseInputExt SplitAs             = "split_s"   -- not really generated
184 phaseInputExt CmmCpp              = "cmm"
185 phaseInputExt Cmm                 = "cmmcpp"
186 phaseInputExt StopLn              = "o"
187 #ifdef ILX
188 phaseInputExt Ilx2Il              = "ilx"
189 phaseInputExt Ilasm               = "il"
190 #endif
191
192 haskellish_src_suffixes      = haskellish_user_src_suffixes ++
193                                [ "hspp", "hscpp", "hcr", "cmm" ]
194 haskellish_suffixes          = haskellish_src_suffixes ++ ["hc", "raw_s"]
195 cish_suffixes                = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ]
196 extcoreish_suffixes          = [ "hcr" ]
197 haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]   -- Will not be deleted as temp files
198
199 -- Use the appropriate suffix for the system on which 
200 -- the GHC-compiled code will run
201 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
202 objish_suffixes     = [ "o", "O", "obj", "OBJ" ]
203 #else
204 objish_suffixes     = [ "o" ]
205 #endif
206
207 #ifdef mingw32_TARGET_OS
208 dynlib_suffixes = ["dll", "DLL"]
209 #elif defined(darwin_TARGET_OS)
210 dynlib_suffixes = ["dylib"]
211 #else
212 dynlib_suffixes = ["so"]
213 #endif
214
215 isHaskellishFilename     f = getFileSuffix f `elem` haskellish_suffixes
216 isHaskellSrcFilename     f = getFileSuffix f `elem` haskellish_src_suffixes
217 isCishFilename           f = getFileSuffix f `elem` cish_suffixes
218 isExtCoreFilename        f = getFileSuffix f `elem` extcoreish_suffixes
219 isObjectFilename         f = getFileSuffix f `elem` objish_suffixes
220 isHaskellUserSrcFilename f = getFileSuffix f `elem` haskellish_user_src_suffixes
221 isDynLibFilename         f = getFileSuffix f `elem` dynlib_suffixes
222
223 isSourceFilename :: FilePath -> Bool
224 isSourceFilename f  =
225    isHaskellishFilename f ||
226    isCishFilename f