Make -split-objs work with --make
[ghc-hetmet.git] / ghc / compiler / main / DriverPhases.hs
index 89e8ef4..6e94531 100644 (file)
@@ -1,24 +1,40 @@
 -----------------------------------------------------------------------------
--- $Id: DriverPhases.hs,v 1.9 2001/05/08 10:58:48 simonmar Exp $
+--  $Id: DriverPhases.hs,v 1.38 2005/05/17 11:01:59 simonmar Exp $
 --
 -- GHC Driver
 --
--- (c) Simon Marlow 2000
+-- (c) The University of Glasgow 2002
 --
 -----------------------------------------------------------------------------
 
 module DriverPhases (
+   HscSource(..), isHsBoot, hscSourceString,
    Phase(..),
+   happensBefore, eqPhase, anyHsc, isStopLn,
    startPhase,         -- :: String -> Phase
    phaseInputExt,      -- :: Phase -> String
 
-   haskellish_file, haskellish_suffix,
-   haskellish_src_file, haskellish_src_suffix,
-   objish_file, objish_suffix,
-   cish_file, cish_suffix
+   isHaskellishSuffix, 
+   isHaskellSrcSuffix,
+   isObjectSuffix,
+   isCishSuffix,
+   isExtCoreSuffix,
+   isDynLibSuffix,
+   isHaskellUserSrcSuffix,
+   isSourceSuffix,
+
+   isHaskellishFilename, 
+   isHaskellSrcFilename,
+   isObjectFilename,
+   isCishFilename,
+   isExtCoreFilename,
+   isDynLibFilename,
+   isHaskellUserSrcFilename,
+   isSourceFilename         -- :: FilePath -> Bool
  ) where
 
-import DriverUtil
+import Util            ( suffixOf )
+import Panic           ( panic )
 
 -----------------------------------------------------------------------------
 -- Phases
@@ -35,58 +51,179 @@ import DriverUtil
    linker                 | other         | -             | a.out
 -}
 
+data HscSource
+   = HsSrcFile | HsBootFile | ExtCoreFile
+     deriving( Eq, Ord, Show )
+       -- Ord needed for the finite maps we build in CompManager
+
+
+hscSourceString :: HscSource -> String
+hscSourceString HsSrcFile   = ""
+hscSourceString HsBootFile  = "[boot]"
+hscSourceString ExtCoreFile = "[ext core]"
+
+isHsBoot :: HscSource -> Bool
+isHsBoot HsBootFile = True
+isHsBoot other      = False
+
 data Phase 
-       = MkDependHS    -- haskell dependency generation
-       | Unlit
-       | Cpp
-       | Hsc -- ToDo: HscTargetLang
+       = Unlit HscSource
+       | Cpp   HscSource
+       | HsPp  HscSource
+       | Hsc   HscSource
        | Cc
        | HCc           -- Haskellised C (as opposed to vanilla C) compilation
        | Mangle        -- assembly mangling, now done by a separate script.
        | SplitMangle   -- after mangler if splitting
        | SplitAs
        | As
-       | Ln 
+       | CmmCpp        -- pre-process Cmm source
+       | Cmm           -- parse & compile Cmm code
+
+       -- The final phase is a pseudo-phase that tells the pipeline to stop.
+       -- There is no runPhase case for it.
+       | StopLn        -- Stop, but linking will follow, so generate .o file
   deriving (Eq, Show)
 
