module UHC.Light.Compiler.EHC.CompilePhase.Module
( cpCheckModsModWith
, cpCheckModsWithOrWithoutBuiltin
, cpCheckModsWithBuiltin
, cpCheckModsWithoutBuiltin
, cpGetCoreModnameAndImports
, cpGetHsModnameAndImports
, cpGetHsMod
, cpGetDummyCheckSrcMod
, cpUpdateModOffMp
, cpGenImportNameInfo
, cpUpdHiddenExports )
where
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified UHC.Util.Rel as Rel
import UHC.Util.Time
import UHC.Util.FPath
import System.Directory
import Control.Monad.State
import UHC.Light.Compiler.Base.Optimize
import UHC.Light.Compiler.EHC.Common
import UHC.Light.Compiler.EHC.CompileUnit
import UHC.Light.Compiler.EHC.CompileRun.Base
import UHC.Light.Compiler.Module.ImportExport
import qualified UHC.Light.Compiler.Config as Cfg
import qualified UHC.Light.Compiler.HS.ModImpExp as HSSemMod
import qualified UHC.Light.Compiler.Core.Check as Core2ChkSem
import qualified UHC.Light.Compiler.CoreRun.Check as CoreRun2ChkSem
import UHC.Light.Compiler.CodeGen.RefGenerator
cpCheckModsModWith :: EHCCompileRunner m => (HsName -> ModMpInfo) -> [Mod] -> EHCompilePhaseT m ()
cpCheckModsModWith dfltMod modL@(Mod {modName = modNm} : _)
= do { cr <- get
; cpMsg modNm VerboseDebug $ "cpCheckModsModWith modL: " ++ show modL
; let crsi = _crStateInfo cr
(mm,e) = modMpCombine' dfltMod modL (crsiModMp crsi)
; cpUpdSI (\crsi -> crsi {crsiModMp = mm})
; cpSetLimitErrsWhen 5 "Module analysis" e
}
cpCheckModsWithOrWithoutBuiltin :: EHCCompileRunner m => Bool -> [HsName] -> EHCompilePhaseT m ()
cpCheckModsWithOrWithoutBuiltin bltin modNmL@(modNm:_)
= do { cr <- get
; cpMsg modNm VerboseDebug $ "cpCheckModsWithOrWithoutBuiltin modNmL: " ++ show modNmL
; let modL = [ addBuiltin $ ecuMod $ crCU n cr | n <- modNmL ]
; cpCheckModsModWith (\n -> panic $ "cpCheckModsWithOrWithoutBuiltin: " ++ show n) modL
}
where addBuiltin | bltin = \m -> m { modImpL = modImpBuiltin : modImpL m }
| otherwise = id
cpCheckModsWithBuiltin :: EHCCompileRunner m => [HsName] -> EHCompilePhaseT m ()
cpCheckModsWithBuiltin = cpCheckModsWithOrWithoutBuiltin True
cpCheckModsWithoutBuiltin :: EHCCompileRunner m => [HsName] -> EHCompilePhaseT m ()
cpCheckModsWithoutBuiltin = cpCheckModsWithOrWithoutBuiltin False
cpGetCoreModnameAndImports :: EHCCompileRunner m => HsName -> EHCompilePhaseT m HsName
cpGetCoreModnameAndImports modNm
= do { cr <- get
; let (ecu,_,opts,_) = crBaseInfo modNm cr
mbCrSemMod = _ecuMbCoreSemMod ecu
crSemMod = panicJust "cpGetCoreModnameAndImports" mbCrSemMod
modNm' = Core2ChkSem.realModuleNm_Syn_CodeAGItf crSemMod
; cpMsg modNm VerboseDebug $ "cpGetCoreModnameAndImports: " ++ show modNm ++ " -> " ++ show modNm'
; case mbCrSemMod of
Just _ -> cpUpdCUWithKey modNm $ \_ ecu ->
( modNm'
, ecuStoreSrcDeclImpS (Set.fromList $ Core2ChkSem.impModNmL_Syn_CodeAGItf crSemMod )
$ cuUpdKey modNm' ecu
)
_ -> return modNm
}
cpGetHsModnameAndImports :: EHCCompileRunner m => HsName -> EHCompilePhaseT m HsName
cpGetHsModnameAndImports modNm
= do { cr <- get
; let (ecu,_,opts,_) = crBaseInfo modNm cr
mbHsSemMod = _ecuMbHSSemMod ecu
hsSemMod = panicJust "cpGetHsModnameAndImports" mbHsSemMod
modNm' = HSSemMod.realModuleNm_Syn_AGItf hsSemMod
upd = ecuStoreSrcDeclImpS (
HSSemMod.modImpNmS_Syn_AGItf hsSemMod)
; case mbHsSemMod of
Just _ | _ecuIsTopMod ecu -> cpUpdCUWithKey modNm (\_ ecu -> (modNm', upd $ cuUpdKey modNm' ecu))
| otherwise -> do { cpUpdCU modNm upd ; return modNm }
_ -> return modNm
}
cpGetHsMod :: EHCCompileRunner m => HsName -> EHCompilePhaseT m ()
cpGetHsMod modNm
= do { cr <- get
; let (ecu,_,opts,_) = crBaseInfo modNm cr
mbHsSemMod = _ecuMbHSSemMod ecu
hsSemMod = panicJust "cpGetHsMod" mbHsSemMod
mod = HSSemMod.mod_Syn_AGItf hsSemMod
; when (ehcOptVerbosity opts >= VerboseDebug)
(do { cpMsg modNm VerboseDebug "cpGetHsMod"
; liftIO $ putWidthPPLn 120 (pp mod)
})
; when (isJust mbHsSemMod)
(cpUpdCU modNm (ecuStoreMod mod))
}
cpGetDummyCheckSrcMod :: EHCCompileRunner m => HsName -> EHCompilePhaseT m ()
cpGetDummyCheckSrcMod modNm
= do { cr <- get
; let crsi = _crStateInfo cr
mm = crsiModMp crsi
mod = Mod modNm Nothing Nothing [] Rel.empty Rel.empty []
; cpUpdCU modNm (ecuStoreMod mod)
; cpUpdSI (\crsi -> crsi {crsiModMp = Map.insert modNm emptyModMpInfo mm})
}
cpUpdateModOffMp :: EHCCompileRunner m => [HsName] -> EHCompilePhaseT m ()
cpUpdateModOffMp modNmL@(modNm:_)
= do { cr <- get
; cpMsg modNm VerboseDebug "cpUpdateModOffMp"
; let crsi = _crStateInfo cr
offMp = crsiModOffMp crsi
(offMp',_)
= foldr add (offMp, Map.size offMp) modNmL
where add modNm (offMp, offset)
= case Map.lookup modNm offMp of
Just (o,_) -> (Map.insert modNm (o, new) offMp, offset )
_ -> (Map.insert modNm (o, new) offMp, offset')
where (o, offset') = refGen1 offset 1 modNm
where new = crsiExpNmOffMp modNm crsi
; cpUpdSI (\crsi -> crsi {crsiModOffMp = offMp'})
}
cpGenImportNameInfo :: EHCCompileRunner m => HsName -> EHCompilePhaseT m [HsName]
cpGenImportNameInfo modNm
= do { cr <- get
; let (ecu,crsi,opts,fp) = crBaseInfo modNm cr
isWholeProg = ehcOptOptimizationScope opts > OptimizationScope_PerModule
impNmL | isWholeProg = []
| otherwise = ecuImpNmL ecu
; return impNmL
}
cpUpdHiddenExports :: EHCCompileRunner m => HsName -> [(HsName,IdOccKind)] -> EHCompilePhaseT m ()
cpUpdHiddenExports modNm exps
= when (not $ null exps)
(do { cpUpdSI (\crsi -> crsi { crsiModMp = modMpAddHiddenExps modNm exps $ crsiModMp crsi
})
; cpUpdateModOffMp [modNm]
})