diff options
Diffstat (limited to 'compiler/main/DriverPhases.hs')
-rw-r--r-- | compiler/main/DriverPhases.hs | 80 |
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) |