+anyHsc :: Phase
+anyHsc = Hsc (panic "anyHsc")
+
+isStopLn :: Phase -> Bool
+isStopLn StopLn = True
+isStopLn other  = False
+
+eqPhase :: Phase -> Phase -> Bool
+-- Equality of constructors, ignoring the HscSource field
+-- NB: the HscSource field can be 'bot'; see anyHsc above
+eqPhase (Unlit _)   (Unlit _)  = True
+eqPhase (Cpp   _)   (Cpp   _)  = True
+eqPhase (HsPp  _)   (HsPp  _)  = True
+eqPhase (Hsc   _)   (Hsc   _)  = True
+eqPhase Cc         Cc          = True
+eqPhase HCc        HCc         = True
+eqPhase Mangle     Mangle      = True
+eqPhase SplitMangle SplitMangle = True
+eqPhase SplitAs            SplitAs     = True
+eqPhase As         As          = True
+eqPhase CmmCpp     CmmCpp      = True
+eqPhase Cmm        Cmm         = True
+eqPhase StopLn     StopLn      = True
+eqPhase _          _           = False
+
+-- Partial ordering on phases: we want to know which phases will occur before 
+-- which others.  This is used for sanity checking, to ensure that the
+-- pipeline will stop at some point (see DriverPipeline.runPipeline).
+StopLn `happensBefore` y = False
+x      `happensBefore` y = after_x `eqPhase` y || after_x `happensBefore` y
+       where
+         after_x = nextPhase x
+
+nextPhase :: Phase -> Phase
+-- A conservative approximation the next phase, used in happensBefore
+nextPhase (Unlit sf)   = Cpp  sf
+nextPhase (Cpp   sf)   = HsPp sf
+nextPhase (HsPp  sf)   = Hsc  sf
+nextPhase (Hsc   sf)   = HCc
+nextPhase HCc          = Mangle
+nextPhase Mangle       = SplitMangle
+nextPhase SplitMangle  = As
+nextPhase As           = SplitAs
+nextPhase SplitAs      = StopLn
+nextPhase Cc           = As
+nextPhase CmmCpp       = Cmm
+nextPhase Cmm          = HCc
+nextPhase StopLn       = panic "nextPhase: nothing after StopLn"
+
 -- the first compilation phase for a given file is determined
 -- by its suffix.
-startPhase "lhs"   = Unlit
-startPhase "hs"    = Cpp
-startPhase "hspp"  = Hsc
-startPhase "hc"    = HCc
-startPhase "c"     = Cc
-startPhase "raw_s" = Mangle
-startPhase "s"     = As
-startPhase "S"     = As
-startPhase "o"     = Ln
-startPhase _       = Ln           -- all unknown file types
-
--- the output suffix for a given phase is uniquely determined by
--- the input requirements of the next phase.
-phaseInputExt Unlit       = "lhs"
-phaseInputExt Cpp         = "lpp"      -- intermediate only
-phaseInputExt Hsc         = "hspp"
-phaseInputExt HCc         = "hc"
-phaseInputExt Cc          = "c"
-phaseInputExt Mangle      = "raw_s"
-phaseInputExt SplitMangle = "split_s"  -- not really generated
-phaseInputExt As          = "s"
-phaseInputExt SplitAs     = "split_s"   -- not really generated
-phaseInputExt Ln          = "o"
-phaseInputExt MkDependHS  = "dep"
-
-haskellish_suffix     = (`elem` [ "hs", "hspp", "lhs", "hc", "raw_s" ])
-haskellish_src_suffix = (`elem` [ "hs", "hspp", "lhs" ])
-cish_suffix           = (`elem` [ "c", "s", "S" ])  -- maybe .cc et al.??
+startPhase "lhs"      = Unlit HsSrcFile
+startPhase "lhs-boot" = Unlit HsBootFile
+startPhase "hs"       = Cpp   HsSrcFile
+startPhase "hs-boot"  = Cpp   HsBootFile
+startPhase "hscpp"    = HsPp  HsSrcFile
+startPhase "hspp"     = Hsc   HsSrcFile
+startPhase "hcr"      = Hsc   ExtCoreFile
+startPhase "hc"       = HCc
+startPhase "c"        = Cc
+startPhase "cpp"      = Cc
+startPhase "C"        = Cc
+startPhase "cc"       = Cc
+startPhase "cxx"      = Cc
+startPhase "raw_s"    = Mangle
+startPhase "split_s"  = SplitMangle
+startPhase "s"        = As
+startPhase "S"        = As
+startPhase "o"        = StopLn
+startPhase "cmm"      = CmmCpp
+startPhase "cmmcpp"   = Cmm
+startPhase _          = StopLn    -- all unknown file types
 
