summaryrefslogtreecommitdiff
path: root/compiler/main/DriverPhases.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/main/DriverPhases.hs')
-rw-r--r--compiler/main/DriverPhases.hs80
1 files changed, 49 insertions, 31 deletions
diff --git a/compiler/main/DriverPhases.hs b/compiler/main/DriverPhases.hs
index f079212112..ff6f8b8ab1 100644
--- a/compiler/main/DriverPhases.hs
+++ b/compiler/main/DriverPhases.hs
@@ -10,7 +10,7 @@
-----------------------------------------------------------------------------
module DriverPhases (
- HscSource(..), isHsBoot, hscSourceString,
+ HscSource(..), isHsBootOrSig, hscSourceString,
Phase(..),
happensBefore, eqPhase, anyHsc, isStopLn,
startPhase,
@@ -22,10 +22,12 @@ module DriverPhases (
isCishSuffix,
isDynLibSuffix,
isHaskellUserSrcSuffix,
+ isHaskellSigSuffix,
isSourceSuffix,
isHaskellishFilename,
isHaskellSrcFilename,
+ isHaskellSigFilename,
isObjectFilename,
isCishFilename,
isDynLibFilename,
@@ -58,51 +60,63 @@ import Binary
-- Note [HscSource types]
-- ~~~~~~~~~~~~~~~~~~~~~~
--- There are two types of source file for user-written Haskell code:
+-- There are three types of source file for Haskell code:
--
-- * HsSrcFile is an ordinary hs file which contains code,
--
--- * HsBootFile is an hs-boot file. Within a unit, it can
--- be used to break recursive module imports, in which case there's an
--- HsSrcFile associated with it. However, externally, it can
--- also be used to specify the *requirements* of a package,
--- in which case there is an HsBootMerge associated with it.
+-- * HsBootFile is an hs-boot file, which is used to break
+-- recursive module imports (there will always be an
+-- HsSrcFile associated with it), and
--
--- An HsBootMerge is a "fake" source file, which is constructed
--- by collecting up non-recursive HsBootFiles into a single interface.
--- HsBootMerges get an hi and o file, and are treated as "non-boot"
--- sources.
+-- * HsigFile is an hsig file, which contains only type
+-- signatures and is used to specify signatures for
+-- modules.
+--
+-- Syntactically, hs-boot files and hsig files are quite similar: they
+-- only include type signatures and must be associated with an
+-- actual HsSrcFile. isHsBootOrSig allows us to abstract over code
+-- which is indifferent to which. However, there are some important
+-- differences, mostly owing to the fact that hsigs are proper
+-- modules (you `import Sig` directly) whereas HsBootFiles are
+-- temporary placeholders (you `import {-# SOURCE #-} Mod).
+-- When we finish compiling the true implementation of an hs-boot,
+-- we replace the HomeModInfo with the real HsSrcFile. An HsigFile, on the
+-- other hand, is never replaced (in particular, we *cannot* use the
+-- HomeModInfo of the original HsSrcFile backing the signature, since it
+-- will export too many symbols.)
+--
+-- Additionally, while HsSrcFile is the only Haskell file
+-- which has *code*, we do generate .o files for HsigFile, because
+-- this is how the recompilation checker figures out if a file
+-- needs to be recompiled. These are fake object files which
+-- should NOT be linked against.
data HscSource
- = HsSrcFile | HsBootFile | HsBootMerge
+ = HsSrcFile | HsBootFile | HsigFile
deriving( Eq, Ord, Show )
-- Ord needed for the finite maps we build in CompManager
-instance Outputable HscSource where
- ppr HsSrcFile = text "HsSrcFile"
- ppr HsBootFile = text "HsBootFile"
- ppr HsBootMerge = text "HsBootMerge"
-
instance Binary HscSource where
put_ bh HsSrcFile = putByte bh 0
put_ bh HsBootFile = putByte bh 1
- put_ bh HsBootMerge = putByte bh 2
+ put_ bh HsigFile = putByte bh 2
get bh = do
h <- getByte bh
case h of
0 -> return HsSrcFile
1 -> return HsBootFile
- _ -> return HsBootMerge
+ _ -> return HsigFile
hscSourceString :: HscSource -> String
hscSourceString HsSrcFile = ""
hscSourceString HsBootFile = "[boot]"
-hscSourceString HsBootMerge = "[merge]"
+hscSourceString HsigFile = "[sig]"
-isHsBoot :: HscSource -> Bool
-isHsBoot HsBootFile = True
-isHsBoot HsSrcFile = False
-isHsBoot HsBootMerge = False
+-- See Note [isHsBootOrSig]
+isHsBootOrSig :: HscSource -> Bool
+isHsBootOrSig HsBootFile = True
+isHsBootOrSig HsigFile = True
+isHsBootOrSig _ = False
data Phase
= Unlit HscSource
@@ -218,8 +232,10 @@ nextPhase dflags p
startPhase :: String -> Phase
startPhase "lhs" = Unlit HsSrcFile
startPhase "lhs-boot" = Unlit HsBootFile
+startPhase "lhsig" = Unlit HsigFile
startPhase "hs" = Cpp HsSrcFile
startPhase "hs-boot" = Cpp HsBootFile
+startPhase "hsig" = Cpp HsigFile
startPhase "hscpp" = HsPp HsSrcFile
startPhase "hspp" = Hsc HsSrcFile
startPhase "hc" = HCc
@@ -248,9 +264,7 @@ startPhase _ = StopLn -- all unknown file types
phaseInputExt :: Phase -> String
phaseInputExt (Unlit HsSrcFile) = "lhs"
phaseInputExt (Unlit HsBootFile) = "lhs-boot"
-phaseInputExt (Unlit HsBootMerge) = panic "phaseInputExt: Unlit HsBootMerge"
- -- You can't Unlit an HsBootMerge, because there's no source
- -- file to Unlit!
+phaseInputExt (Unlit HsigFile) = "lhsig"
phaseInputExt (Cpp _) = "lpp" -- intermediate only
phaseInputExt (HsPp _) = "hscpp" -- intermediate only
phaseInputExt (Hsc _) = "hspp" -- intermediate only
@@ -275,7 +289,7 @@ phaseInputExt MergeStub = "o"
phaseInputExt StopLn = "o"
haskellish_src_suffixes, haskellish_suffixes, cish_suffixes,
- haskellish_user_src_suffixes
+ haskellish_user_src_suffixes, haskellish_sig_suffixes
:: [String]
-- When a file with an extension in the haskellish_src_suffixes group is
-- loaded in --make mode, its imports will be loaded too.
@@ -286,7 +300,9 @@ haskellish_suffixes = haskellish_src_suffixes ++
cish_suffixes = [ "c", "cpp", "C", "cc", "cxx", "s", "S", "ll", "bc", "lm_s", "m", "M", "mm" ]
-- Will not be deleted as temp files:
-haskellish_user_src_suffixes = [ "hs", "lhs", "hs-boot", "lhs-boot" ]
+haskellish_user_src_suffixes =
+ haskellish_sig_suffixes ++ [ "hs", "lhs", "hs-boot", "lhs-boot" ]
+haskellish_sig_suffixes = [ "hsig", "lhsig" ]
objish_suffixes :: Platform -> [String]
-- Use the appropriate suffix for the system on which
@@ -302,9 +318,10 @@ dynlib_suffixes platform = case platformOS platform of
_ -> ["so"]
isHaskellishSuffix, isHaskellSrcSuffix, isCishSuffix,
- isHaskellUserSrcSuffix
+ isHaskellUserSrcSuffix, isHaskellSigSuffix
:: String -> Bool
isHaskellishSuffix s = s `elem` haskellish_suffixes
+isHaskellSigSuffix s = s `elem` haskellish_sig_suffixes
isHaskellSrcSuffix s = s `elem` haskellish_src_suffixes
isCishSuffix s = s `elem` cish_suffixes
isHaskellUserSrcSuffix s = s `elem` haskellish_user_src_suffixes
@@ -317,7 +334,7 @@ isSourceSuffix :: String -> Bool
isSourceSuffix suff = isHaskellishSuffix suff || isCishSuffix suff
isHaskellishFilename, isHaskellSrcFilename, isCishFilename,
- isHaskellUserSrcFilename, isSourceFilename
+ isHaskellUserSrcFilename, isSourceFilename, isHaskellSigFilename
:: FilePath -> Bool
-- takeExtension return .foo, so we drop 1 to get rid of the .
isHaskellishFilename f = isHaskellishSuffix (drop 1 $ takeExtension f)
@@ -325,6 +342,7 @@ isHaskellSrcFilename f = isHaskellSrcSuffix (drop 1 $ takeExtension f)
isCishFilename f = isCishSuffix (drop 1 $ takeExtension f)
isHaskellUserSrcFilename f = isHaskellUserSrcSuffix (drop 1 $ takeExtension f)
isSourceFilename f = isSourceSuffix (drop 1 $ takeExtension f)
+isHaskellSigFilename f = isHaskellSigSuffix (drop 1 $ takeExtension f)
isObjectFilename, isDynLibFilename :: Platform -> FilePath -> Bool
isObjectFilename platform f = isObjectSuffix platform (drop 1 $ takeExtension f)