37d73d3d6d0e0f0c57a32f882cc65d117ef98b3e
[ghc-hetmet.git] / ghc / compiler / main / DriverPhases.hs
1 -----------------------------------------------------------------------------
2 -- $Id: DriverPhases.hs,v 1.31 2005/01/18 13:51:28 simonmar 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    Phase(..),
14    happensBefore,
15    startPhase,          -- :: String -> Phase
16    phaseInputExt,       -- :: Phase -> String
17
18    isHaskellishFilename, 
19    isHaskellSrcFilename,
20    isObjectFilename,
21    isCishFilename,
22    isExtCoreFilename,
23    isDynLibFilename,
24    isHaskellUserSrcFilename,
25    isSourceFilename         -- :: FilePath -> Bool
26  ) where
27
28 import DriverUtil
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 Phase 
46         = Unlit
47         | Cpp
48         | HsPp
49         | Hsc
50         | Cc
51         | HCc           -- Haskellised C (as opposed to vanilla C) compilation
52         | Mangle        -- assembly mangling, now done by a separate script.
53         | SplitMangle   -- after mangler if splitting
54         | SplitAs
55         | As
56         | Ln
57         | CmmCpp        -- pre-process Cmm source
58         | Cmm           -- parse & compile Cmm code
59 #ifdef ILX
60         | Ilx2Il
61         | Ilasm
62 #endif
63   deriving (Eq, Show)
64
65 -- Partial ordering on phases: we want to know which phases will occur before 
66 -- which others.  This is used for sanity checking, to ensure that the
67 -- pipeline will stop at some point (see DriverPipeline.runPipeline).
68 x `happensBefore` y 
69         | x `elem` haskell_pipe = y `elem` tail (dropWhile (/= x) haskell_pipe)
70         | x `elem` cmm_pipe     = y `elem` tail (dropWhile (/= x) cmm_pipe)
71         | x `elem` c_pipe       = y `elem` tail (dropWhile (/= x) c_pipe)
72         | otherwise = False
73
74 haskell_post_hsc = [HCc,Mangle,SplitMangle,As,SplitAs,Ln]
75 haskell_pipe = Unlit : Cpp : HsPp : Hsc : haskell_post_hsc
76 cmm_pipe     = CmmCpp : Cmm : haskell_post_hsc
77 c_pipe       = [Cc,As,Ln]
78
79 -- the first compilation phase for a given file is determined
80 -- by its suffix.
81 startPhase "lhs"   = Unlit
82 startPhase "hs"    = Cpp
83 startPhase "hscpp" = HsPp
84 startPhase "hspp"  = Hsc
85 startPhase "hcr"   = Hsc
86 startPhase "hc"    = HCc
87 startPhase "c"     = Cc
88 startPhase "cpp"   = Cc
89 startPhase "C"     = Cc
90 startPhase "cc"    = Cc
91 startPhase "cxx"   = Cc
92 startPhase "raw_s" = Mangle
93 startPhase "s"     = As
94 startPhase "S"     = As
95 startPhase "o"     = Ln
96 startPhase "cmm"   = CmmCpp
97 startPhase "cmmcpp" = Cmm
98 startPhase _       = Ln    -- all unknown file types
99
100 -- This is used to determine the extension for the output from the
101 -- current phase (if it generates a new file).  The extension depends
102 -- on the next phase in the pipeline.
103 phaseInputExt Unlit       = "lhs"
104 phaseInputExt Cpp         = "lpp"       -- intermediate only
105 phaseInputExt HsPp        = "hscpp"
106 phaseInputExt Hsc         = "hspp"
107 phaseInputExt HCc         = "hc"
108 phaseInputExt Cc          = "c"
109 phaseInputExt Mangle      = "raw_s"
110 phaseInputExt SplitMangle = "split_s"   -- not really generated
111 phaseInputExt As          = "s"
112 phaseInputExt SplitAs     = "split_s"   -- not really generated
113 phaseInputExt Ln          = "o"
114 phaseInputExt CmmCpp      = "cmm"
115 phaseInputExt Cmm         = "cmmcpp"
116 #ifdef ILX
117 phaseInputExt Ilx2Il      = "ilx"
118 phaseInputExt Ilasm       = "il"
119 #endif
120
121 haskellish_suffixes          = [ "hs", "lhs", "hspp", "hscpp", "hcr", "hc", "raw_s", "cmm" ]
122 haskellish_src_suffixes      = [ "hs", "lhs", "hspp", "hscpp", "hcr", "cmm" ]
123 cish_suffixes                = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ]
124 extcoreish_suffixes          = [ "hcr" ]
125 haskellish_user_src_suffixes = [ "hs", "lhs" ]
126
127 -- Use the appropriate suffix for the system on which 
128 -- the GHC-compiled code will run
129 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
130 objish_suffixes     = [ "o", "O", "obj", "OBJ" ]
131 #else
132 objish_suffixes     = [ "o" ]
133 #endif
134
135 #ifdef mingw32_TARGET_OS
136 dynlib_suffixes = ["dll", "DLL"]
137 #elif defined(darwin_TARGET_OS)
138 dynlib_suffixes = ["dylib"]
139 #else
140 dynlib_suffixes = ["so"]
141 #endif
142
143 isHaskellishFilename     f = getFileSuffix f `elem` haskellish_suffixes
144 isHaskellSrcFilename     f = getFileSuffix f `elem` haskellish_src_suffixes
145 isCishFilename           f = getFileSuffix f `elem` cish_suffixes
146 isExtCoreFilename        f = getFileSuffix f `elem` extcoreish_suffixes
147 isObjectFilename         f = getFileSuffix f `elem` objish_suffixes
148 isHaskellUserSrcFilename f = getFileSuffix f `elem` haskellish_user_src_suffixes
149 isDynLibFilename         f = getFileSuffix f `elem` dynlib_suffixes
150
151 isSourceFilename :: FilePath -> Bool
152 isSourceFilename f  =
153    isHaskellishFilename f ||
154    isCishFilename f