+-- This is used to determine the extension for the output from the
+-- current phase (if it generates a new file).  The extension depends
+-- on the next phase in the pipeline.
+phaseInputExt (Unlit HsSrcFile)   = "lhs"
+phaseInputExt (Unlit HsBootFile)  = "lhs-boot"
+phaseInputExt (Unlit ExtCoreFile) = "lhcr"
+phaseInputExt (Cpp   _)          = "lpp"       -- intermediate only
+phaseInputExt (HsPp  _)                  = "hscpp"     -- intermediate only
+phaseInputExt (Hsc   _)          = "hspp"      -- intermediate only
+       -- NB: as things stand, phaseInputExt (Hsc x) must not evaluate x
+       --     because runPipeline uses the StopBefore phase to pick the
+       --     output filename.  That could be fixed, but watch out.
+phaseInputExt HCc                = "hc"  
+phaseInputExt Cc                 = "c"
+phaseInputExt Mangle             = "raw_s"
+phaseInputExt SplitMangle        = "split_s"   -- not really generated
+phaseInputExt As                 = "s"
+phaseInputExt SplitAs            = "split_s"   -- not really generated
+phaseInputExt CmmCpp             = "cmm"
+phaseInputExt Cmm                = "cmmcpp"
+phaseInputExt StopLn             = "o"
+#ifdef ILX
+phaseInputExt Ilx2Il             = "ilx"
+phaseInputExt Ilasm              = "il"
+#endif
+
+haskellish_src_suffixes      = haskellish_user_src_suffixes ++
+                              [ "hspp", "hscpp", "hcr", "cmm" ]
+haskellish_suffixes          = haskellish_src_suffixes ++ ["hc", "raw_s"]
+cish_suffixes                = [ "c", "cpp", "C", "cc", "cxx", "s", "S" ]
+extcoreish_suffixes          = [ "hcr" ]
+haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]  -- Will not be deleted as temp files
+
+-- Use the appropriate suffix for the system on which 
+-- the GHC-compiled code will run
 #if mingw32_TARGET_OS || cygwin32_TARGET_OS
-objish_suffix     = (`elem` [ "o", "O", "obj", "OBJ" ])
+objish_suffixes     = [ "o", "O", "obj", "OBJ" ]
+#else
+objish_suffixes     = [ "o" ]
+#endif
+
+#ifdef mingw32_TARGET_OS
+dynlib_suffixes = ["dll", "DLL"]
+#elif defined(darwin_TARGET_OS)
+dynlib_suffixes = ["dylib"]
 #else
-objish_suffix     = (`elem` [ "o" ])
+dynlib_suffixes = ["so"]
 #endif
 
-haskellish_file     = haskellish_suffix     . getFileSuffix
-haskellish_src_file = haskellish_src_suffix . getFileSuffix
-cish_file           = cish_suffix           . getFileSuffix
-objish_file         = objish_suffix         . getFileSuffix
+isHaskellishSuffix     s = s `elem` haskellish_suffixes
+isHaskellSrcSuffix     s = s `elem` haskellish_src_suffixes
+isCishSuffix           s = s `elem` cish_suffixes
+isExtCoreSuffix        s = s `elem` extcoreish_suffixes
+isObjectSuffix         s = s `elem` objish_suffixes
+isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes
+isDynLibSuffix        s = s `elem` dynlib_suffixes
+
+isSourceSuffix suff  = isHaskellishSuffix suff || isCishSuffix suff
+
+isHaskellishFilename     f = isHaskellishSuffix     (suffixOf f)
+isHaskellSrcFilename     f = isHaskellSrcSuffix     (suffixOf f)
+isCishFilename           f = isCishSuffix           (suffixOf f)
+isExtCoreFilename        f = isExtCoreSuffix        (suffixOf f)
+isObjectFilename         f = isObjectSuffix         (suffixOf f)
+isHaskellUserSrcFilename f = isHaskellUserSrcSuffix (suffixOf f)
+isDynLibFilename        f = isDynLibSuffix         (suffixOf f)
+isSourceFilename        f = isSourceSuffix         (suffixOf f)
+
+