1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
{-# LANGUAGE DerivingVia #-}
module GHC.Driver.Env.Types
( Hsc(..)
, HscEnv(..)
) where
import GHC.Driver.Errors.Types ( GhcMessage )
import {-# SOURCE #-} GHC.Driver.Hooks
import GHC.Driver.Session ( ContainsDynFlags(..), HasDynFlags(..), DynFlags )
import GHC.Driver.LlvmConfigCache (LlvmConfigCache)
import GHC.Prelude
import GHC.Runtime.Context
import GHC.Runtime.Interpreter.Types ( Interp )
import GHC.Types.Error ( Messages )
import GHC.Types.Name.Cache
import GHC.Types.Target
import GHC.Types.TypeEnv
import GHC.Unit.Finder.Types
import GHC.Unit.Module.Graph
import GHC.Unit.Env
import GHC.Utils.Logger
import GHC.Utils.TmpFs
import {-# SOURCE #-} GHC.Driver.Plugins
import Control.Monad.IO.Class
import Control.Monad.Trans.Reader
import Control.Monad.Trans.State
import Data.IORef
import GHC.Driver.Env.KnotVars
-- | The Hsc monad: Passing an environment and diagnostic state
newtype Hsc a = Hsc (HscEnv -> Messages GhcMessage -> IO (a, Messages GhcMessage))
deriving (Functor, Applicative, Monad, MonadIO)
via ReaderT HscEnv (StateT (Messages GhcMessage) IO)
instance HasDynFlags Hsc where
getDynFlags = Hsc $ \e w -> return (hsc_dflags e, w)
instance ContainsDynFlags HscEnv where
extractDynFlags h = hsc_dflags h
instance HasLogger Hsc where
getLogger = Hsc $ \e w -> return (hsc_logger e, w)
-- | HscEnv is like 'GHC.Driver.Monad.Session', except that some of the fields are immutable.
-- An HscEnv is used to compile a single module from plain Haskell source
-- code (after preprocessing) to either C, assembly or C--. It's also used
-- to store the dynamic linker state to allow for multiple linkers in the
-- same address space.
-- Things like the module graph don't change during a single compilation.
--
-- Historical note: \"hsc\" used to be the name of the compiler binary,
-- when there was a separate driver and compiler. To compile a single
-- module, the driver would invoke hsc on the source code... so nowadays
-- we think of hsc as the layer of the compiler that deals with compiling
-- a single module.
data HscEnv
= HscEnv {
hsc_dflags :: DynFlags,
-- ^ The dynamic flag settings
hsc_targets :: [Target],
-- ^ The targets (or roots) of the current session
hsc_mod_graph :: ModuleGraph,
-- ^ The module graph of the current session
hsc_IC :: InteractiveContext,
-- ^ The context for evaluating interactive statements
hsc_NC :: {-# UNPACK #-} !NameCache,
-- ^ Global Name cache so that each Name gets a single Unique.
-- Also track the origin of the Names.
hsc_FC :: {-# UNPACK #-} !FinderCache,
-- ^ The cached result of performing finding in the file system
hsc_type_env_vars :: KnotVars (IORef TypeEnv)
-- ^ Used for one-shot compilation only, to initialise
-- the 'IfGblEnv'. See 'GHC.Tc.Utils.tcg_type_env_var' for
-- 'GHC.Tc.Utils.TcGblEnv'. See also Note [hsc_type_env_var hack]
, hsc_interp :: Maybe Interp
-- ^ target code interpreter (if any) to use for TH and GHCi.
-- See Note [Target code interpreter]
, hsc_plugins :: !Plugins
-- ^ Plugins
, hsc_unit_env :: UnitEnv
-- ^ Unit environment (unit state, home unit, etc.).
--
-- Initialized from the databases cached in 'hsc_unit_dbs' and
-- from the DynFlags.
, hsc_logger :: !Logger
-- ^ Logger with its flags.
--
-- Don't forget to update the logger flags if the logging
-- related DynFlags change. Or better, use hscSetFlags setter
-- which does it.
, hsc_hooks :: !Hooks
-- ^ Hooks
, hsc_tmpfs :: !TmpFs
-- ^ Temporary files
, hsc_llvm_config :: !LlvmConfigCache
-- ^ LLVM configuration cache.
}
|