1b2972c145b192c354083f7e954e58c95eb19192
[ghc-hetmet.git] / ghc / compiler / main / DriverPhases.hs
1 -----------------------------------------------------------------------------
2 --  $Id: DriverPhases.hs,v 1.36 2005/03/31 10:16:38 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    isHaskellishFilename, 
18    isHaskellSrcFilename,
19    isObjectFilename,
20    isCishFilename,
21    isExtCoreFilename,
22    isDynLibFilename,
23    isHaskellUserSrcFilename,
24    isSourceFilename         -- :: FilePath -> Bool
25  ) where
26
27 import Util             ( getFileSuffix )
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 Phase 
61         = Unlit HscSource
62         | Cpp   HscSource
63         | HsPp  HscSource
64         | Hsc   HscSource
65         | Cc
66         | HCc           -- Haskellised C (as opposed to vanilla C) compilation
67         | Mangle        -- assembly mangling, now done by a separate script.
68         | SplitMangle   -- after mangler if splitting
69         | SplitAs
70         | As
71         | CmmCpp        -- pre-process Cmm source
72         | Cmm           -- parse & compile Cmm code
73
74         -- The final phase is a pseudo-phase that tells the pipeline to stop.
75         -- There is no runPhase case for it.
76         | StopLn        -- Stop, but linking will follow, so generate .o file
77   deriving (Show)
78
79 anyHsc :: Phase
80 anyHsc = Hsc (panic "anyHsc")
81
82 isStopLn :: Phase -> Bool
83 isStopLn StopLn = True
84 isStopLn other  = False
85
86 eqPhase :: Phase -> Phase -> Bool
87 -- Equality of constructors, ignoring the HscSource field
88 -- NB: the HscSource field can be 'bot'; see anyHsc above
89 eqPhase (Unlit _)   (Unlit _)   = True
90 eqPhase (Cpp   _)   (Cpp   _)   = True
91 eqPhase (HsPp  _)   (HsPp  _)   = True
92 eqPhase (Hsc   _)   (Hsc   _)   = True
93 eqPhase Cc          Cc          = True
94 eqPhase HCc         HCc         = True
95 eqPhase Mangle      Mangle      = True
96 eqPhase SplitMangle SplitMangle = True
97 eqPhase SplitAs     SplitAs     = True
98 eqPhase As          As          = True
99 eqPhase CmmCpp      CmmCpp      = True
100 eqPhase Cmm         Cmm         = True
101 eqPhase StopLn      StopLn      = True
102 eqPhase _           _           = False
103
104 -- Partial ordering on phases: we want to know which phases will occur before 
105 -- which others.  This is used for sanity checking, to ensure that the
106 -- pipeline will stop at some point (see DriverPipeline.runPipeline).
107 StopLn `happensBefore` y = False
108 x      `happensBefore` y = after_x `eqPhase` y || after_x `happensBefore` y
109         where
110           after_x = nextPhase x
111
112 nextPhase :: Phase -> Phase
113 -- A conservative approximation the next phase, used in happensBefore
114 nextPhase (Unlit sf)    = Cpp  sf
115 nextPhase (Cpp   sf)    = HsPp sf
116 nextPhase (HsPp  sf)    = Hsc  sf
117 nextPhase (Hsc   sf)    = HCc
118 nextPhase HCc           = Mangle
119 nextPhase Mangle        = SplitMangle
120 nextPhase SplitMangle   = As
121 nextPhase As            = SplitAs
122 nextPhase SplitAs       = StopLn
123 nextPhase Cc            = As
124 nextPhase CmmCpp        = Cmm
125 nextPhase Cmm           = HCc
126 nextPhase StopLn        = panic "nextPhase: nothing after StopLn"
127
128 -- the first compilation phase for a given file is determined
129 -- by its suffix.
130 startPhase "lhs"      = Unlit HsSrcFile
131 startPhase "lhs-boot" = Unlit HsBootFile
132 startPhase "hs"       = Cpp   HsSrcFile
133 startPhase "hs-boot"  = Cpp   HsBootFile
134 startPhase "hscpp"    = HsPp  HsSrcFile
135 startPhase "hspp"     = Hsc   HsSrcFile
136 startPhase "hcr"      = Hsc   ExtCoreFile
137 startPhase "hc"       = HCc
138 startPhase "c"        = Cc
139 startPhase "cpp"      = Cc
140 startPhase "C"        = Cc
141 startPhase "cc"       = Cc
142 startPhase "cxx"      = Cc
143 startPhase "raw_s"    = Mangle
144 startPhase "s"        = As
145 startPhase "S"        = As
146 startPhase "o"        = StopLn
147 startPhase "cmm"      = CmmCpp
148 startPhase "cmmcpp"   = Cmm
149 startPhase _          = StopLn     -- all unknown file types
150
151 -- This is used to determine the extension for the output from the
152 -- current phase (if it generates a new file).  The extension depends
153 -- on the next phase in the pipeline.
154 phaseInputExt (Unlit HsSrcFile)   = "lhs"
155 phaseInputExt (Unlit HsBootFile)  = "lhs-boot"
156 phaseInputExt (Unlit ExtCoreFile) = "lhcr"
157 phaseInputExt (Cpp   _)           = "lpp"       -- intermediate only
158 phaseInputExt (HsPp  _)           = "hscpp"     -- intermediate only
159 phaseInputExt (Hsc   _)           = "hspp"      -- intermediate only
160         -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
161         --     because runPipeline uses the StopBefore phase to pick the
162         --     output filename.  That could be fixed, but watch out.
163 phaseInputExt HCc                 = "hc"  
164 phaseInputExt Cc                  = "c"
165 phaseInputExt Mangle              = "raw_s"
166 phaseInputExt SplitMangle         = "split_s"   -- not really generated
167 phaseInputExt As                  = "s"
168 phaseInputExt SplitAs             = "split_s"   -- not really generated
169 phaseInputExt CmmCpp              = "cmm"
170 phaseInputExt Cmm                 = "cmmcpp"
171 phaseInputExt StopLn              = "o"
172 #ifdef ILX
173 phaseInputExt Ilx2Il              = "ilx"
174 phaseInputExt Ilasm               = "il"
175 #endif
176
177 haskellish_src_suffixes      = haskellish_user_src_suffixes ++
178                                [ "hspp", "hscpp", "hcr", "cmm" ]
179 haskellish_suffixes          = haskellish_src_suffixes ++ ["hc", "raw_s"]
180 cish_suffixes                = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ]
181 extcoreish_suffixes          = [ "hcr" ]
182 haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]   -- Will not be deleted as temp files
183
184 -- Use the appropriate suffix for the system on which 
185 -- the GHC-compiled code will run
186 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
187 objish_suffixes     = [ "o", "O", "obj", "OBJ" ]
188 #else
189 objish_suffixes     = [ "o" ]
190 #endif
191
192 #ifdef mingw32_TARGET_OS
193 dynlib_suffixes = ["dll", "DLL"]
194 #elif defined(darwin_TARGET_OS)
195 dynlib_suffixes = ["dylib"]
196 #else
197 dynlib_suffixes = ["so"]
198 #endif
199
200 isHaskellishFilename     f = getFileSuffix f `elem` haskellish_suffixes
201 isHaskellSrcFilename     f = getFileSuffix f `elem` haskellish_src_suffixes
202 isCishFilename           f = getFileSuffix f `elem` cish_suffixes
203 isExtCoreFilename        f = getFileSuffix f `elem` extcoreish_suffixes
204 isObjectFilename         f = getFileSuffix f `elem` objish_suffixes
205 isHaskellUserSrcFilename f = getFileSuffix f `elem` haskellish_user_src_suffixes
206 isDynLibFilename         f = getFileSuffix f `elem` dynlib_suffixes
207
208 isSourceFilename :: FilePath -> Bool
209 isSourceFilename f  =
210    isHaskellishFilename f ||
211    isCishFilename f