[project @ 2004-08-13 13:04:50 by simonmar]
[ghc-hetmet.git] / ghc / compiler / main / DriverPhases.hs
1 -----------------------------------------------------------------------------
2 -- $Id: DriverPhases.hs,v 1.29 2004/08/13 13:06:57 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 -- the output suffix for a given phase is uniquely determined by
101 -- the input requirements of the next phase.
102 phaseInputExt Unlit       = "lhs"
103 phaseInputExt Cpp         = "lpp"       -- intermediate only
104 phaseInputExt HsPp        = "hscpp"
105 phaseInputExt Hsc         = "hspp"
106 phaseInputExt HCc         = "hc"
107 phaseInputExt Cc          = "c"
108 phaseInputExt Mangle      = "raw_s"
109 phaseInputExt SplitMangle = "split_s"   -- not really generated
110 phaseInputExt As          = "s"
111 phaseInputExt SplitAs     = "split_s"   -- not really generated
112 phaseInputExt Ln          = "o"
113 phaseInputExt CmmCpp      = "cmm"
114 phaseInputExt Cmm         = "cmmcpp"
115 #ifdef ILX
116 phaseInputExt Ilx2Il      = "ilx"
117 phaseInputExt Ilasm       = "il"
118 #endif
119
120 haskellish_suffixes          = [ "hs", "lhs", "hspp", "hscpp", "hcr", "hc", "raw_s", "cmm" ]
121 haskellish_src_suffixes      = [ "hs", "lhs", "hspp", "hscpp", "hcr", "cmm" ]
122 cish_suffixes                = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ]
123 extcoreish_suffixes          = [ "hcr" ]
124 haskellish_user_src_suffixes = [ "hs", "lhs" ]
125
126 -- Use the appropriate suffix for the system on which 
127 -- the GHC-compiled code will run
128 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
129 objish_suffixes     = [ "o", "O", "obj", "OBJ" ]
130 #else
131 objish_suffixes     = [ "o" ]
132 #endif
133
134 #ifdef mingw32_TARGET_OS
135 dynlib_suffixes = ["dll", "DLL"]
136 #elif defined(darwin_TARGET_OS)
137 dynlib_suffixes = ["dylib"]
138 #else
139 dynlib_suffixes = ["so"]
140 #endif
141
142 isHaskellishFilename     f = getFileSuffix f `elem` haskellish_suffixes
143 isHaskellSrcFilename     f = getFileSuffix f `elem` haskellish_src_suffixes
144 isCishFilename           f = getFileSuffix f `elem` cish_suffixes
145 isExtCoreFilename        f = getFileSuffix f `elem` extcoreish_suffixes
146 isObjectFilename         f = getFileSuffix f `elem` objish_suffixes
147 isHaskellUserSrcFilename f = getFileSuffix f `elem` haskellish_user_src_suffixes
148 isDynLibFilename         f = getFileSuffix f `elem` dynlib_suffixes
149
150 isSourceFilename :: FilePath -> Bool
151 isSourceFilename f  =
152    isHaskellishFilename f ||
153    isCishFilename f