{-# LANGUAGE NamedFieldPuns #-}-- | The CompPipeline monad and associated ops---- Defined in separate module so that it can safely be imported from HooksmodulePipelineMonad(CompPipeline (..),evalP ,PhasePlus (..),PipeEnv (..),PipeState (..),PipelineOutput (..),getPipeEnv ,getPipeState ,setDynFlags ,setModLocation ,setForeignOs )whereimportGhcPrelude importMonadUtils importOutputable importDynFlags importDriverPhases importHscTypes importModule importFileCleanup (TempFileLifetime )importControl.MonadnewtypeCompPipeline a =P {unP ::PipeEnv ->PipeState ->IO(PipeState ,a )}evalP::CompPipeline a ->PipeEnv ->PipeState ->IOa evalP f env st =liftMsnd$unPf env st instanceFunctorCompPipeline wherefmap =liftMinstanceApplicativeCompPipeline wherepure a =P $\_env state ->return(state ,a )(<*> )=apinstanceMonadCompPipeline whereP m >>= k =P $\env state ->do(state' ,a )<-m env state unP(k a )env state' instanceMonadIOCompPipeline whereliftIO m =P $\_env state ->doa <-m ;return(state ,a )dataPhasePlus =RealPhase Phase |HscOut HscSource ModuleName HscStatus instanceOutputable PhasePlus whereppr (RealPhase p )=ppr p ppr(HscOut {})=text "HscOut"-- ------------------------------------------------------------------------------- The pipeline uses a monad to carry around various bits of information-- PipeEnv: invariant information passed downdataPipeEnv =PipeEnv {stop_phase ::Phase ,-- ^ Stop just before this phasesrc_filename ::String,-- ^ basename of original input sourcesrc_basename ::String,-- ^ basename of original input sourcesrc_suffix ::String,-- ^ its extensionoutput_spec ::PipelineOutput -- ^ says where to put the pipeline output}-- PipeState: information that might change during a pipeline rundataPipeState =PipeState {hsc_env ::HscEnv ,-- ^ only the DynFlags change in the HscEnv. The DynFlags change-- at various points, for example when we read the OPTIONS_GHC-- pragmas in the Cpp phase.maybe_loc ::MaybeModLocation ,-- ^ the ModLocation. This is discovered during compilation,-- in the Hsc phase where we read the module header.foreign_os ::[FilePath]-- ^ additional object files resulting from compiling foreign-- code. They come from two sources: foreign stubs, and-- add{C,Cxx,Objc,Objcxx}File from template haskell}dataPipelineOutput =Temporary TempFileLifetime -- ^ Output should be to a temporary file: we're going to-- run more compilation steps on this output later.|Persistent -- ^ We want a persistent file, i.e. a file in the current directory-- derived from the input filename, but with the appropriate extension.-- eg. in "ghc -c Foo.hs" the output goes into ./Foo.o.|SpecificFile -- ^ The output must go into the specific outputFile in DynFlags.-- We don't store the filename in the constructor as it changes-- when doing -dynamic-too.derivingShowgetPipeEnv::CompPipeline PipeEnv getPipeEnv =P $\env state ->return(state ,env )getPipeState::CompPipeline PipeState getPipeState =P $\_env state ->return(state ,state )instanceHasDynFlags CompPipeline wheregetDynFlags =P $\_env state ->return(state ,hsc_dflags(hsc_envstate ))setDynFlags::DynFlags ->CompPipeline ()setDynFlags dflags =P $\_env state ->return(state {hsc_env=(hsc_envstate ){hsc_dflags=dflags }},())setModLocation::ModLocation ->CompPipeline ()setModLocation loc =P $\_env state ->return(state {maybe_loc=Justloc },())setForeignOs::[FilePath]->CompPipeline ()setForeignOs os =P $\_env state ->return(state {foreign_os=os },())