+-- | Print the error message and all warnings. Useful inside exception
+-- handlers. Clears warnings after printing.
+printExceptionAndWarnings :: GhcMonad m => SourceError -> m ()
+printExceptionAndWarnings err = do
+ let errs = srcErrorMessages err
+ warns <- getWarnings
+ dflags <- getSessionDynFlags
+ if isEmptyBag errs
+ -- Empty errors means we failed due to -Werror. (Since this function
+ -- takes a source error as argument, we know for sure _some_ error
+ -- did indeed happen.)
+ then liftIO $ do
+ printBagOfWarnings dflags warns
+ printBagOfErrors dflags (unitBag warnIsErrorMsg)
+ else liftIO $ printBagOfErrors dflags errs
+ clearWarnings
+
+-- | Print all accumulated warnings using 'log_action'.
+printWarnings :: GhcMonad m => m ()
+printWarnings = do
+ dflags <- getSessionDynFlags
+ warns <- getWarnings
+ liftIO $ printBagOfWarnings dflags warns
+ clearWarnings
+
+-- | Run function for the 'Ghc' monad.
+--
+-- It initialises the GHC session and warnings via 'initGhcMonad'. Each call
+-- to this function will create a new session which should not be shared among
+-- several threads.
+--
+-- Any errors not handled inside the 'Ghc' action are propagated as IO
+-- exceptions.
+
+runGhc :: Maybe FilePath -- ^ See argument to 'initGhcMonad'.
+ -> Ghc a -- ^ The action to perform.
+ -> IO a
+runGhc mb_top_dir ghc = do
+ wref <- newIORef emptyBag
+ ref <- newIORef undefined
+ let session = Session ref wref
+ flip unGhc session $ do
+ initGhcMonad mb_top_dir
+ ghc
+ -- XXX: unregister interrupt handlers here?
+
+-- | Run function for 'GhcT' monad transformer.
+--
+-- It initialises the GHC session and warnings via 'initGhcMonad'. Each call
+-- to this function will create a new session which should not be shared among
+-- several threads.
+
+runGhcT :: (ExceptionMonad m, Functor m, MonadIO m) =>
+ Maybe FilePath -- ^ See argument to 'initGhcMonad'.
+ -> GhcT m a -- ^ The action to perform.
+ -> m a
+runGhcT mb_top_dir ghct = do
+ wref <- liftIO $ newIORef emptyBag
+ ref <- liftIO $ newIORef undefined
+ let session = Session ref wref
+ flip unGhcT session $ do
+ initGhcMonad mb_top_dir
+ ghct
+
+-- | Initialise a GHC session.
+--
+-- If you implement a custom 'GhcMonad' you must call this function in the
+-- monad run function. It will initialise the session variable and clear all
+-- warnings.
+--
+-- The first argument should point to the directory where GHC's library files
+-- reside. More precisely, this should be the output of @ghc --print-libdir@
+-- of the version of GHC the module using this API is compiled with. For
+-- portability, you should use the @ghc-paths@ package, available at
+-- <http://hackage.haskell.org/cgi-bin/hackage-scripts/package/ghc-paths>.
+
+initGhcMonad :: GhcMonad m => Maybe FilePath -> m ()
+initGhcMonad mb_top_dir = do