summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ghc/compiler/coreSyn/CoreLint.lhs4
-rw-r--r--ghc/compiler/deSugar/Desugar.lhs23
-rw-r--r--ghc/compiler/ghci/InteractiveUI.hs3
-rw-r--r--ghc/compiler/ghci/Linker.lhs9
-rw-r--r--ghc/compiler/main/CodeOutput.lhs2
-rw-r--r--ghc/compiler/main/DriverMkDepend.hs6
-rw-r--r--ghc/compiler/main/DriverPipeline.hs91
-rw-r--r--ghc/compiler/main/DynFlags.hs20
-rw-r--r--ghc/compiler/main/ErrUtils.lhs97
-rw-r--r--ghc/compiler/main/GHC.hs121
-rw-r--r--ghc/compiler/main/HscMain.lhs62
-rw-r--r--ghc/compiler/main/Main.hs3
-rw-r--r--ghc/compiler/main/Packages.lhs15
-rw-r--r--ghc/compiler/main/SysTools.lhs117
-rw-r--r--ghc/compiler/typecheck/TcRnMonad.lhs10
-rw-r--r--ghc/compiler/utils/Outputable.lhs2
16 files changed, 363 insertions, 222 deletions
diff --git a/ghc/compiler/coreSyn/CoreLint.lhs b/ghc/compiler/coreSyn/CoreLint.lhs
index f94314c053..fc25c9a27e 100644
--- a/ghc/compiler/coreSyn/CoreLint.lhs
+++ b/ghc/compiler/coreSyn/CoreLint.lhs
@@ -67,7 +67,7 @@ endPass dflags pass_name dump_flag binds
-- Report result size if required
-- This has the side effect of forcing the intermediate to be evaluated
debugTraceMsg dflags 2 $
- " Result size = " ++ show (coreBindsSize binds)
+ (text " Result size =" <+> int (coreBindsSize binds))
-- Report verbosely, if required
dumpIfSet_core dflags dump_flag pass_name (pprCoreBindings binds)
@@ -120,7 +120,7 @@ lintCoreBindings dflags whoDunnit binds
= case (initL (lint_binds binds)) of
Nothing -> showPass dflags ("Core Linted result of " ++ whoDunnit)
Just bad_news -> printDump (display bad_news) >>
- ghcExit 1
+ ghcExit dflags 1
where
-- Put all the top-level binders in scope at the start
-- This is because transformation rules can bring something
diff --git a/ghc/compiler/deSugar/Desugar.lhs b/ghc/compiler/deSugar/Desugar.lhs
index be5ad1e544..c6e75badc5 100644
--- a/ghc/compiler/deSugar/Desugar.lhs
+++ b/ghc/compiler/deSugar/Desugar.lhs
@@ -12,7 +12,7 @@ import DynFlags ( DynFlag(..), DynFlags(..), dopt, GhcMode(..) )
import StaticFlags ( opt_SccProfilingOn )
import DriverPhases ( isHsBoot )
import HscTypes ( ModGuts(..), HscEnv(..),
- Dependencies(..), TypeEnv, IsBootInterface )
+ Dependencies(..), ForeignStubs(..), TypeEnv, IsBootInterface )
import HsSyn ( RuleDecl(..), RuleBndr(..), LHsExpr, LRuleDecl )
import TcRnTypes ( TcGblEnv(..), ImportAvails(..) )
import MkIface ( mkUsageInfo )
@@ -35,7 +35,7 @@ import Rules ( roughTopNames )
import CoreLint ( showPass, endPass )
import CoreFVs ( ruleRhsFreeVars, exprsFreeNames )
import Packages ( PackageState(thPackageId), PackageIdH(..) )
-import ErrUtils ( doIfSet, dumpIfSet_dyn, pprBagOfWarnings,
+import ErrUtils ( doIfSet, dumpIfSet_dyn, printBagOfWarnings,
errorsFound, WarnMsg )
import ListSetOps ( insertList )
import Outputable
@@ -79,13 +79,16 @@ deSugar hsc_env
-- Desugar the program
; ((all_prs, ds_rules, ds_fords), warns)
- <- initDs hsc_env mod rdr_env type_env $ do
- { core_prs <- dsTopLHsBinds auto_scc binds
- ; (ds_fords, foreign_prs) <- dsForeigns fords
- ; let all_prs = foreign_prs ++ core_prs
- local_bndrs = mkVarSet (map fst all_prs)
- ; ds_rules <- mappM (dsRule mod local_bndrs) rules
- ; return (all_prs, catMaybes ds_rules, ds_fords) }
+ <- case ghcMode (hsc_dflags hsc_env) of
+ JustTypecheck -> return (([], [], NoStubs), emptyBag)
+ _ -> initDs hsc_env mod rdr_env type_env $ do
+ { core_prs <- dsTopLHsBinds auto_scc binds
+ ; (ds_fords, foreign_prs) <- dsForeigns fords
+ ; let all_prs = foreign_prs ++ core_prs
+ local_bndrs = mkVarSet (map fst all_prs)
+ ; ds_rules <- mappM (dsRule mod local_bndrs) rules
+ ; return (all_prs, catMaybes ds_rules, ds_fords)
+ }
-- If warnings are considered errors, leave.
; if errorsFound dflags (warns, emptyBag)
@@ -185,7 +188,7 @@ deSugarExpr hsc_env this_mod rdr_env type_env tc_expr
-- Display any warnings
-- Note: if -Werror is used, we don't signal an error here.
; doIfSet (not (isEmptyBag ds_warns))
- (printErrs (pprBagOfWarnings ds_warns))
+ (printBagOfWarnings dflags ds_warns)
-- Dump output
; dumpIfSet_dyn dflags Opt_D_dump_ds "Desugared" (pprCoreExpr core_expr)
diff --git a/ghc/compiler/ghci/InteractiveUI.hs b/ghc/compiler/ghci/InteractiveUI.hs
index 67c68d3b16..3469421b18 100644
--- a/ghc/compiler/ghci/InteractiveUI.hs
+++ b/ghc/compiler/ghci/InteractiveUI.hs
@@ -37,7 +37,6 @@ import StaticFlags ( opt_IgnoreDotGhci )
import Linker ( showLinkerState )
import Util ( removeSpaces, handle, global, toArgs,
looksLikeModuleName, prefixMatch, sortLe )
-import ErrUtils ( printErrorsAndWarnings )
#ifndef mingw32_HOST_OS
import System.Posix
@@ -675,7 +674,7 @@ checkModule :: String -> GHCi ()
checkModule m = do
let modl = mkModule m
session <- getSession
- result <- io (GHC.checkModule session modl printErrorsAndWarnings)
+ result <- io (GHC.checkModule session modl)
case result of
Nothing -> io $ putStrLn "Nothing"
Just r -> io $ putStrLn (showSDoc (
diff --git a/ghc/compiler/ghci/Linker.lhs b/ghc/compiler/ghci/Linker.lhs
index 81b512feee..162adbf04d 100644
--- a/ghc/compiler/ghci/Linker.lhs
+++ b/ghc/compiler/ghci/Linker.lhs
@@ -623,12 +623,9 @@ unload dflags linkables
new_pls <- unload_wkr dflags linkables pls
writeIORef v_PersistentLinkerState new_pls
- debugTraceMsg dflags 3 (showSDoc
- (text "unload: retaining objs" <+> ppr (objs_loaded new_pls)))
- debugTraceMsg dflags 3 (showSDoc
- (text "unload: retaining bcos" <+> ppr (bcos_loaded new_pls)))
-
- return ()
+ debugTraceMsg dflags 3 (text "unload: retaining objs" <+> ppr (objs_loaded new_pls))
+ debugTraceMsg dflags 3 (text "unload: retaining bcos" <+> ppr (bcos_loaded new_pls))
+ return ()
unload_wkr :: DynFlags
-> [Linkable] -- stable linkables
diff --git a/ghc/compiler/main/CodeOutput.lhs b/ghc/compiler/main/CodeOutput.lhs
index 24d67910a4..ce12d0cc0c 100644
--- a/ghc/compiler/main/CodeOutput.lhs
+++ b/ghc/compiler/main/CodeOutput.lhs
@@ -71,7 +71,7 @@ codeOutput dflags this_mod foreign_stubs pkg_deps flat_abstractC
; let lints = map cmmLint flat_abstractC
; case firstJust lints of
Just err -> do { printDump err
- ; ghcExit 1
+ ; ghcExit dflags 1
}
Nothing -> return ()
}
diff --git a/ghc/compiler/main/DriverMkDepend.hs b/ghc/compiler/main/DriverMkDepend.hs
index 3e35b758e1..fe2d8f3785 100644
--- a/ghc/compiler/main/DriverMkDepend.hs
+++ b/ghc/compiler/main/DriverMkDepend.hs
@@ -62,15 +62,15 @@ doMkDependHS session srcs
; excl_mods <- readIORef v_Dep_exclude_mods
; r <- GHC.depanal session excl_mods True {- Allow dup roots -}
; case r of
- Left e -> do printErrorsAndWarnings e; exitWith (ExitFailure 1)
- Right mod_summaries -> do {
+ Nothing -> exitWith (ExitFailure 1)
+ Just mod_summaries -> do {
-- Sort into dependency order
-- There should be no cycles
let sorted = GHC.topSortModuleGraph False mod_summaries Nothing
-- Print out the dependencies if wanted
- ; debugTraceMsg dflags 2 (showSDoc (text "Module dependencies" $$ ppr sorted))
+ ; debugTraceMsg dflags 2 (text "Module dependencies" $$ ppr sorted)
-- Prcess them one by one, dumping results into makefile
-- and complaining about cycles
diff --git a/ghc/compiler/main/DriverPipeline.hs b/ghc/compiler/main/DriverPipeline.hs
index 025a09bff2..698cb42c95 100644
--- a/ghc/compiler/main/DriverPipeline.hs
+++ b/ghc/compiler/main/DriverPipeline.hs
@@ -55,6 +55,8 @@ import FastString ( mkFastString )
import Bag ( listToBag, emptyBag )
import SrcLoc ( Located(..) )
+import Distribution.Compiler ( extensionsToGHCFlag )
+
import EXCEPTION
import DATA_IOREF ( readIORef, writeIORef, IORef )
import GLAEXTS ( Int(..) )
@@ -93,7 +95,6 @@ preprocess dflags (filename, mb_phase) =
-- NB. No old interface can also mean that the source has changed.
compile :: HscEnv
- -> (Messages -> IO ()) -- error message callback
-> ModSummary
-> Maybe Linkable -- Just linkable <=> source unchanged
-> Maybe ModIface -- Old interface, if available
@@ -108,7 +109,7 @@ data CompResult
| CompErrs
-compile hsc_env msg_act mod_summary maybe_old_linkable old_iface mod_index nmods = do
+compile hsc_env mod_summary maybe_old_linkable old_iface mod_index nmods = do
let dflags0 = hsc_dflags hsc_env
this_mod = ms_mod mod_summary
@@ -124,16 +125,16 @@ compile hsc_env msg_act mod_summary maybe_old_linkable old_iface mod_index nmods
let input_fn = expectJust "compile:hs" (ml_hs_file location)
let input_fnpp = expectJust "compile:hspp" (ms_hspp_file mod_summary)
- debugTraceMsg dflags0 2 ("compile: input file " ++ input_fnpp)
+ debugTraceMsg dflags0 2 (text "compile: input file" <+> text input_fnpp)
-- Add in the OPTIONS from the source file
-- This is nasty: we've done this once already, in the compilation manager
-- It might be better to cache the flags in the ml_hspp_file field,say
let hspp_buf = expectJust "compile:hspp_buf" (ms_hspp_buf mod_summary)
- opts = getOptionsFromStringBuffer hspp_buf
+ opts = getOptionsFromStringBuffer hspp_buf input_fn
(dflags1,unhandled_flags) <- parseDynamicFlags dflags0 (map snd opts)
if (not (null unhandled_flags))
- then do msg_act (optionsErrorMsgs unhandled_flags opts input_fn)
+ then do printErrorsAndWarnings dflags1 (optionsErrorMsgs unhandled_flags opts input_fn)
return CompErrs
else do
@@ -167,7 +168,7 @@ compile hsc_env msg_act mod_summary maybe_old_linkable old_iface mod_index nmods
object_filename = ml_obj_file location
-- run the compiler
- hsc_result <- hscMain hsc_env' msg_act mod_summary
+ hsc_result <- hscMain hsc_env' mod_summary
source_unchanged have_object old_iface
(Just (mod_index, nmods))
@@ -298,15 +299,16 @@ link BatchCompile dflags batch_attempt_linking hpt
-- the linkables to link
linkables = map (fromJust.hm_linkable) home_mod_infos
- debugTraceMsg dflags 3 "link: linkables are ..."
- debugTraceMsg dflags 3 (showSDoc (vcat (map ppr linkables)))
+ debugTraceMsg dflags 3 (text "link: linkables are ..." $$ vcat (map ppr linkables))
-- check for the -no-link flag
if isNoLink (ghcLink dflags)
- then do debugTraceMsg dflags 3 "link(batch): linking omitted (-c flag given)."
+ then do debugTraceMsg dflags 3 (text "link(batch): linking omitted (-c flag given).")
return Succeeded
else do
+ debugTraceMsg dflags 1 (text "Linking ...")
+
let getOfiles (LM _ _ us) = map nameOfObject (filter isObject us)
obj_files = concatMap getOfiles linkables
@@ -322,23 +324,23 @@ link BatchCompile dflags batch_attempt_linking hpt
any (t <) (map linkableTime linkables)
if dopt Opt_RecompChecking dflags && not linking_needed
- then do debugTraceMsg dflags 1 (exe_file ++ " is up to date, linking not required.")
+ then do debugTraceMsg dflags 1 (text exe_file <+> ptext SLIT("is up to date, linking not required."))
return Succeeded
else do
- debugTraceMsg dflags 1 "Linking ..."
+ debugTraceMsg dflags 1 (ptext SLIT("Linking ..."))
-- Don't showPass in Batch mode; doLink will do that for us.
staticLink dflags obj_files pkg_deps
- debugTraceMsg dflags 3 "link: done"
+ debugTraceMsg dflags 3 (text "link: done")
-- staticLink only returns if it succeeds
return Succeeded
| otherwise
- = do debugTraceMsg dflags 3 "link(batch): upsweep (partially) failed OR"
- debugTraceMsg dflags 3 " Main.main not exported; not linking."
+ = do debugTraceMsg dflags 3 (text "link(batch): upsweep (partially) failed OR" $$
+ text " Main.main not exported; not linking.")
return Succeeded
@@ -751,7 +753,7 @@ runPhase (Hsc src_flavour) stop dflags0 basename suff input_fn get_output_fn _ma
addHomeModuleToFinder hsc_env mod_name location4
-- run the compiler!
- result <- hscMain hsc_env printErrorsAndWarnings
+ result <- hscMain hsc_env
mod_summary source_unchanged
False -- No object file
Nothing -- No iface
@@ -1341,14 +1343,19 @@ hsSourceCppOpts =
-----------------------------------------------------------------------------
-- Reading OPTIONS pragmas
+-- This is really very ugly and should be rewritten.
+-- - some error messages are thrown as exceptions (should return)
+-- - we ignore LINE pragmas
+-- - parsing is horrible, combination of prefixMatch and 'read'.
+
getOptionsFromSource
:: String -- input file
-> IO [String] -- options, if any
getOptionsFromSource file
= do h <- openFile file ReadMode
- look h `finally` hClose h
+ look h 1 `finally` hClose h
where
- look h = do
+ look h i = do
r <- tryJust ioErrors (hGetLine h)
case r of
Left e | isEOFError e -> return []
@@ -1356,16 +1363,16 @@ getOptionsFromSource file
Right l' -> do
let l = removeSpaces l'
case () of
- () | null l -> look h
- | prefixMatch "#" l -> look h
- | prefixMatch "{-# LINE" l -> look h -- -}
- | Just opts <- matchOptions l
- -> do rest <- look h
+ () | null l -> look h (i+1)
+ | prefixMatch "#" l -> look h (i+1)
+ | prefixMatch "{-# LINE" l -> look h (i+1) -- -} wrong!
+ | Just opts <- matchOptions i file l
+ -> do rest <- look h (i+1)
return (opts ++ rest)
| otherwise -> return []
-getOptionsFromStringBuffer :: StringBuffer -> [(Int,String)]
-getOptionsFromStringBuffer buffer@(StringBuffer _ len# _) =
+getOptionsFromStringBuffer :: StringBuffer -> FilePath -> [(Int,String)]
+getOptionsFromStringBuffer buffer@(StringBuffer _ len# _) fn =
let
ls = lines (lexemeToString buffer (I# len#)) -- lazy, so it's ok
in
@@ -1377,37 +1384,57 @@ getOptionsFromStringBuffer buffer@(StringBuffer _ len# _) =
case () of
() | null l -> look (i+1) ls
| prefixMatch "#" l -> look (i+1) ls
- | prefixMatch "{-# LINE" l -> look (i+1) ls -- -}
- | Just opts <- matchOptions l
+ | prefixMatch "{-# LINE" l -> look (i+1) ls -- -} wrong!
+ | Just opts <- matchOptions i fn l
-> zip (repeat i) opts ++ look (i+1) ls
| otherwise -> []
-- detect {-# OPTIONS_GHC ... #-}. For the time being, we accept OPTIONS
-- instead of OPTIONS_GHC, but that is deprecated.
-matchOptions s
+matchOptions i fn s
| Just s1 <- maybePrefixMatch "{-#" s -- -}
- = matchOptions1 (removeSpaces s1)
+ = matchOptions1 i fn (removeSpaces s1)
| otherwise
= Nothing
where
- matchOptions1 s
+ matchOptions1 i fn s
| Just s2 <- maybePrefixMatch "OPTIONS" s
= case () of
_ | Just s3 <- maybePrefixMatch "_GHC" s2, not (is_ident (head s3))
- -> matchOptions2 s3
+ -> matchOptions2 i fn s3
| not (is_ident (head s2))
- -> matchOptions2 s2
+ -> matchOptions2 i fn s2
| otherwise
-> Just [] -- OPTIONS_anything is ignored, not treated as start of source
| Just s2 <- maybePrefixMatch "INCLUDE" s, not (is_ident (head s2)),
Just s3 <- maybePrefixMatch "}-#" (reverse s2)
= Just ["-#include", removeSpaces (reverse s3)]
+
+ | Just s2 <- maybePrefixMatch "LANGUAGE" s, not (is_ident (head s2)),
+ Just s3 <- maybePrefixMatch "}-#" (reverse s2)
+ = case [ exts | (exts,"") <- reads ('[' : reverse (']':s3))] of
+ [] -> languagePragParseError i fn
+ exts:_ -> case extensionsToGHCFlag exts of
+ ([], opts) -> Just opts
+ (unsup,_) -> unsupportedExtnError i fn unsup
| otherwise = Nothing
- matchOptions2 s
+ matchOptions2 i fn s
| Just s3 <- maybePrefixMatch "}-#" (reverse s) = Just (words (reverse s3))
| otherwise = Nothing
+languagePragParseError i fn =
+ pgmError (showSDoc (mkLocMessage loc (
+ text "cannot parse LANGUAGE pragma")))
+ where loc = srcLocSpan (mkSrcLoc (mkFastString fn) i 0)
+
+unsupportedExtnError i fn unsup =
+ pgmError (showSDoc (mkLocMessage loc (
+ text "unsupported extensions: " <>
+ hcat (punctuate comma (map (text.show) unsup)))))
+ where loc = srcLocSpan (mkSrcLoc (mkFastString fn) i 0)
+
+
optionsErrorMsgs :: [String] -> [(Int,String)] -> FilePath -> Messages
optionsErrorMsgs unhandled_flags flags_lines filename
= (emptyBag, listToBag (map mkMsg unhandled_flags_lines))
diff --git a/ghc/compiler/main/DynFlags.hs b/ghc/compiler/main/DynFlags.hs
index c5156eef94..52e5542509 100644
--- a/ghc/compiler/main/DynFlags.hs
+++ b/ghc/compiler/main/DynFlags.hs
@@ -56,6 +56,7 @@ import Config
import CmdLineParser
import Panic ( panic, GhcException(..) )
import Util ( notNull, splitLongestPrefix, split, normalisePath )
+import SrcLoc ( SrcSpan )
import DATA_IOREF ( readIORef )
import EXCEPTION ( throwDyn )
@@ -66,6 +67,9 @@ import Data.List ( isPrefixOf )
import Maybe ( fromJust )
import Char ( isDigit, isUpper )
import Outputable
+import System.IO ( hPutStrLn, stderr )
+import {-# SOURCE #-} ErrUtils ( Severity(..), Message, mkLocMessage )
+
-- -----------------------------------------------------------------------------
-- DynFlags
@@ -180,7 +184,7 @@ data DynFlag
| Opt_KeepTmpFiles
deriving (Eq)
-
+
data DynFlags = DynFlags {
ghcMode :: GhcMode,
ghcLink :: GhcLink,
@@ -254,7 +258,10 @@ data DynFlags = DynFlags {
pkgState :: PackageState,
-- hsc dynamic flags
- flags :: [DynFlag]
+ flags :: [DynFlag],
+
+ -- message output
+ log_action :: Severity -> SrcSpan -> PprStyle -> Message -> IO ()
}
data HscTarget
@@ -395,7 +402,13 @@ defaultDynFlags =
Opt_IgnoreInterfacePragmas,
Opt_OmitInterfacePragmas
- ] ++ standardWarnings
+ ] ++ standardWarnings,
+
+ log_action = \severity srcSpan style msg ->
+ case severity of
+ SevInfo -> hPutStrLn stderr (show (msg style))
+ SevFatal -> hPutStrLn stderr (show (msg style))
+ _ -> hPutStrLn stderr ('\n':show ((mkLocMessage srcSpan msg) style))
}
{-
@@ -602,7 +615,6 @@ getCoreToDo dflags
MaxSimplifierIterations max_iter
]
]
-
else {- opt_level >= 1 -} [
-- initial simplify: mk specialiser happy: minimum effort please
diff --git a/ghc/compiler/main/ErrUtils.lhs b/ghc/compiler/main/ErrUtils.lhs
index 50db73c3b4..90e5dc87b6 100644
--- a/ghc/compiler/main/ErrUtils.lhs
+++ b/ghc/compiler/main/ErrUtils.lhs
@@ -6,24 +6,25 @@
\begin{code}
module ErrUtils (
Message, mkLocMessage, printError,
+ Severity(..),
ErrMsg, WarnMsg,
errMsgSpans, errMsgContext, errMsgShortDoc, errMsgExtraInfo,
Messages, errorsFound, emptyMessages,
mkErrMsg, mkWarnMsg, mkPlainErrMsg, mkLongErrMsg,
- printErrorsAndWarnings, pprBagOfErrors, pprBagOfWarnings,
+ printErrorsAndWarnings, printBagOfErrors, printBagOfWarnings,
ghcExit,
doIfSet, doIfSet_dyn,
- dumpIfSet, dumpIfSet_core, dumpIfSet_dyn, dumpIfSet_dyn_or, mkDumpDoc,
- showPass,
+ dumpIfSet, dumpIfSet_core, dumpIfSet_dyn, dumpIfSet_dyn_or, mkDumpDoc,
-- * Messages during compilation
- setMsgHandler,
putMsg,
- compilationProgressMsg,
- debugTraceMsg,
errorMsg,
+ fatalErrorMsg,
+ compilationProgressMsg,
+ showPass,
+ debugTraceMsg,
) where
#include "HsVersions.h"
@@ -33,7 +34,7 @@ import SrcLoc ( SrcSpan )
import Util ( sortLe, global )
import Outputable
import qualified Pretty
-import SrcLoc ( srcSpanStart )
+import SrcLoc ( srcSpanStart, noSrcSpan )
import DynFlags ( DynFlags(..), DynFlag(..), dopt )
import StaticFlags ( opt_ErrorSpans )
import System ( ExitCode(..), exitWith )
@@ -47,6 +48,12 @@ import DYNAMIC
type Message = SDoc
+data Severity
+ = SevInfo
+ | SevWarning
+ | SevError
+ | SevFatal
+
mkLocMessage :: SrcSpan -> Message -> Message
mkLocMessage locn msg
| opt_ErrorSpans = hang (ppr locn <> colon) 4 msg
@@ -117,22 +124,20 @@ errorsFound dflags (warns, errs)
| dopt Opt_WarnIsError dflags = not (isEmptyBag errs) || not (isEmptyBag warns)
| otherwise = not (isEmptyBag errs)
-printErrorsAndWarnings :: Messages -> IO ()
-printErrorsAndWarnings (warns, errs)
+printErrorsAndWarnings :: DynFlags -> Messages -> IO ()
+printErrorsAndWarnings dflags (warns, errs)
| no_errs && no_warns = return ()
- | no_errs = printErrs (pprBagOfWarnings warns)
+ | no_errs = printBagOfWarnings dflags warns
-- Don't print any warnings if there are errors
- | otherwise = printErrs (pprBagOfErrors errs)
+ | otherwise = printBagOfErrors dflags errs
where
no_warns = isEmptyBag warns
no_errs = isEmptyBag errs
-pprBagOfErrors :: Bag ErrMsg -> Pretty.Doc
-pprBagOfErrors bag_of_errors
- = Pretty.vcat [ let style = mkErrStyle unqual
- doc = mkLocMessage s (d $$ e)
- in
- Pretty.text "" Pretty.$$ doc style
+printBagOfErrors :: DynFlags -> Bag ErrMsg -> IO ()
+printBagOfErrors dflags bag_of_errors
+ = sequence_ [ let style = mkErrStyle unqual
+ in log_action dflags SevError s style (d $$ e)
| ErrMsg { errMsgSpans = s:ss,
errMsgShortDoc = d,
errMsgExtraInfo = e,
@@ -147,15 +152,30 @@ pprBagOfErrors bag_of_errors
EQ -> True
GT -> False
-pprBagOfWarnings :: Bag WarnMsg -> Pretty.Doc
-pprBagOfWarnings bag_of_warns = pprBagOfErrors bag_of_warns
+printBagOfWarnings :: DynFlags -> Bag ErrMsg -> IO ()
+printBagOfWarnings dflags bag_of_warns
+ = sequence_ [ let style = mkErrStyle unqual
+ in log_action dflags SevWarning s style (d $$ e)
+ | ErrMsg { errMsgSpans = s:ss,
+ errMsgShortDoc = d,
+ errMsgExtraInfo = e,
+ errMsgContext = unqual } <- sorted_errs ]
+ where
+ bag_ls = bagToList bag_of_warns
+ sorted_errs = sortLe occ'ed_before bag_ls
+
+ occ'ed_before err1 err2 =
+ case compare (head (errMsgSpans err1)) (head (errMsgSpans err2)) of
+ LT -> True
+ EQ -> True
+ GT -> False
\end{code}
\begin{code}
-ghcExit :: Int -> IO ()
-ghcExit val
+ghcExit :: DynFlags -> Int -> IO ()
+ghcExit dflags val
| val == 0 = exitWith ExitSuccess
- | otherwise = do errorMsg "\nCompilation had errors\n\n"
+ | otherwise = do errorMsg dflags (text "\nCompilation had errors\n\n")
exitWith (ExitFailure val)
\end{code}
@@ -170,9 +190,6 @@ doIfSet_dyn dflags flag action | dopt flag dflags = action
\end{code}
\begin{code}
-showPass :: DynFlags -> String -> IO ()
-showPass dflags what = compilationPassMsg dflags ("*** "++what++":")
-
dumpIfSet :: Bool -> String -> SDoc -> IO ()
dumpIfSet flag hdr doc
| not flag = return ()
@@ -220,26 +237,24 @@ ifVerbose dflags val act
| verbosity dflags >= val = act
| otherwise = return ()
-errorMsg :: String -> IO ()
-errorMsg = putMsg
+putMsg :: DynFlags -> Message -> IO ()
+putMsg dflags msg = log_action dflags SevInfo noSrcSpan defaultUserStyle msg
+
+errorMsg :: DynFlags -> Message -> IO ()
+errorMsg dflags msg = log_action dflags SevError noSrcSpan defaultErrStyle msg
+
+fatalErrorMsg :: DynFlags -> Message -> IO ()
+fatalErrorMsg dflags msg = log_action dflags SevFatal noSrcSpan defaultErrStyle msg
compilationProgressMsg :: DynFlags -> String -> IO ()
compilationProgressMsg dflags msg
- = ifVerbose dflags 1 (putMsg msg)
+ = ifVerbose dflags 1 (log_action dflags SevInfo noSrcSpan defaultUserStyle (text msg))
-compilationPassMsg :: DynFlags -> String -> IO ()
-compilationPassMsg dflags msg
- = ifVerbose dflags 2 (putMsg msg)
+showPass :: DynFlags -> String -> IO ()
+showPass dflags what
+ = ifVerbose dflags 2 (log_action dflags SevInfo noSrcSpan defaultUserStyle (text "***" <+> text what <> colon))
-debugTraceMsg :: DynFlags -> Int -> String -> IO ()
+debugTraceMsg :: DynFlags -> Int -> Message -> IO ()
debugTraceMsg dflags val msg
- = ifVerbose dflags val (putMsg msg)
-
-GLOBAL_VAR(msgHandler, hPutStrLn stderr, (String -> IO ()))
-
-setMsgHandler :: (String -> IO ()) -> IO ()
-setMsgHandler handle_msg = writeIORef msgHandler handle_msg
-
-putMsg :: String -> IO ()
-putMsg msg = do h <- readIORef msgHandler; h msg
+ = ifVerbose dflags val (log_action dflags SevInfo noSrcSpan defaultDumpStyle msg)
\end{code}
diff --git a/ghc/compiler/main/GHC.hs b/ghc/compiler/main/GHC.hs
index 938757bb55..e222579a06 100644
--- a/ghc/compiler/main/GHC.hs
+++ b/ghc/compiler/main/GHC.hs
@@ -15,12 +15,11 @@ module GHC (
newSession,
-- * Flags and settings
- DynFlags(..), DynFlag(..), GhcMode(..), HscTarget(..), dopt,
+ DynFlags(..), DynFlag(..), Severity(..), GhcMode(..), HscTarget(..), dopt,
parseDynamicFlags,
initPackages,
getSessionDynFlags,
setSessionDynFlags,
- setMsgHandler,
-- * Targets
Target(..), TargetId(..), Phase,
@@ -33,7 +32,6 @@ module GHC (
-- * Loading\/compiling the program
depanal,
load, LoadHowMuch(..), SuccessFlag(..), -- also does depanal
- loadMsgs,
workingDirectoryChanged,
checkModule, CheckedModule(..),
TypecheckedSource, ParsedSource, RenamedSource,
@@ -220,9 +218,9 @@ import Module
import FiniteMap
import Panic
import Digraph
-import Bag ( unitBag, emptyBag )
-import ErrUtils ( showPass, Messages, putMsg, debugTraceMsg,
- mkPlainErrMsg, pprBagOfErrors )
+import Bag ( unitBag )
+import ErrUtils ( Severity(..), showPass, Messages, fatalErrorMsg, debugTraceMsg,
+ mkPlainErrMsg, printBagOfErrors, printErrorsAndWarnings )
import qualified ErrUtils
import Util
import StringBuffer ( StringBuffer, hGetStringBuffer )
@@ -252,23 +250,25 @@ import Prelude hiding (init)
-- Unless you want to handle exceptions yourself, you should wrap this around
-- the top level of your program. The default handlers output the error
-- message(s) to stderr and exit cleanly.
-defaultErrorHandler :: IO a -> IO a
-defaultErrorHandler inner =
+defaultErrorHandler :: DynFlags -> IO a -> IO a
+defaultErrorHandler dflags inner =
-- top-level exception handler: any unrecognised exception is a compiler bug.
handle (\exception -> do
hFlush stdout
case exception of
-- an IO exception probably isn't our fault, so don't panic
- IOException _ -> putMsg (show exception)
+ IOException _ ->
+ fatalErrorMsg dflags (text (show exception))
AsyncException StackOverflow ->
- putMsg "stack overflow: use +RTS -K<size> to increase it"
- _other -> putMsg (show (Panic (show exception)))
+ fatalErrorMsg dflags (text "stack overflow: use +RTS -K<size> to increase it")
+ _other ->
+ fatalErrorMsg dflags (text (show (Panic (show exception))))
exitWith (ExitFailure 1)
) $
-- program errors: messages with locations attached. Sometimes it is
-- convenient to just throw these as exceptions.
- handleDyn (\dyn -> do printErrs (pprBagOfErrors (unitBag dyn))
+ handleDyn (\dyn -> do printBagOfErrors dflags (unitBag dyn)
exitWith (ExitFailure 1)) $
-- error messages propagated as exceptions
@@ -277,7 +277,7 @@ defaultErrorHandler inner =
case dyn of
PhaseFailed _ code -> exitWith code
Interrupted -> exitWith (ExitFailure 1)
- _ -> do putMsg (show (dyn :: GhcException))
+ _ -> do fatalErrorMsg dflags (text (show (dyn :: GhcException)))
exitWith (ExitFailure 1)
) $
inner
@@ -353,12 +353,6 @@ getSessionDynFlags s = withSession s (return . hsc_dflags)
setSessionDynFlags :: Session -> DynFlags -> IO ()
setSessionDynFlags s dflags = modifySession s (\h -> h{ hsc_dflags = dflags })
--- | Messages during compilation (eg. warnings and progress messages)
--- are reported using this callback. By default, these messages are
--- printed to stderr.
-setMsgHandler :: (String -> IO ()) -> IO ()
-setMsgHandler = ErrUtils.setMsgHandler
-
-- -----------------------------------------------------------------------------
-- Targets
@@ -422,7 +416,7 @@ guessTarget file Nothing
-- Perform a dependency analysis starting from the current targets
-- and update the session with the new module graph.
-depanal :: Session -> [Module] -> Bool -> IO (Either Messages ModuleGraph)
+depanal :: Session -> [Module] -> Bool -> IO (Maybe ModuleGraph)
depanal (Session ref) excluded_mods allow_dup_roots = do
hsc_env <- readIORef ref
let
@@ -433,13 +427,13 @@ depanal (Session ref) excluded_mods allow_dup_roots = do
showPass dflags "Chasing dependencies"
when (gmode == BatchCompile) $
- debugTraceMsg dflags 1 (showSDoc (hcat [
+ debugTraceMsg dflags 1 (hcat [
text "Chasing modules from: ",
- hcat (punctuate comma (map pprTarget targets))]))
+ hcat (punctuate comma (map pprTarget targets))])
r <- downsweep hsc_env old_graph excluded_mods allow_dup_roots
case r of
- Right mod_graph -> writeIORef ref hsc_env{ hsc_mod_graph = mod_graph }
+ Just mod_graph -> writeIORef ref hsc_env{ hsc_mod_graph = mod_graph }
_ -> return ()
return r
@@ -468,24 +462,18 @@ data LoadHowMuch
-- attempt to load up to this target. If no Module is supplied,
-- then try to load all targets.
load :: Session -> LoadHowMuch -> IO SuccessFlag
-load session how_much =
- loadMsgs session how_much ErrUtils.printErrorsAndWarnings
-
--- | Version of 'load' that takes a callback function to be invoked
--- on compiler errors and warnings as they occur during compilation.
-loadMsgs :: Session -> LoadHowMuch -> (Messages-> IO ()) -> IO SuccessFlag
-loadMsgs s@(Session ref) how_much msg_act
+load s@(Session ref) how_much
= do
-- Dependency analysis first. Note that this fixes the module graph:
-- even if we don't get a fully successful upsweep, the full module
-- graph is still retained in the Session. We can tell which modules
-- were successfully loaded by inspecting the Session's HPT.
mb_graph <- depanal s [] False
- case mb_graph of
- Left msgs -> do msg_act msgs; return Failed
- Right mod_graph -> loadMsgs2 s how_much msg_act mod_graph
+ case mb_graph of
+ Just mod_graph -> load2 s how_much mod_graph
+ Nothing -> return Failed
-loadMsgs2 s@(Session ref) how_much msg_act mod_graph = do
+load2 s@(Session ref) how_much mod_graph = do
hsc_env <- readIORef ref
let hpt1 = hsc_HPT hsc_env
@@ -524,8 +512,8 @@ loadMsgs2 s@(Session ref) how_much msg_act mod_graph = do
evaluate pruned_hpt
- debugTraceMsg dflags 2 (showSDoc (text "Stable obj:" <+> ppr stable_obj $$
- text "Stable BCO:" <+> ppr stable_bco))
+ debugTraceMsg dflags 2 (text "Stable obj:" <+> ppr stable_obj $$
+ text "Stable BCO:" <+> ppr stable_bco)
-- Unload any modules which are going to be re-linked this time around.
let stable_linkables = [ linkable
@@ -587,7 +575,7 @@ loadMsgs2 s@(Session ref) how_much msg_act mod_graph = do
(upsweep_ok, hsc_env1, modsUpswept)
<- upsweep (hsc_env { hsc_HPT = emptyHomePackageTable })
- pruned_hpt stable_mods cleanup msg_act mg
+ pruned_hpt stable_mods cleanup mg
-- Make modsDone be the summaries for each home module now
-- available; this should equal the domain of hpt3.
@@ -602,7 +590,7 @@ loadMsgs2 s@(Session ref) how_much msg_act mod_graph = do
then
-- Easy; just relink it all.
- do debugTraceMsg dflags 2 "Upsweep completely successful."
+ do debugTraceMsg dflags 2 (text "Upsweep completely successful.")
-- Clean up after ourselves
cleanTempFilesExcept dflags (ppFilesFromSummaries modsDone)
@@ -624,9 +612,9 @@ loadMsgs2 s@(Session ref) how_much msg_act mod_graph = do
do_linking = a_root_is_Main || no_hs_main
when (ghci_mode == BatchCompile && isJust ofile && not do_linking) $
- debugTraceMsg dflags 1 ("Warning: output was redirected with -o, " ++
- "but no output will be generated\n" ++
- "because there is no " ++ main_mod ++ " module.")
+ debugTraceMsg dflags 1 (text ("Warning: output was redirected with -o, " ++
+ "but no output will be generated\n" ++
+ "because there is no " ++ main_mod ++ " module."))
-- link everything together
linkresult <- link ghci_mode dflags do_linking (hsc_HPT hsc_env1)
@@ -637,7 +625,7 @@ loadMsgs2 s@(Session ref) how_much msg_act mod_graph = do
-- Tricky. We need to back out the effects of compiling any
-- half-done cycles, both so as to clean up the top level envs
-- and to avoid telling the interactive linker to link them.
- do debugTraceMsg dflags 2 "Upsweep partially successful."
+ do debugTraceMsg dflags 2 (text "Upsweep partially successful.")
let modsDone_names
= map ms_mod modsDone
@@ -730,11 +718,10 @@ type TypecheckedSource = LHsBinds Id
-- for a module. 'checkModule' loads all the dependencies of the specified
-- module in the Session, and then attempts to typecheck the module. If
-- successful, it returns the abstract syntax for the module.
-checkModule :: Session -> Module -> (Messages -> IO ())
- -> IO (Maybe CheckedModule)
-checkModule session@(Session ref) mod msg_act = do
+checkModule :: Session -> Module -> IO (Maybe CheckedModule)
+checkModule session@(Session ref) mod = do
-- load up the dependencies first
- r <- loadMsgs session (LoadDependenciesOf mod) msg_act
+ r <- load session (LoadDependenciesOf mod)
if (failed r) then return Nothing else do
-- now parse & typecheck the module
@@ -749,15 +736,15 @@ checkModule session@(Session ref) mod msg_act = do
-- ml_hspp_file field, say
let dflags0 = hsc_dflags hsc_env
hspp_buf = expectJust "GHC.checkModule" (ms_hspp_buf ms)
- opts = getOptionsFromStringBuffer hspp_buf
+ filename = fromJust (ml_hs_file (ms_location ms))
+ opts = getOptionsFromStringBuffer hspp_buf filename
(dflags1,leftovers) <- parseDynamicFlags dflags0 (map snd opts)
if (not (null leftovers))
- then do let filename = fromJust (ml_hs_file (ms_location ms))
- msg_act (optionsErrorMsgs leftovers opts filename)
+ then do printErrorsAndWarnings dflags1 (optionsErrorMsgs leftovers opts filename)
return Nothing
else do
- r <- hscFileCheck hsc_env{hsc_dflags=dflags1} msg_act ms
+ r <- hscFileCheck hsc_env{hsc_dflags=dflags1} ms
case r of
HscFail ->
return Nothing
@@ -981,31 +968,30 @@ upsweep
-> HomePackageTable -- HPT from last time round (pruned)
-> ([Module],[Module]) -- stable modules (see checkStability)
-> IO () -- How to clean up unwanted tmp files
- -> (Messages -> IO ()) -- Compiler error message callback
-> [SCC ModSummary] -- Mods to do (the worklist)
-> IO (SuccessFlag,
HscEnv, -- With an updated HPT
[ModSummary]) -- Mods which succeeded
-upsweep hsc_env old_hpt stable_mods cleanup msg_act mods
- = upsweep' hsc_env old_hpt stable_mods cleanup msg_act mods 1 (length mods)
+upsweep hsc_env old_hpt stable_mods cleanup mods
+ = upsweep' hsc_env old_hpt stable_mods cleanup mods 1 (length mods)
-upsweep' hsc_env old_hpt stable_mods cleanup msg_act
+upsweep' hsc_env old_hpt stable_mods cleanup
[] _ _
= return (Succeeded, hsc_env, [])
-upsweep' hsc_env old_hpt stable_mods cleanup msg_act
+upsweep' hsc_env old_hpt stable_mods cleanup
(CyclicSCC ms:_) _ _
- = do putMsg (showSDoc (cyclicModuleErr ms))
+ = do fatalErrorMsg (hsc_dflags hsc_env) (cyclicModuleErr ms)
return (Failed, hsc_env, [])
-upsweep' hsc_env old_hpt stable_mods cleanup msg_act
+upsweep' hsc_env old_hpt stable_mods cleanup
(AcyclicSCC mod:mods) mod_index nmods
= do -- putStrLn ("UPSWEEP_MOD: hpt = " ++
-- show (map (moduleUserString.moduleName.mi_module.hm_iface)
-- (moduleEnvElts (hsc_HPT hsc_env)))
- mb_mod_info <- upsweep_mod hsc_env old_hpt stable_mods msg_act mod
+ mb_mod_info <- upsweep_mod hsc_env old_hpt stable_mods mod
mod_index nmods
cleanup -- Remove unwanted tmp files between compilations
@@ -1031,7 +1017,7 @@ upsweep' hsc_env old_hpt stable_mods cleanup msg_act
; (restOK, hsc_env2, modOKs)
<- upsweep' hsc_env1 old_hpt1 stable_mods cleanup
- msg_act mods (mod_index+1) nmods
+ mods (mod_index+1) nmods
; return (restOK, hsc_env2, mod:modOKs)
}
@@ -1041,13 +1027,12 @@ upsweep' hsc_env old_hpt stable_mods cleanup msg_act
upsweep_mod :: HscEnv
-> HomePackageTable
-> ([Module],[Module])
- -> (Messages -> IO ())
-> ModSummary
-> Int -- index of module
-> Int -- total number of modules
-> IO (Maybe HomeModInfo) -- Nothing => Failed
-upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) msg_act summary mod_index nmods
+upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) summary mod_index nmods
= do
let
this_mod = ms_mod summary
@@ -1057,7 +1042,7 @@ upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) msg_act summary mod_index n
compile_it :: Maybe Linkable -> IO (Maybe HomeModInfo)
compile_it = upsweep_compile hsc_env old_hpt this_mod
- msg_act summary mod_index nmods
+ summary mod_index nmods
case ghcMode (hsc_dflags hsc_env) of
BatchCompile ->
@@ -1110,7 +1095,7 @@ upsweep_mod hsc_env old_hpt (stable_obj, stable_bco) msg_act summary mod_index n
old_hmi = lookupModuleEnv old_hpt this_mod
-- Run hsc to compile a module
-upsweep_compile hsc_env old_hpt this_mod msg_act summary
+upsweep_compile hsc_env old_hpt this_mod summary
mod_index nmods
mb_old_linkable = do
let
@@ -1132,7 +1117,7 @@ upsweep_compile hsc_env old_hpt this_mod msg_act summary
where
iface = hm_iface hm_info
- compresult <- compile hsc_env msg_act summary mb_old_linkable mb_old_iface
+ compresult <- compile hsc_env summary mb_old_linkable mb_old_iface
mod_index nmods
case compresult of
@@ -1259,18 +1244,18 @@ downsweep :: HscEnv
-> Bool -- True <=> allow multiple targets to have
-- the same module name; this is
-- very useful for ghc -M
- -> IO (Either Messages [ModSummary])
+ -> IO (Maybe [ModSummary])
-- The elts of [ModSummary] all have distinct
-- (Modules, IsBoot) identifiers, unless the Bool is true
-- in which case there can be repeats
downsweep hsc_env old_summaries excl_mods allow_dup_roots
= -- catch error messages and return them
- handleDyn (\err_msg -> return (Left (emptyBag, unitBag err_msg))) $ do
+ handleDyn (\err_msg -> printBagOfErrors (hsc_dflags hsc_env) (unitBag err_msg) >> return Nothing) $ do
rootSummaries <- mapM getRootSummary roots
let root_map = mkRootMap rootSummaries
checkDuplicates root_map
summs <- loop (concatMap msDeps rootSummaries) root_map
- return (Right summs)
+ return (Just summs)
where
roots = hsc_targets hsc_env
@@ -1555,7 +1540,7 @@ preprocessFile dflags src_fn mb_phase (Just (buf, time))
= do
-- case we bypass the preprocessing stage?
let
- local_opts = getOptionsFromStringBuffer buf
+ local_opts = getOptionsFromStringBuffer buf src_fn
--
(dflags', errs) <- parseDynamicFlags dflags (map snd local_opts)
diff --git a/ghc/compiler/main/HscMain.lhs b/ghc/compiler/main/HscMain.lhs
index 187f6442f3..2586340eda 100644
--- a/ghc/compiler/main/HscMain.lhs
+++ b/ghc/compiler/main/HscMain.lhs
@@ -157,7 +157,6 @@ type MessageAction = Messages -> IO ()
hscMain
:: HscEnv
- -> MessageAction -- What to do with errors/warnings
-> ModSummary
-> Bool -- True <=> source unchanged
-> Bool -- True <=> have an object file (for msgs only)
@@ -165,7 +164,7 @@ hscMain
-> Maybe (Int, Int) -- Just (i,n) <=> module i of n (for msgs)
-> IO HscResult
-hscMain hsc_env msg_act mod_summary
+hscMain hsc_env mod_summary
source_unchanged have_object maybe_old_iface
mb_mod_index
= do {
@@ -178,14 +177,14 @@ hscMain hsc_env msg_act mod_summary
what_next | recomp_reqd || no_old_iface = hscRecomp
| otherwise = hscNoRecomp
- ; what_next hsc_env msg_act mod_summary have_object
+ ; what_next hsc_env mod_summary have_object
maybe_checked_iface
mb_mod_index
}
------------------------------
-hscNoRecomp hsc_env msg_act mod_summary
+hscNoRecomp hsc_env mod_summary
have_object (Just old_iface)
mb_mod_index
| isOneShot (ghcMode (hsc_dflags hsc_env))
@@ -210,36 +209,38 @@ hscNoRecomp hsc_env msg_act mod_summary
; return (HscNoRecomp new_details old_iface)
}
-hscNoRecomp hsc_env msg_act mod_summary
+hscNoRecomp hsc_env mod_summary
have_object Nothing
mb_mod_index
= panic "hscNoRecomp" -- hscNoRecomp definitely expects to
-- have the old interface available
------------------------------
-hscRecomp hsc_env msg_act mod_summary
+hscRecomp hsc_env mod_summary
have_object maybe_old_iface
mb_mod_index
= case ms_hsc_src mod_summary of
- HsSrcFile -> do
- front_res <- hscFileFrontEnd hsc_env msg_act mod_summary mb_mod_index
- hscBackEnd hsc_env mod_summary maybe_old_iface front_res
+ HsSrcFile -> do
+ front_res <- hscFileFrontEnd hsc_env mod_summary mb_mod_index
+ case ghcMode (hsc_dflags hsc_env) of
+ JustTypecheck -> hscBootBackEnd hsc_env mod_summary maybe_old_iface front_res
+ _ -> hscBackEnd hsc_env mod_summary maybe_old_iface front_res
HsBootFile -> do
- front_res <- hscFileFrontEnd hsc_env msg_act mod_summary mb_mod_index
+ front_res <- hscFileFrontEnd hsc_env mod_summary mb_mod_index
hscBootBackEnd hsc_env mod_summary maybe_old_iface front_res
ExtCoreFile -> do
- front_res <- hscCoreFrontEnd hsc_env msg_act mod_summary
+ front_res <- hscCoreFrontEnd hsc_env mod_summary
hscBackEnd hsc_env mod_summary maybe_old_iface front_res
-hscCoreFrontEnd hsc_env msg_act mod_summary = do {
+hscCoreFrontEnd hsc_env mod_summary = do {
-------------------
-- PARSE
-------------------
; inp <- readFile (expectJust "hscCoreFrontEnd" (ms_hspp_file mod_summary))
; case parseCore inp 1 of
- FailP s -> putMsg s{-ToDo: wrong-} >> return Nothing
+ FailP s -> errorMsg (hsc_dflags hsc_env) (text s{-ToDo: wrong-}) >> return Nothing
OkP rdr_module -> do {
-------------------
@@ -247,20 +248,20 @@ hscCoreFrontEnd hsc_env msg_act mod_summary = do {
-------------------
; (tc_msgs, maybe_tc_result) <- {-# SCC "TypeCheck" #-}
tcRnExtCore hsc_env rdr_module
- ; msg_act tc_msgs
+ ; printErrorsAndWarnings (hsc_dflags hsc_env) tc_msgs
; case maybe_tc_result of
Nothing -> return Nothing
Just mod_guts -> return (Just mod_guts) -- No desugaring to do!
}}
-hscFileFrontEnd hsc_env msg_act mod_summary mb_mod_index = do {
+hscFileFrontEnd hsc_env mod_summary mb_mod_index = do {
-------------------
-- DISPLAY PROGRESS MESSAGE
-------------------
- let one_shot = isOneShot (ghcMode (hsc_dflags hsc_env))
- ; let dflags = hsc_dflags hsc_env
- ; let toInterp = hscTarget dflags == HscInterpreted
+ ; let dflags = hsc_dflags hsc_env
+ one_shot = isOneShot (ghcMode dflags)
+ toInterp = hscTarget dflags == HscInterpreted
; when (not one_shot) $
compilationProgressMsg dflags $
(showModuleIndex mb_mod_index ++
@@ -272,10 +273,10 @@ hscFileFrontEnd hsc_env msg_act mod_summary mb_mod_index = do {
; let hspp_file = expectJust "hscFileFrontEnd" (ms_hspp_file mod_summary)
hspp_buf = ms_hspp_buf mod_summary
- ; maybe_parsed <- myParseModule (hsc_dflags hsc_env) hspp_file hspp_buf
+ ; maybe_parsed <- myParseModule dflags hspp_file hspp_buf
; case maybe_parsed of {
- Left err -> do { msg_act (unitBag err, emptyBag)
+ Left err -> do { printBagOfErrors dflags (unitBag err)
; return Nothing } ;
Right rdr_module -> do {
@@ -286,7 +287,7 @@ hscFileFrontEnd hsc_env msg_act mod_summary mb_mod_index = do {
<- {-# SCC "Typecheck-Rename" #-}
tcRnModule hsc_env (ms_hsc_src mod_summary) False rdr_module
- ; msg_act tc_msgs
+ ; printErrorsAndWarnings dflags tc_msgs
; case maybe_tc_result of {
Nothing -> return Nothing ;
Just tc_result -> do {
@@ -296,24 +297,25 @@ hscFileFrontEnd hsc_env msg_act mod_summary mb_mod_index = do {
-------------------
; (warns, maybe_ds_result) <- {-# SCC "DeSugar" #-}
deSugar hsc_env tc_result
- ; msg_act (warns, emptyBag)
+ ; printBagOfWarnings dflags warns
; return maybe_ds_result
}}}}}
------------------------------
-hscFileCheck :: HscEnv -> MessageAction -> ModSummary -> IO HscResult
-hscFileCheck hsc_env msg_act mod_summary = do {
+hscFileCheck :: HscEnv -> ModSummary -> IO HscResult
+hscFileCheck hsc_env mod_summary = do {
-------------------
-- PARSE
-------------------
- ; let hspp_file = expectJust "hscFileFrontEnd" (ms_hspp_file mod_summary)
+ ; let dflags = hsc_dflags hsc_env
+ hspp_file = expectJust "hscFileFrontEnd" (ms_hspp_file mod_summary)
hspp_buf = ms_hspp_buf mod_summary
- ; maybe_parsed <- myParseModule (hsc_dflags hsc_env) hspp_file hspp_buf
+ ; maybe_parsed <- myParseModule dflags hspp_file hspp_buf
; case maybe_parsed of {
- Left err -> do { msg_act (unitBag err, emptyBag)
+ Left err -> do { printBagOfErrors dflags (unitBag err)
; return HscFail } ;
Right rdr_module -> do {
@@ -326,7 +328,7 @@ hscFileCheck hsc_env msg_act mod_summary = do {
True{-save renamed syntax-}
rdr_module
- ; msg_act tc_msgs
+ ; printErrorsAndWarnings dflags tc_msgs
; case maybe_tc_result of {
Nothing -> return (HscChecked rdr_module Nothing Nothing);
Just tc_result -> do
@@ -655,7 +657,7 @@ hscTcExpr hsc_env expr
Nothing -> return Nothing ; -- Parse error
Just (Just (L _ (ExprStmt expr _ _)))
-> tcRnExpr hsc_env icontext expr ;
- Just other -> do { errorMsg ("not an expression: `" ++ expr ++ "'") ;
+ Just other -> do { errorMsg (hsc_dflags hsc_env) (text "not an expression:" <+> quotes (text expr)) ;
return Nothing } ;
} }
@@ -669,7 +671,7 @@ hscKcType hsc_env str
; let icontext = hsc_IC hsc_env
; case maybe_type of {
Just ty -> tcRnType hsc_env icontext ty ;
- Just other -> do { errorMsg ("not an type: `" ++ str ++ "'") ;
+ Just other -> do { errorMsg (hsc_dflags hsc_env) (text "not an type:" <+> quotes (text str)) ;
return Nothing } ;
Nothing -> return Nothing } }
#endif
diff --git a/ghc/compiler/main/Main.hs b/ghc/compiler/main/Main.hs
index f38bcc48de..a9c4122fe4 100644
--- a/ghc/compiler/main/Main.hs
+++ b/ghc/compiler/main/Main.hs
@@ -32,6 +32,7 @@ import Packages ( dumpPackages, initPackages )
import DriverPhases ( Phase(..), isSourceFilename, anyHsc,
startPhase, isHaskellSrcFilename )
import StaticFlags ( staticFlags, v_Ld_inputs )
+import DynFlags ( defaultDynFlags )
import BasicTypes ( failed )
import Util
import Panic
@@ -58,7 +59,7 @@ import Maybe
-- GHC's command-line interface
main =
- GHC.defaultErrorHandler $ do
+ GHC.defaultErrorHandler defaultDynFlags $ do
argv0 <- getArgs
argv1 <- GHC.init argv0
diff --git a/ghc/compiler/main/Packages.lhs b/ghc/compiler/main/Packages.lhs
index 85cf4ac55b..5f32acca34 100644
--- a/ghc/compiler/main/Packages.lhs
+++ b/ghc/compiler/main/Packages.lhs
@@ -13,7 +13,8 @@ module Packages (
-- * Reading the package config, and processing cmdline args
PackageIdH(..), isHomePackage,
- PackageState(..),
+ PackageState(..),
+ mkPackageState,
initPackages,
getPackageDetails,
checkForPackageConflicts,
@@ -238,7 +239,7 @@ readPackageConfigs dflags = do
readPackageConfig
:: DynFlags -> PackageConfigMap -> FilePath -> IO PackageConfigMap
readPackageConfig dflags pkg_map conf_file = do
- debugTraceMsg dflags 2 ("Using package config file: " ++ conf_file)
+ debugTraceMsg dflags 2 (text "Using package config file:" <+> text conf_file)
proto_pkg_configs <- loadPackageConfig conf_file
top_dir <- getTopDir
let pkg_configs1 = mungePackagePaths top_dir proto_pkg_configs
@@ -342,9 +343,9 @@ mkPackageState dflags orig_pkg_db = do
| not (exposed p) = return p
| (p' : _) <- later_versions = do
debugTraceMsg dflags 2 $
- ("hiding package " ++ showPackageId (package p) ++
- " to avoid conflict with later version " ++
- showPackageId (package p'))
+ (ptext SLIT("hiding package") <+> text (showPackageId (package p)) <+>
+ ptext SLIT("to avoid conflict with later version") <+>
+ text (showPackageId (package p')))
return (p {exposed=False})
| otherwise = return p
where myname = pkgName (package p)
@@ -370,7 +371,7 @@ mkPackageState dflags orig_pkg_db = do
elimDanglingDeps (map fst qs)
reportElim (p, deps) =
- debugTraceMsg dflags 2 $ showSDoc $
+ debugTraceMsg dflags 2 $
(ptext SLIT("package") <+> pprPkg p <+>
ptext SLIT("will be ignored due to missing dependencies:") $$
nest 2 (hsep (map (text.showPackageId) deps)))
@@ -710,6 +711,6 @@ dumpPackages :: DynFlags -> IO ()
-- Show package info on console, if verbosity is >= 3
dumpPackages dflags
= do let pkg_map = pkgIdMap (pkgState dflags)
- putMsg $ showSDoc $
+ putMsg dflags $
vcat (map (text.showInstalledPackageInfo) (eltsUFM pkg_map))
\end{code}
diff --git a/ghc/compiler/main/SysTools.lhs b/ghc/compiler/main/SysTools.lhs
index c08ebe4129..d6ed73743e 100644
--- a/ghc/compiler/main/SysTools.lhs
+++ b/ghc/compiler/main/SysTools.lhs
@@ -47,7 +47,7 @@ module SysTools (
import DriverPhases ( isHaskellUserSrcFilename )
import Config
import Outputable
-import ErrUtils ( putMsg, debugTraceMsg )
+import ErrUtils ( putMsg, debugTraceMsg, showPass, Severity(..), Messages )
import Panic ( GhcException(..) )
import Util ( Suffix, global, notNull, consIORef, joinFileName,
normalisePath, pgmPath, platformPath, joinFileExt )
@@ -91,7 +91,13 @@ import Compat.RawSystem ( rawSystem )
import GHC.IOBase ( IOErrorType(..) )
import System.IO.Error ( ioeGetErrorType )
#else
-import System.Cmd ( rawSystem )
+import System.Process ( runInteractiveProcess, getProcessExitCode )
+import System.IO ( hSetBuffering, hGetLine, BufferMode(..) )
+import Control.Concurrent( forkIO, newChan, readChan, writeChan )
+import Text.Regex
+import Data.Char ( isSpace )
+import FastString ( mkFastString )
+import SrcLoc ( SrcLoc, mkSrcLoc, noSrcSpan, mkSrcSpan )
#endif
\end{code}
@@ -492,7 +498,7 @@ touch dflags purpose arg = do
copy :: DynFlags -> String -> String -> String -> IO ()
copy dflags purpose from to = do
- debugTraceMsg dflags 2 ("*** " ++ purpose)
+ showPass dflags purpose
h <- openFile to WriteMode
ls <- readFile from -- inefficient, but it'll do for now.
@@ -573,14 +579,14 @@ removeTmpFiles dflags fs
warnNon act
| null non_deletees = act
| otherwise = do
- putMsg ("WARNING - NOT deleting source files: " ++ unwords non_deletees)
+ putMsg dflags (text "WARNING - NOT deleting source files:" <+> hsep (map text non_deletees))
act
(non_deletees, deletees) = partition isHaskellUserSrcFilename fs
rm f = removeFile f `IO.catch`
(\_ignored ->
- debugTraceMsg dflags 2 ("Warning: deleting non-existent " ++ f)
+ debugTraceMsg dflags 2 (ptext SLIT("Warning: deleting non-existent") <+> text f)
)
@@ -600,7 +606,7 @@ runSomething dflags phase_name pgm args = do
traceCmd dflags phase_name (unwords (pgm:real_args)) $ do
(exit_code, doesn'tExist) <-
IO.catch (do
- rc <- rawSystem pgm real_args
+ rc <- builderMainLoop dflags pgm real_args
case rc of
ExitSuccess{} -> return (rc, False)
ExitFailure n
@@ -629,6 +635,97 @@ runSomething dflags phase_name pgm args = do
(_, ExitSuccess) -> return ()
_ -> throwDyn (PhaseFailed phase_name exit_code)
+
+
+#if __GLASGOW_HASKELL__ < 603
+builderMainLoop dflags pgm real_args = do
+ rawSystem pgm real_args
+#else
+builderMainLoop dflags pgm real_args = do
+ chan <- newChan
+ (hStdIn, hStdOut, hStdErr, hProcess) <- runInteractiveProcess pgm real_args Nothing Nothing
+
+ -- and run a loop piping the output from the compiler to the log_action in DynFlags
+ hSetBuffering hStdOut LineBuffering
+ hSetBuffering hStdErr LineBuffering
+ forkIO (readerProc chan hStdOut)
+ forkIO (readerProc chan hStdErr)
+ rc <- loop chan hProcess 2 1 ExitSuccess
+ hClose hStdIn
+ hClose hStdOut
+ hClose hStdErr
+ return rc
+ where
+ -- status starts at zero, and increments each time either
+ -- a reader process gets EOF, or the build proc exits. We wait
+ -- for all of these to happen (status==3).
+ -- ToDo: we should really have a contingency plan in case any of
+ -- the threads dies, such as a timeout.
+ loop chan hProcess 0 0 exitcode = return exitcode
+ loop chan hProcess t p exitcode = do
+ mb_code <- if p > 0
+ then getProcessExitCode hProcess
+ else return Nothing
+ case mb_code of
+ Just code -> loop chan hProcess t (p-1) code
+ Nothing
+ | t > 0 -> do
+ msg <- readChan chan
+ case msg of
+ BuildMsg msg -> do
+ log_action dflags SevInfo noSrcSpan defaultUserStyle msg
+ loop chan hProcess t p exitcode
+ BuildError loc msg -> do
+ log_action dflags SevError (mkSrcSpan loc loc) defaultUserStyle msg
+ loop chan hProcess t p exitcode
+ EOF ->
+ loop chan hProcess (t-1) p exitcode
+ | otherwise -> loop chan hProcess t p exitcode
+
+readerProc chan hdl = loop Nothing `catch` \e -> writeChan chan EOF
+ -- ToDo: check errors more carefully
+ where
+ loop in_err = do
+ l <- hGetLine hdl `catch` \e -> do
+ case in_err of
+ Just err -> writeChan chan err
+ Nothing -> return ()
+ ioError e
+ case in_err of
+ Just err@(BuildError srcLoc msg)
+ | leading_whitespace l -> do
+ loop (Just (BuildError srcLoc (msg $$ text l)))
+ | otherwise -> do
+ writeChan chan err
+ checkError l
+ Nothing -> do
+ checkError l
+
+ checkError l
+ = case matchRegex errRegex l of
+ Nothing -> do
+ writeChan chan (BuildMsg (text l))
+ loop Nothing
+ Just (file':lineno':colno':msg:_) -> do
+ let file = mkFastString file'
+ lineno = read lineno'::Int
+ colno = case colno' of
+ "" -> 0
+ _ -> read (init colno') :: Int
+ srcLoc = mkSrcLoc file lineno colno
+ loop (Just (BuildError srcLoc (text msg)))
+
+ leading_whitespace [] = False
+ leading_whitespace (x:_) = isSpace x
+
+errRegex = mkRegex "^([^:]*):([0-9]+):([0-9]+:)?(.*)"
+
+data BuildMessage
+ = BuildMsg !SDoc
+ | BuildError !SrcLoc !SDoc
+ | EOF
+#endif
+
showOpt (FileOption pre f) = pre ++ platformPath f
showOpt (Option "") = ""
showOpt (Option s) = s
@@ -638,8 +735,8 @@ traceCmd :: DynFlags -> String -> String -> IO () -> IO ()
-- b) don't do it at all if dry-run is set
traceCmd dflags phase_name cmd_line action
= do { let verb = verbosity dflags
- ; debugTraceMsg dflags 2 ("*** " ++ phase_name)
- ; debugTraceMsg dflags 3 cmd_line
+ ; showPass dflags phase_name
+ ; debugTraceMsg dflags 3 (text cmd_line)
; hFlush stderr
-- Test for -n flag
@@ -649,8 +746,8 @@ traceCmd dflags phase_name cmd_line action
; action `IO.catch` handle_exn verb
}}
where
- handle_exn verb exn = do { debugTraceMsg dflags 2 "\n"
- ; debugTraceMsg dflags 2 ("Failed: " ++ cmd_line ++ (show exn))
+ handle_exn verb exn = do { debugTraceMsg dflags 2 (char '\n')
+ ; debugTraceMsg dflags 2 (ptext SLIT("Failed:") <+> text cmd_line <+> text (show exn))
; throwDyn (PhaseFailed phase_name (ExitFailure 1)) }
\end{code}
diff --git a/ghc/compiler/typecheck/TcRnMonad.lhs b/ghc/compiler/typecheck/TcRnMonad.lhs
index d8032b2f19..d1d8528795 100644
--- a/ghc/compiler/typecheck/TcRnMonad.lhs
+++ b/ghc/compiler/typecheck/TcRnMonad.lhs
@@ -28,7 +28,7 @@ import InstEnv ( emptyInstEnv )
import VarSet ( emptyVarSet )
import VarEnv ( TidyEnv, emptyTidyEnv, emptyVarEnv )
import ErrUtils ( Message, Messages, emptyMessages, errorsFound,
- mkWarnMsg, printErrorsAndWarnings, pprBagOfErrors,
+ mkWarnMsg, printErrorsAndWarnings,
mkLocMessage, mkLongErrMsg )
import Packages ( mkHomeModules )
import SrcLoc ( mkGeneralSrcSpan, isGoodSrcSpan, SrcSpan, Located(..) )
@@ -159,7 +159,7 @@ initTcPrintErrors -- Used from the interactive loop only
-> IO (Maybe r)
initTcPrintErrors env mod todo = do
(msgs, res) <- initTc env HsSrcFile mod todo
- printErrorsAndWarnings msgs
+ printErrorsAndWarnings (hsc_dflags env) msgs
return res
-- mkImpTypeEnv makes the imported symbol table
@@ -452,8 +452,10 @@ addLongErrAt loc msg extra
rdr_env <- getGlobalRdrEnv ;
let { err = mkLongErrMsg loc (unQualInScope rdr_env) msg extra } ;
(warns, errs) <- readMutVar errs_var ;
- traceTc (ptext SLIT("Adding error:") <+> \ _ -> pprBagOfErrors (unitBag err)) ;
- -- Ugh! traceTc is too specific; unitBag is horrible
+
+ let style = mkErrStyle (unQualInScope rdr_env)
+ doc = mkLocMessage loc (msg $$ extra)
+ in traceTc (ptext SLIT("Adding error:") <+> doc) ;
writeMutVar errs_var (warns, errs `snocBag` err) }
addErrs :: [(SrcSpan,Message)] -> TcRn ()
diff --git a/ghc/compiler/utils/Outputable.lhs b/ghc/compiler/utils/Outputable.lhs
index a88451d273..cf99e12bcf 100644
--- a/ghc/compiler/utils/Outputable.lhs
+++ b/ghc/compiler/utils/Outputable.lhs
@@ -17,7 +17,7 @@ module Outputable (
getPprStyle, withPprStyle, withPprStyleDoc, pprDeeper, pprSetDepth,
codeStyle, userStyle, debugStyle, dumpStyle, asmStyle,
ifPprDebug, unqualStyle,
- mkErrStyle, defaultErrStyle,
+ mkErrStyle, defaultErrStyle, defaultDumpStyle, defaultUserStyle,
SDoc, -- Abstract
docToSDoc,