summaryrefslogtreecommitdiff
path: root/compiler/main
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/main')
-rw-r--r--compiler/main/Annotations.hs15
-rw-r--r--compiler/main/CodeOutput.lhs18
-rw-r--r--compiler/main/DriverPipeline.hs234
-rw-r--r--compiler/main/DynFlags.hs178
-rw-r--r--compiler/main/ErrUtils.lhs1
-rw-r--r--compiler/main/ErrUtils.lhs-boot1
-rw-r--r--compiler/main/GHC.hs14
-rw-r--r--compiler/main/GhcMake.hs3
-rw-r--r--compiler/main/HeaderInfo.hs61
-rw-r--r--compiler/main/HscMain.hs49
-rw-r--r--compiler/main/HscTypes.lhs222
-rw-r--r--compiler/main/InteractiveEval.hs4
-rw-r--r--compiler/main/Packages.lhs17
-rw-r--r--compiler/main/PprTyThing.hs33
-rw-r--r--compiler/main/StaticFlags.hs97
-rw-r--r--compiler/main/SysTools.lhs242
-rw-r--r--compiler/main/TidyPgm.lhs32
17 files changed, 814 insertions, 407 deletions
diff --git a/compiler/main/Annotations.hs b/compiler/main/Annotations.hs
index 277c059b11..7de1a9914b 100644
--- a/compiler/main/Annotations.hs
+++ b/compiler/main/Annotations.hs
@@ -16,6 +16,7 @@ module Annotations (
deserializeAnns
) where
+import Binary
import Module ( Module )
import Name
import Outputable
@@ -23,6 +24,7 @@ import Serialized
import UniqFM
import Unique
+import Control.Monad
import Data.Maybe
import Data.Typeable
import Data.Word ( Word8 )
@@ -64,6 +66,19 @@ instance Outputable name => Outputable (AnnTarget name) where
ppr (NamedTarget nm) = text "Named target" <+> ppr nm
ppr (ModuleTarget mod) = text "Module target" <+> ppr mod
+instance Binary name => Binary (AnnTarget name) where
+ put_ bh (NamedTarget a) = do
+ putByte bh 0
+ put_ bh a
+ put_ bh (ModuleTarget a) = do
+ putByte bh 1
+ put_ bh a
+ get bh = do
+ h <- getByte bh
+ case h of
+ 0 -> liftM NamedTarget $ get bh
+ _ -> liftM ModuleTarget $ get bh
+
instance Outputable Annotation where
ppr ann = ppr (ann_target ann)
diff --git a/compiler/main/CodeOutput.lhs b/compiler/main/CodeOutput.lhs
index d6c096a595..b8b187241b 100644
--- a/compiler/main/CodeOutput.lhs
+++ b/compiler/main/CodeOutput.lhs
@@ -45,6 +45,7 @@ import System.IO
\begin{code}
codeOutput :: DynFlags
-> Module
+ -> FilePath
-> ModLocation
-> ForeignStubs
-> [PackageId]
@@ -52,7 +53,7 @@ codeOutput :: DynFlags
-> IO (FilePath,
(Bool{-stub_h_exists-}, Maybe FilePath{-stub_c_exists-}))
-codeOutput dflags this_mod location foreign_stubs pkg_deps cmm_stream
+codeOutput dflags this_mod filenm location foreign_stubs pkg_deps cmm_stream
=
do {
-- Lint each CmmGroup as it goes past
@@ -72,10 +73,9 @@ codeOutput dflags this_mod location foreign_stubs pkg_deps cmm_stream
}
; showPass dflags "CodeOutput"
- ; let filenm = hscOutName dflags
; stubs_exist <- outputForeignStubs dflags this_mod location foreign_stubs
; case hscTarget dflags of {
- HscAsm -> outputAsm dflags filenm linted_cmm_stream;
+ HscAsm -> outputAsm dflags this_mod filenm linted_cmm_stream;
HscC -> outputC dflags filenm linted_cmm_stream pkg_deps;
HscLlvm -> outputLlvm dflags filenm linted_cmm_stream;
HscInterpreted -> panic "codeOutput: HscInterpreted";
@@ -140,8 +140,8 @@ outputC dflags filenm cmm_stream packages
%************************************************************************
\begin{code}
-outputAsm :: DynFlags -> FilePath -> Stream IO RawCmmGroup () -> IO ()
-outputAsm dflags filenm cmm_stream
+outputAsm :: DynFlags -> Module -> FilePath -> Stream IO RawCmmGroup () -> IO ()
+outputAsm dflags this_mod filenm cmm_stream
| cGhcWithNativeCodeGen == "YES"
= do ncg_uniqs <- mkSplitUniqSupply 'n'
@@ -149,7 +149,7 @@ outputAsm dflags filenm cmm_stream
_ <- {-# SCC "OutputAsm" #-} doOutput filenm $
\h -> {-# SCC "NativeCodeGen" #-}
- nativeCodeGen dflags h ncg_uniqs cmm_stream
+ nativeCodeGen dflags this_mod h ncg_uniqs cmm_stream
return ()
| otherwise
@@ -168,13 +168,9 @@ outputLlvm :: DynFlags -> FilePath -> Stream IO RawCmmGroup () -> IO ()
outputLlvm dflags filenm cmm_stream
= do ncg_uniqs <- mkSplitUniqSupply 'n'
- -- ToDo: make the LLVM backend consume the C-- incrementally,
- -- by pushing the cmm_stream inside (c.f. nativeCodeGen)
- rawcmms <- Stream.collect cmm_stream
-
{-# SCC "llvm_output" #-} doOutput filenm $
\f -> {-# SCC "llvm_CodeGen" #-}
- llvmCodeGen dflags f ncg_uniqs rawcmms
+ llvmCodeGen dflags f ncg_uniqs cmm_stream
\end{code}
diff --git a/compiler/main/DriverPipeline.hs b/compiler/main/DriverPipeline.hs
index bdc2e8e812..c005a46873 100644
--- a/compiler/main/DriverPipeline.hs
+++ b/compiler/main/DriverPipeline.hs
@@ -78,7 +78,7 @@ preprocess :: HscEnv
-> IO (DynFlags, FilePath)
preprocess hsc_env (filename, mb_phase) =
ASSERT2(isJust mb_phase || isHaskellSrcFilename filename, text filename)
- runPipeline anyHsc hsc_env (filename, mb_phase)
+ runPipeline anyHsc hsc_env (filename, fmap RealPhase mb_phase)
Nothing Temporary Nothing{-no ModLocation-} Nothing{-no stub-}
-- ---------------------------------------------------------------------------
@@ -148,9 +148,7 @@ compileOne' m_tc_result mHscMessage
output_fn <- getOutputFilename next_phase
Temporary basename dflags next_phase (Just location)
- let dflags' = dflags { hscOutName = output_fn,
- extCoreName = basename ++ ".hcr" }
- let hsc_env' = hsc_env { hsc_dflags = dflags' }
+ let extCore_filename = basename ++ ".hcr"
-- -fforce-recomp should also work with --make
let force_recomp = gopt Opt_ForceRecomp dflags
@@ -166,12 +164,12 @@ compileOne' m_tc_result mHscMessage
e <- genericHscCompileGetFrontendResult
always_do_basic_recompilation_check
m_tc_result mHscMessage
- hsc_env' summary source_modified mb_old_iface (mod_index, nmods)
+ hsc_env summary source_modified mb_old_iface (mod_index, nmods)
case e of
Left iface ->
do details <- genModDetails hsc_env iface
- MASSERT (isJust maybe_old_linkable)
+ MASSERT(isJust maybe_old_linkable)
return (HomeModInfo{ hm_details = details,
hm_iface = iface,
hm_linkable = maybe_old_linkable })
@@ -182,19 +180,19 @@ compileOne' m_tc_result mHscMessage
HscInterpreted ->
case ms_hsc_src summary of
HsBootFile ->
- do (iface, _changed, details) <- hscSimpleIface hsc_env' tc_result mb_old_hash
+ do (iface, _changed, details) <- hscSimpleIface hsc_env tc_result mb_old_hash
return (HomeModInfo{ hm_details = details,
hm_iface = iface,
hm_linkable = maybe_old_linkable })
- _ -> do guts0 <- hscDesugar hsc_env' summary tc_result
- guts <- hscSimplify hsc_env' guts0
- (iface, _changed, details, cgguts) <- hscNormalIface hsc_env' guts mb_old_hash
- (hasStub, comp_bc, modBreaks) <- hscInteractive hsc_env' cgguts summary
+ _ -> do guts0 <- hscDesugar hsc_env summary tc_result
+ guts <- hscSimplify hsc_env guts0
+ (iface, _changed, details, cgguts) <- hscNormalIface hsc_env extCore_filename guts mb_old_hash
+ (hasStub, comp_bc, modBreaks) <- hscInteractive hsc_env cgguts summary
stub_o <- case hasStub of
Nothing -> return []
Just stub_c -> do
- stub_o <- compileStub hsc_env' stub_c
+ stub_o <- compileStub hsc_env stub_c
return [DotO stub_o]
let hs_unlinked = [BCOs comp_bc modBreaks]
@@ -212,7 +210,7 @@ compileOne' m_tc_result mHscMessage
hm_iface = iface,
hm_linkable = Just linkable })
HscNothing ->
- do (iface, _changed, details) <- hscSimpleIface hsc_env' tc_result mb_old_hash
+ do (iface, _changed, details) <- hscSimpleIface hsc_env tc_result mb_old_hash
let linkable = if isHsBoot src_flavour
then maybe_old_linkable
else Just (LM (ms_hs_date summary) this_mod [])
@@ -223,30 +221,27 @@ compileOne' m_tc_result mHscMessage
_ ->
case ms_hsc_src summary of
HsBootFile ->
- do (iface, changed, details) <- hscSimpleIface hsc_env' tc_result mb_old_hash
- hscWriteIface dflags' iface changed summary
- touchObjectFile dflags' object_filename
+ do (iface, changed, details) <- hscSimpleIface hsc_env tc_result mb_old_hash
+ hscWriteIface dflags iface changed summary
+ touchObjectFile dflags object_filename
return (HomeModInfo{ hm_details = details,
hm_iface = iface,
hm_linkable = maybe_old_linkable })
- _ -> do guts0 <- hscDesugar hsc_env' summary tc_result
- guts <- hscSimplify hsc_env' guts0
- (iface, changed, details, cgguts) <- hscNormalIface hsc_env' guts mb_old_hash
- hscWriteIface dflags' iface changed summary
- (_outputFilename, hasStub) <- hscGenHardCode hsc_env' cgguts summary
+ _ -> do guts0 <- hscDesugar hsc_env summary tc_result
+ guts <- hscSimplify hsc_env guts0
+ (iface, changed, details, cgguts) <- hscNormalIface hsc_env extCore_filename guts mb_old_hash
+ hscWriteIface dflags iface changed summary
-- We're in --make mode: finish the compilation pipeline.
- maybe_stub_o <- case hasStub of
- Nothing -> return Nothing
- Just stub_c -> do
- stub_o <- compileStub hsc_env' stub_c
- return (Just stub_o)
- _ <- runPipeline StopLn hsc_env' (output_fn,Nothing)
+ let mod_name = ms_mod_name summary
+ _ <- runPipeline StopLn hsc_env
+ (output_fn,
+ Just (HscOut src_flavour mod_name (HscRecomp cgguts summary)))
(Just basename)
Persistent
(Just location)
- maybe_stub_o
+ Nothing
-- The object filename comes from the ModLocation
o_time <- getModificationUTCTime object_filename
let linkable = LM o_time this_mod [DotO object_filename]
@@ -375,7 +370,7 @@ linkingNeeded dflags linkables pkg_deps = do
Left _ -> return True
Right t -> do
-- first check object files and extra_ld_inputs
- let extra_ld_inputs = ldInputs dflags
+ let extra_ld_inputs = [ f | FileOption _ f <- ldInputs dflags ]
e_extra_times <- mapM (tryIO . getModificationUTCTime) extra_ld_inputs
let (errs,extra_times) = splitEithers e_extra_times
let obj_times = map linkableTime linkables ++ extra_times
@@ -475,7 +470,7 @@ compileFile hsc_env stop_phase (src, mb_phase) = do
_ -> stop_phase
( _, out_file) <- runPipeline stop_phase' hsc_env
- (src, mb_phase) Nothing output
+ (src, fmap RealPhase mb_phase) Nothing output
Nothing{-no ModLocation-} Nothing
return out_file
@@ -521,12 +516,12 @@ data PipelineOutput
runPipeline
:: Phase -- ^ When to stop
-> HscEnv -- ^ Compilation environment
- -> (FilePath,Maybe Phase) -- ^ Input filename (and maybe -x suffix)
+ -> (FilePath,Maybe PhasePlus) -- ^ Input filename (and maybe -x suffix)
-> Maybe FilePath -- ^ original basename (if different from ^^^)
-> PipelineOutput -- ^ Output filename
-> Maybe ModLocation -- ^ A ModLocation, if this is a Haskell module
-> Maybe FilePath -- ^ stub object, if we have one
- -> IO (DynFlags, FilePath) -- ^ (final flags, output filename)
+ -> IO (DynFlags, FilePath) -- ^ (final flags, output filename)
runPipeline stop_phase hsc_env0 (input_fn, mb_phase)
mb_basename output maybe_loc maybe_stub_o
@@ -543,13 +538,14 @@ runPipeline stop_phase hsc_env0 (input_fn, mb_phase)
| otherwise = input_basename
-- If we were given a -x flag, then use that phase to start from
- start_phase = fromMaybe (startPhase suffix') mb_phase
+ start_phase = fromMaybe (RealPhase (startPhase suffix')) mb_phase
- isHaskell (Unlit _) = True
- isHaskell (Cpp _) = True
- isHaskell (HsPp _) = True
- isHaskell (Hsc _) = True
- isHaskell _ = False
+ isHaskell (RealPhase (Unlit _)) = True
+ isHaskell (RealPhase (Cpp _)) = True
+ isHaskell (RealPhase (HsPp _)) = True
+ isHaskell (RealPhase (Hsc _)) = True
+ isHaskell (HscOut {}) = True
+ isHaskell _ = False
isHaskellishFile = isHaskell start_phase
@@ -568,10 +564,13 @@ runPipeline stop_phase hsc_env0 (input_fn, mb_phase)
-- before B in a normal compilation pipeline.
let happensBefore' = happensBefore dflags
- when (not (start_phase `happensBefore'` stop_phase)) $
- throwGhcExceptionIO (UsageError
- ("cannot compile this file to desired target: "
- ++ input_fn))
+ case start_phase of
+ RealPhase start_phase' ->
+ when (not (start_phase' `happensBefore'` stop_phase)) $
+ throwGhcExceptionIO (UsageError
+ ("cannot compile this file to desired target: "
+ ++ input_fn))
+ HscOut {} -> return ()
debugTraceMsg dflags 4 (text "Running the pipeline")
r <- runPipeline' start_phase hsc_env env input_fn
@@ -584,7 +583,7 @@ runPipeline stop_phase hsc_env0 (input_fn, mb_phase)
when isHaskellishFile $ whenCannotGenerateDynamicToo dflags $ do
debugTraceMsg dflags 4
(text "Running the pipeline again for -dynamic-too")
- let dflags' = doDynamicToo dflags
+ let dflags' = dynamicTooMkDynamicDynFlags dflags
hsc_env' <- newHscEnv dflags'
_ <- runPipeline' start_phase hsc_env' env input_fn
maybe_loc maybe_stub_o
@@ -592,7 +591,7 @@ runPipeline stop_phase hsc_env0 (input_fn, mb_phase)
return r
runPipeline'
- :: Phase -- ^ When to start
+ :: PhasePlus -- ^ When to start
-> HscEnv -- ^ Compilation environment
-> PipeEnv
-> FilePath -- ^ Input filename
@@ -605,7 +604,7 @@ runPipeline' start_phase hsc_env env input_fn
-- Execute the pipeline...
let state = PipeState{ hsc_env, maybe_loc, maybe_stub_o = maybe_stub_o }
- evalP (pipeLoop (RealPhase start_phase) input_fn) env state
+ evalP (pipeLoop start_phase input_fn) env state
-- -----------------------------------------------------------------------------
-- The pipeline uses a monad to carry around various bits of information
@@ -722,12 +721,12 @@ pipeLoop phase input_fn = do
(ptext (sLit "Running phase") <+> ppr phase)
(next_phase, output_fn) <- runPhase phase input_fn dflags
r <- pipeLoop next_phase output_fn
- case next_phase of
+ case phase of
HscOut {} ->
whenGeneratingDynamicToo dflags $ do
- setDynFlags $ doDynamicToo dflags
+ setDynFlags $ dynamicTooMkDynamicDynFlags dflags
-- TODO shouldn't ignore result:
- _ <- pipeLoop next_phase output_fn
+ _ <- pipeLoop phase input_fn
return ()
_ ->
return ()
@@ -801,7 +800,7 @@ instance Outputable PhasePlus where
-- what the rest of the phases will be until part-way through the
-- compilation: for example, an {-# OPTIONS -fasm #-} at the beginning
-- of a source file can change the latter stages of the pipeline from
--- taking the via-C route to using the native code generator.
+-- taking the LLVM route to using the native code generator.
--
runPhase :: PhasePlus -- ^ Run this phase
-> FilePath -- ^ name of the input file
@@ -821,9 +820,7 @@ runPhase (RealPhase (Unlit sf)) input_fn dflags
= do
output_fn <- phaseOutputFilename (Cpp sf)
- let unlit_flags = getOpts dflags opt_L
- flags = map SysTools.Option unlit_flags ++
- [ -- The -h option passes the file name for unlit to
+ let flags = [ -- The -h option passes the file name for unlit to
-- put in a #line directive
SysTools.Option "-h"
, SysTools.Option $ escape $ normalise input_fn
@@ -870,7 +867,7 @@ runPhase (RealPhase (Cpp sf)) input_fn dflags0
return (RealPhase (HsPp sf), input_fn)
else do
output_fn <- phaseOutputFilename (HsPp sf)
- liftIO $ doCpp dflags1 True{-raw-} False{-no CC opts-}
+ liftIO $ doCpp dflags1 True{-raw-}
input_fn output_fn
-- re-read the pragmas now that we've preprocessed the file
-- See #2464,#3457
@@ -896,7 +893,6 @@ runPhase (RealPhase (HsPp sf)) input_fn dflags
-- to the next phase of the pipeline.
return (RealPhase (Hsc sf), input_fn)
else do
- let hspp_opts = getOpts dflags opt_F
PipeEnv{src_basename, src_suffix} <- getPipeEnv
let orig_fn = src_basename <.> src_suffix
output_fn <- phaseOutputFilename (Hsc sf)
@@ -904,8 +900,7 @@ runPhase (RealPhase (HsPp sf)) input_fn dflags
( [ SysTools.Option orig_fn
, SysTools.Option input_fn
, SysTools.FileOption "" output_fn
- ] ++
- map SysTools.Option hspp_opts
+ ]
)
-- re-read pragmas now that we've parsed the file (see #3674)
@@ -960,8 +955,6 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
let o_file = ml_obj_file location -- The real object file
- setModLocation location
-
-- Figure out if the source has changed, for recompilation avoidance.
--
-- Setting source_unchanged to True means that M.o seems
@@ -986,9 +979,8 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
then return SourceUnmodified
else return SourceModified
- let dflags' = dflags { extCoreName = basename ++ ".hcr" }
+ let extCore_filename = basename ++ ".hcr"
- setDynFlags dflags'
PipeState{hsc_env=hsc_env'} <- getPipeState
-- Tell the finder cache about this module
@@ -1008,7 +1000,7 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
ms_srcimps = src_imps }
-- run the compiler!
- result <- liftIO $ hscCompileOneShot hsc_env'
+ result <- liftIO $ hscCompileOneShot hsc_env' extCore_filename
mod_summary source_unchanged
return (HscOut src_flavour mod_name result,
@@ -1016,6 +1008,8 @@ runPhase (RealPhase (Hsc src_flavour)) input_fn dflags0
runPhase (HscOut src_flavour mod_name result) _ dflags = do
location <- getLocation src_flavour mod_name
+ setModLocation location
+
let o_file = ml_obj_file location -- The real object file
hsc_lang = hscTarget dflags
next_phase = hscPostBackendPhase dflags src_flavour hsc_lang
@@ -1038,11 +1032,9 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do
HscRecomp cgguts mod_summary
-> do output_fn <- phaseOutputFilename next_phase
- let dflags' = dflags { hscOutName = output_fn }
- setDynFlags dflags'
PipeState{hsc_env=hsc_env'} <- getPipeState
- (outputFilename, mStub) <- liftIO $ hscGenHardCode hsc_env' cgguts mod_summary
+ (outputFilename, mStub) <- liftIO $ hscGenHardCode hsc_env' cgguts mod_summary output_fn
case mStub of
Nothing -> return ()
Just stub_c ->
@@ -1057,26 +1049,21 @@ runPhase (HscOut src_flavour mod_name result) _ dflags = do
runPhase (RealPhase CmmCpp) input_fn dflags
= do
output_fn <- phaseOutputFilename Cmm
- liftIO $ doCpp dflags False{-not raw-} True{-include CC opts-}
+ liftIO $ doCpp dflags False{-not raw-}
input_fn output_fn
return (RealPhase Cmm, output_fn)
runPhase (RealPhase Cmm) input_fn dflags
= do
- PipeEnv{src_basename} <- getPipeEnv
let hsc_lang = hscTarget dflags
let next_phase = hscPostBackendPhase dflags HsSrcFile hsc_lang
output_fn <- phaseOutputFilename next_phase
- let dflags' = dflags { hscOutName = output_fn,
- extCoreName = src_basename ++ ".hcr" }
-
- setDynFlags dflags'
PipeState{hsc_env} <- getPipeState
- liftIO $ hscCompileCmmFile hsc_env input_fn
+ liftIO $ hscCompileCmmFile hsc_env input_fn output_fn
return (RealPhase next_phase, output_fn)
@@ -1090,7 +1077,6 @@ runPhase (RealPhase cc_phase) input_fn dflags
| any (cc_phase `eqPhase`) [Cc, Ccpp, HCc, Cobjc, Cobjcpp]
= do
let platform = targetPlatform dflags
- cc_opts = getOpts dflags opt_c
hcc = cc_phase `eqPhase` HCc
let cmdline_include_paths = includePaths dflags
@@ -1130,8 +1116,9 @@ runPhase (RealPhase cc_phase) input_fn dflags
split_opt | hcc && split_objs = [ "-DUSE_SPLIT_MARKERS" ]
| otherwise = [ ]
- let cc_opt | optLevel dflags >= 2 = "-O2"
- | otherwise = "-O"
+ let cc_opt | optLevel dflags >= 2 = [ "-O2" ]
+ | optLevel dflags >= 1 = [ "-O" ]
+ | otherwise = []
-- Decide next phase
let next_phase = As
@@ -1154,10 +1141,10 @@ runPhase (RealPhase cc_phase) input_fn dflags
-- very weakly typed, being derived from C--.
["-fno-strict-aliasing"]
- let gcc_lang_opt | cc_phase `eqPhase` Ccpp = "c++"
- | cc_phase `eqPhase` Cobjc = "objective-c"
+ let gcc_lang_opt | cc_phase `eqPhase` Ccpp = "c++"
+ | cc_phase `eqPhase` Cobjc = "objective-c"
| cc_phase `eqPhase` Cobjcpp = "objective-c++"
- | otherwise = "c"
+ | otherwise = "c"
liftIO $ SysTools.runCc dflags (
-- force the C compiler to interpret this file as C when
-- compiling .hc files, by adding the -x c option.
@@ -1201,10 +1188,10 @@ runPhase (RealPhase cc_phase) input_fn dflags
then gcc_extra_viac_flags ++ more_hcc_opts
else [])
++ verbFlags
- ++ [ "-S", cc_opt ]
+ ++ [ "-S" ]
+ ++ cc_opt
++ [ "-D__GLASGOW_HASKELL__="++cProjectVersionInt ]
++ framework_paths
- ++ cc_opts
++ split_opt
++ include_paths
++ pkg_extra_cc_opts
@@ -1263,8 +1250,7 @@ runPhase (RealPhase As) input_fn dflags
| otherwise = return SysTools.runAs
as_prog <- whichAsProg
- let as_opts = getOpts dflags opt_a
- cmdline_include_paths = includePaths dflags
+ let cmdline_include_paths = includePaths dflags
next_phase <- maybeMergeStub
output_fn <- phaseOutputFilename next_phase
@@ -1275,8 +1261,7 @@ runPhase (RealPhase As) input_fn dflags
let runAssembler inputFilename outputFilename
= liftIO $ as_prog dflags
- (map SysTools.Option as_opts
- ++ [ SysTools.Option ("-I" ++ p) | p <- cmdline_include_paths ]
+ ([ SysTools.Option ("-I" ++ p) | p <- cmdline_include_paths ]
-- We only support SparcV9 and better because V8 lacks an atomic CAS
-- instruction so we have to make sure that the assembler accepts the
@@ -1322,8 +1307,6 @@ runPhase (RealPhase SplitAs) _input_fn dflags
liftIO $ mapM_ removeFile $
map (split_odir </>) $ filter (osuf `isSuffixOf`) fs
- let as_opts = getOpts dflags opt_a
-
let (split_s_prefix, n) = case splitInfo dflags of
Nothing -> panic "No split info"
Just x -> x
@@ -1335,8 +1318,7 @@ runPhase (RealPhase SplitAs) _input_fn dflags
takeFileName base_o ++ "__" ++ show n <.> osuf
let assemble_file n
- = SysTools.runAs dflags
- (map SysTools.Option as_opts ++
+ = SysTools.runAs dflags (
-- We only support SparcV9 and better because V8 lacks an atomic CAS
-- instruction so we have to make sure that the assembler accepts the
@@ -1392,14 +1374,13 @@ runPhase (RealPhase LlvmOpt) input_fn dflags
= do
ver <- liftIO $ readIORef (llvmVersion dflags)
- let lo_opts = getOpts dflags opt_lo
- opt_lvl = max 0 (min 2 $ optLevel dflags)
+ let opt_lvl = max 0 (min 2 $ optLevel dflags)
-- don't specify anything if user has specified commands. We do this
-- for opt but not llc since opt is very specifically for optimisation
-- passes only, so if the user is passing us extra options we assume
-- they know what they are doing and don't get in the way.
- optFlag = if null lo_opts
- then [SysTools.Option (llvmOpts !! opt_lvl)]
+ optFlag = if null (getOpts dflags opt_lo)
+ then map SysTools.Option $ words (llvmOpts !! opt_lvl)
else []
tbaa | ver < 29 = "" -- no tbaa in 2.8 and earlier
| gopt Opt_LlvmTBAA dflags = "--enable-tbaa=true"
@@ -1413,14 +1394,13 @@ runPhase (RealPhase LlvmOpt) input_fn dflags
SysTools.Option "-o",
SysTools.FileOption "" output_fn]
++ optFlag
- ++ [SysTools.Option tbaa]
- ++ map SysTools.Option lo_opts)
+ ++ [SysTools.Option tbaa])
return (RealPhase LlvmLlc, output_fn)
where
-- we always (unless -optlo specified) run Opt since we rely on it to
-- fix up some pretty big deficiencies in the code we generate
- llvmOpts = ["-mem2reg", "-O1", "-O2"]
+ llvmOpts = ["-mem2reg -globalopt", "-O1", "-O2"]
-----------------------------------------------------------------------------
-- LlvmLlc phase
@@ -1429,8 +1409,7 @@ runPhase (RealPhase LlvmLlc) input_fn dflags
= do
ver <- liftIO $ readIORef (llvmVersion dflags)
- let lc_opts = getOpts dflags opt_lc
- opt_lvl = max 0 (min 2 $ optLevel dflags)
+ let opt_lvl = max 0 (min 2 $ optLevel dflags)
-- iOS requires external references to be loaded indirectly from the
-- DATA segment or dyld traps at runtime writing into TEXT: see #7722
rmodel | platformOS (targetPlatform dflags) == OSiOS = "dynamic-no-pic"
@@ -1454,7 +1433,6 @@ runPhase (RealPhase LlvmLlc) input_fn dflags
SysTools.Option $ "-relocation-model=" ++ rmodel,
SysTools.FileOption "" input_fn,
SysTools.Option "-o", SysTools.FileOption "" output_fn]
- ++ map SysTools.Option lc_opts
++ [SysTools.Option tbaa]
++ map SysTools.Option fpOpts
++ map SysTools.Option abiOpts
@@ -1607,7 +1585,6 @@ mkExtraObj dflags extn xs
FileOption "" cFile,
Option "-o",
FileOption "" oFile]
- ++ map SysTools.Option (getOpts dflags opt_c) -- see #5528
++ map (FileOption "-I") (includeDirs rtsDetails))
return oFile
@@ -1665,7 +1642,17 @@ mkNoteObjsToLinkIntoBinary dflags dep_packages = do
text elfSectionNote,
text "\n",
- text "\t.ascii \"", info', text "\"\n" ]
+ text "\t.ascii \"", info', text "\"\n",
+
+ -- ALL generated assembly must have this section to disable
+ -- executable stacks. See also
+ -- compiler/nativeGen/AsmCodeGen.lhs for another instance
+ -- where we need to do this.
+ (if platformHasGnuNonexecStack (targetPlatform dflags)
+ then text ".section .note.GNU-stack,\"\",@progbits\n"
+ else empty)
+
+ ]
where
info' = text $ escape info
@@ -1694,7 +1681,7 @@ getLinkInfo dflags dep_packages = do
rtsOpts dflags,
rtsOptsEnabled dflags,
gopt Opt_NoHsMain dflags,
- extra_ld_inputs,
+ map showOpt extra_ld_inputs,
getOpts dflags opt_l)
--
return (show link_info)
@@ -1828,7 +1815,13 @@ linkBinary dflags o_files dep_packages = do
extraLinkObj <- mkExtraObjToLinkIntoBinary dflags
noteLinkObjs <- mkNoteObjsToLinkIntoBinary dflags dep_packages
- pkg_link_opts <- getPackageLinkOpts dflags dep_packages
+ pkg_link_opts <- if platformBinariesAreStaticLibs platform
+ then -- If building an executable really means
+ -- making a static library (e.g. iOS), then
+ -- we don't want the options (like -lm)
+ -- that getPackageLinkOpts gives us. #7720
+ return []
+ else getPackageLinkOpts dflags dep_packages
pkg_framework_path_opts <-
if platformUsesFrameworks platform
@@ -1860,9 +1853,6 @@ linkBinary dflags o_files dep_packages = do
-- probably _stub.o files
let extra_ld_inputs = ldInputs dflags
- -- opts from -optl-<blah> (including -l<blah> options)
- let extra_ld_opts = getOpts dflags opt_l
-
-- Here are some libs that need to be linked at the *end* of
-- the command line, because they contain symbols that are referred to
-- by the RTS. We can't therefore use the ordinary way opts for these.
@@ -1926,10 +1916,10 @@ linkBinary dflags o_files dep_packages = do
else [])
++ o_files
+ ++ lib_path_opts)
++ extra_ld_inputs
- ++ lib_path_opts
- ++ extra_ld_opts
- ++ rc_objs
+ ++ map SysTools.Option (
+ rc_objs
++ framework_path_opts
++ framework_opts
++ pkg_lib_path_opts
@@ -1950,15 +1940,16 @@ linkBinary dflags o_files dep_packages = do
exeFileName :: DynFlags -> FilePath
exeFileName dflags
| Just s <- outputFile dflags =
- if platformOS (targetPlatform dflags) == OSMinGW32
- then if null (takeExtension s)
- then s <.> "exe"
- else s
- else s
+ case platformOS (targetPlatform dflags) of
+ OSMinGW32 -> s <?.> "exe"
+ OSiOS -> s <?.> "a"
+ _ -> s
| otherwise =
if platformOS (targetPlatform dflags) == OSMinGW32
then "main.exe"
else "a.out"
+ where s <?.> ext | null (takeExtension s) = s <.> ext
+ | otherwise = s
maybeCreateManifest
:: DynFlags
@@ -2000,12 +1991,10 @@ maybeCreateManifest dflags exe_filename
-- show is a bit hackish above, but we need to escape the
-- backslashes in the path.
- let wr_opts = getOpts dflags opt_windres
runWindres dflags $ map SysTools.Option $
["--input="++rc_filename,
"--output="++rc_obj_filename,
"--output-format=coff"]
- ++ wr_opts
-- no FileOptions here: windres doesn't like seeing
-- backslashes, apparently
@@ -2028,9 +2017,9 @@ linkDynLibCheck dflags o_files dep_packages
-- -----------------------------------------------------------------------------
-- Running CPP
-doCpp :: DynFlags -> Bool -> Bool -> FilePath -> FilePath -> IO ()
-doCpp dflags raw include_cc_opts input_fn output_fn = do
- let hscpp_opts = getOpts dflags opt_P ++ picPOpts dflags
+doCpp :: DynFlags -> Bool -> FilePath -> FilePath -> IO ()
+doCpp dflags raw input_fn output_fn = do
+ let hscpp_opts = picPOpts dflags
let cmdline_include_paths = includePaths dflags
pkg_include_dirs <- getPackageIncludePath dflags []
@@ -2039,10 +2028,6 @@ doCpp dflags raw include_cc_opts input_fn output_fn = do
let verbFlags = getVerbFlags dflags
- let cc_opts
- | include_cc_opts = getOpts dflags opt_c
- | otherwise = []
-
let cpp_prog args | raw = SysTools.runCpp dflags args
| otherwise = SysTools.runCc dflags (SysTools.Option "-E" : args)
@@ -2069,10 +2054,13 @@ doCpp dflags raw include_cc_opts input_fn output_fn = do
++ map SysTools.Option target_defs
++ map SysTools.Option backend_defs
++ map SysTools.Option hscpp_opts
- ++ map SysTools.Option cc_opts
++ map SysTools.Option sse_defs
+ -- Set the language mode to assembler-with-cpp when preprocessing. This
+ -- alleviates some of the C99 macro rules relating to whitespace and the hash
+ -- operator, which we tend to abuse. Clang in particular is not very happy
+ -- about this.
++ [ SysTools.Option "-x"
- , SysTools.Option "c"
+ , SysTools.Option "assembler-with-cpp"
, SysTools.Option input_fn
-- We hackily use Option instead of FileOption here, so that the file
-- name is not back-slashed on Windows. cpp is capable of
diff --git a/compiler/main/DynFlags.hs b/compiler/main/DynFlags.hs
index af4518f8dc..94a6697418 100644
--- a/compiler/main/DynFlags.hs
+++ b/compiler/main/DynFlags.hs
@@ -32,7 +32,7 @@ module DynFlags (
lang_set,
whenGeneratingDynamicToo, ifGeneratingDynamicToo,
whenCannotGenerateDynamicToo,
- doDynamicToo,
+ dynamicTooMkDynamicDynFlags,
DynFlags(..),
HasDynFlags(..), ContainsDynFlags(..),
RtsOptsEnabled(..),
@@ -50,7 +50,7 @@ module DynFlags (
printOutputForUser, printInfoForUser,
- Way(..), mkBuildTag, wayRTSOnly, updateWays,
+ Way(..), mkBuildTag, wayRTSOnly, addWay', updateWays,
wayGeneralFlags, wayUnsetGeneralFlags,
-- ** Safe Haskell
@@ -79,6 +79,7 @@ module DynFlags (
defaultFatalMessager,
defaultLogAction,
defaultLogActionHPrintDoc,
+ defaultLogActionHPutStrDoc,
defaultFlushOut,
defaultFlushErr,
@@ -129,6 +130,9 @@ module DynFlags (
-- * SSE
isSse2Enabled,
isSse4_2Enabled,
+
+ -- * Linker information
+ LinkerInfo(..),
) where
#include "HsVersions.h"
@@ -274,6 +278,8 @@ data GeneralFlag
-- optimisation opts
| Opt_Strictness
| Opt_LateDmdAnal
+ | Opt_KillAbsence
+ | Opt_KillOneShot
| Opt_FullLaziness
| Opt_FloatIn
| Opt_Specialise
@@ -350,6 +356,7 @@ data GeneralFlag
| Opt_RPath
| Opt_RelativeDynlibPaths
| Opt_Hpc
+ | Opt_FlatCache
-- PreInlining is on by default. The option is there just to see how
-- bad things get if you turn it off!
@@ -407,6 +414,8 @@ data WarningFlag =
| Opt_WarnIncompletePatterns
| Opt_WarnIncompleteUniPatterns
| Opt_WarnIncompletePatternsRecUpd
+ | Opt_WarnOverflowedLiterals
+ | Opt_WarnEmptyEnumerations
| Opt_WarnMissingFields
| Opt_WarnMissingImportList
| Opt_WarnMissingMethods
@@ -527,6 +536,7 @@ data ExtensionFlag
| Opt_MagicHash
| Opt_EmptyDataDecls
| Opt_KindSignatures
+ | Opt_RoleAnnotations
| Opt_ParallelListComp
| Opt_TransformListComp
| Opt_MonadComprehensions
@@ -551,6 +561,7 @@ data ExtensionFlag
| Opt_LambdaCase
| Opt_MultiWayIf
| Opt_TypeHoles
+ | Opt_NegativeLiterals
| Opt_EmptyCase
deriving (Eq, Enum, Show)
@@ -561,8 +572,6 @@ data DynFlags = DynFlags {
ghcLink :: GhcLink,
hscTarget :: HscTarget,
settings :: Settings,
- hscOutName :: String, -- ^ Name of the output file
- extCoreName :: String, -- ^ Name of the .hcr output file
verbosity :: Int, -- ^ Verbosity level: see Note [Verbosity levels]
optLevel :: Int, -- ^ Optimisation level
simplPhases :: Int, -- ^ Number of simplifier phases
@@ -613,6 +622,14 @@ data DynFlags = DynFlags {
dynObjectSuf :: String,
dynHiSuf :: String,
+ -- Packages.isDllName needs to know whether a call is within a
+ -- single DLL or not. Normally it does this by seeing if the call
+ -- is to the same package, but for the ghc package, we split the
+ -- package between 2 DLLs. The dllSplit tells us which sets of
+ -- modules are in which package.
+ dllSplitFile :: Maybe FilePath,
+ dllSplit :: Maybe [Set String],
+
outputFile :: Maybe String,
dynOutputFile :: Maybe String,
outputHi :: Maybe String,
@@ -626,7 +643,7 @@ data DynFlags = DynFlags {
-- Set by @-ddump-file-prefix@
dumpPrefixForce :: Maybe FilePath,
- ldInputs :: [String],
+ ldInputs :: [Option],
includePaths :: [String],
libraryPaths :: [String],
@@ -735,7 +752,10 @@ data DynFlags = DynFlags {
nextWrapperNum :: IORef Int,
-- | Machine dependant flags (-m<blah> stuff)
- sseVersion :: Maybe (Int, Int) -- (major, minor)
+ sseVersion :: Maybe (Int, Int), -- (major, minor)
+
+ -- | Run-time linker information (what options we need, etc.)
+ rtldFlags :: IORef (Maybe LinkerInfo)
}
class HasDynFlags m where
@@ -869,11 +889,6 @@ opt_lc dflags = sOpt_lc (settings dflags)
-- 'HscNothing' can be used to avoid generating any output, however, note
-- that:
--
--- * This will not run the desugaring step, thus no warnings generated in
--- this step will be output. In particular, this includes warnings related
--- to pattern matching. You can run the desugarer manually using
--- 'GHC.desugarModule'.
---
-- * If a program uses Template Haskell the typechecker may try to run code
-- from an imported module. This will fail if no code has been generated
-- for this module. You can use 'GHC.needsTemplateHaskell' to detect
@@ -1167,27 +1182,35 @@ generateDynamicTooConditional dflags canGen cannotGen notTryingToGen
if b then canGen else cannotGen
else notTryingToGen
-doDynamicToo :: DynFlags -> DynFlags
-doDynamicToo dflags0 = let dflags1 = addWay' WayDyn dflags0
- dflags2 = dflags1 {
- outputFile = dynOutputFile dflags1,
- hiSuf = dynHiSuf dflags1,
- objectSuf = dynObjectSuf dflags1
- }
- dflags3 = updateWays dflags2
- in dflags3
+dynamicTooMkDynamicDynFlags :: DynFlags -> DynFlags
+dynamicTooMkDynamicDynFlags dflags0
+ = let dflags1 = addWay' WayDyn dflags0
+ dflags2 = dflags1 {
+ outputFile = dynOutputFile dflags1,
+ hiSuf = dynHiSuf dflags1,
+ objectSuf = dynObjectSuf dflags1
+ }
+ dflags3 = updateWays dflags2
+ dflags4 = gopt_unset dflags3 Opt_BuildDynamicToo
+ in dflags4
-----------------------------------------------------------------------------
-- | Used by 'GHC.newSession' to partially initialize a new 'DynFlags' value
initDynFlags :: DynFlags -> IO DynFlags
initDynFlags dflags = do
- refCanGenerateDynamicToo <- newIORef True
+ let -- We can't build with dynamic-too on Windows, as labels before
+ -- the fork point are different depending on whether we are
+ -- building dynamically or not.
+ platformCanGenerateDynamicToo
+ = platformOS (targetPlatform dflags) /= OSMinGW32
+ refCanGenerateDynamicToo <- newIORef platformCanGenerateDynamicToo
refFilesToClean <- newIORef []
refDirsToClean <- newIORef Map.empty
refFilesToNotIntermediateClean <- newIORef []
refGeneratedDumps <- newIORef Set.empty
refLlvmVersion <- newIORef 28
+ refRtldFlags <- newIORef Nothing
wrapperNum <- newIORef 0
canUseUnicodeQuotes <- do let enc = localeEncoding
str = "‛’"
@@ -1203,7 +1226,8 @@ initDynFlags dflags = do
generatedDumps = refGeneratedDumps,
llvmVersion = refLlvmVersion,
nextWrapperNum = wrapperNum,
- useUnicodeQuotes = canUseUnicodeQuotes
+ useUnicodeQuotes = canUseUnicodeQuotes,
+ rtldFlags = refRtldFlags
}
-- | The normal 'DynFlags'. Note that they is not suitable for use in this form
@@ -1214,8 +1238,6 @@ defaultDynFlags mySettings =
ghcMode = CompManager,
ghcLink = LinkBinary,
hscTarget = defaultHscTarget (sTargetPlatform mySettings),
- hscOutName = "",
- extCoreName = "",
verbosity = 0,
optLevel = 0,
simplPhases = 2,
@@ -1254,6 +1276,9 @@ defaultDynFlags mySettings =
dynObjectSuf = "dyn_" ++ phaseInputExt StopLn,
dynHiSuf = "dyn_hi",
+ dllSplitFile = Nothing,
+ dllSplit = Nothing,
+
pluginModNames = [],
pluginModNameOpts = [],
@@ -1336,7 +1361,8 @@ defaultDynFlags mySettings =
llvmVersion = panic "defaultDynFlags: No llvmVersion",
interactivePrint = Nothing,
nextWrapperNum = panic "defaultDynFlags: No nextWrapperNum",
- sseVersion = Nothing
+ sseVersion = Nothing,
+ rtldFlags = panic "defaultDynFlags: no rtldFlags"
}
defaultWays :: Settings -> [Way]
@@ -1360,17 +1386,20 @@ defaultFatalMessager = hPutStrLn stderr
defaultLogAction :: LogAction
defaultLogAction dflags severity srcSpan style msg
= case severity of
- SevOutput -> printSDoc msg style
- SevDump -> printSDoc (msg $$ blankLine) style
- SevInfo -> printErrs msg style
- SevFatal -> printErrs msg style
- _ -> do hPutChar stderr '\n'
- printErrs (mkLocMessage severity srcSpan msg) style
- -- careful (#2302): printErrs prints in UTF-8, whereas
- -- converting to string first and using hPutStr would
- -- just emit the low 8 bits of each unicode char.
- where printSDoc = defaultLogActionHPrintDoc dflags stdout
- printErrs = defaultLogActionHPrintDoc dflags stderr
+ SevOutput -> printSDoc msg style
+ SevDump -> printSDoc (msg $$ blankLine) style
+ SevInteractive -> putStrSDoc msg style
+ SevInfo -> printErrs msg style
+ SevFatal -> printErrs msg style
+ _ -> do hPutChar stderr '\n'
+ printErrs (mkLocMessage severity srcSpan msg) style
+ -- careful (#2302): printErrs prints in UTF-8,
+ -- whereas converting to string first and using
+ -- hPutStr would just emit the low 8 bits of
+ -- each unicode char.
+ where printSDoc = defaultLogActionHPrintDoc dflags stdout
+ printErrs = defaultLogActionHPrintDoc dflags stderr
+ putStrSDoc = defaultLogActionHPutStrDoc dflags stdout
defaultLogActionHPrintDoc :: DynFlags -> Handle -> SDoc -> PprStyle -> IO ()
defaultLogActionHPrintDoc dflags h d sty
@@ -1378,6 +1407,12 @@ defaultLogActionHPrintDoc dflags h d sty
Pretty.printDoc Pretty.PageMode (pprCols dflags) h doc
hFlush h
+defaultLogActionHPutStrDoc :: DynFlags -> Handle -> SDoc -> PprStyle -> IO ()
+defaultLogActionHPutStrDoc dflags h d sty
+ = do let doc = runSDoc d (initSDocContext dflags sty)
+ hPutStr h (Pretty.render doc)
+ hFlush h
+
newtype FlushOut = FlushOut (IO ())
defaultFlushOut :: FlushOut
@@ -1853,9 +1888,23 @@ parseDynamicFlagsFull activeFlags cmdline dflags0 args = do
let (dflags4, consistency_warnings) = makeDynFlagsConsistent dflags3
- liftIO $ setUnsafeGlobalDynFlags dflags4
+ dflags5 <- case dllSplitFile dflags4 of
+ Nothing -> return (dflags4 { dllSplit = Nothing })
+ Just f ->
+ case dllSplit dflags4 of
+ Just _ ->
+ -- If dllSplit is out of date then it would have
+ -- been set to Nothing. As it's a Just, it must be
+ -- up-to-date.
+ return dflags4
+ Nothing ->
+ do xs <- liftIO $ readFile f
+ let ss = map (Set.fromList . words) (lines xs)
+ return $ dflags4 { dllSplit = Just ss }
+
+ liftIO $ setUnsafeGlobalDynFlags dflags5
- return (dflags4, leftover, consistency_warnings ++ sh_warns ++ warns)
+ return (dflags5, leftover, consistency_warnings ++ sh_warns ++ warns)
updateWays :: DynFlags -> DynFlags
updateWays dflags
@@ -2034,10 +2083,12 @@ dynamic_flags = [
, Flag "shared" (noArg (\d -> d{ ghcLink=LinkDynLib }))
, Flag "dynload" (hasArg parseDynLibLoaderMode)
, Flag "dylib-install-name" (hasArg setDylibInstallName)
+ -- -dll-split is an internal flag, used only during the GHC build
+ , Flag "dll-split" (hasArg (\f d -> d{ dllSplitFile = Just f, dllSplit = Nothing }))
------- Libraries ---------------------------------------------------
, Flag "L" (Prefix addLibraryPath)
- , Flag "l" (hasArg (addOptl . ("-l" ++)))
+ , Flag "l" (hasArg (addLdInputs . Option . ("-l" ++)))
------- Frameworks --------------------------------------------------
-- -framework-path should really be -F ...
@@ -2389,6 +2440,8 @@ fWarningFlags = [
( "warn-dodgy-foreign-imports", Opt_WarnDodgyForeignImports, nop ),
( "warn-dodgy-exports", Opt_WarnDodgyExports, nop ),
( "warn-dodgy-imports", Opt_WarnDodgyImports, nop ),
+ ( "warn-overflowed-literals", Opt_WarnOverflowedLiterals, nop ),
+ ( "warn-empty-enumerations", Opt_WarnEmptyEnumerations, nop ),
( "warn-duplicate-exports", Opt_WarnDuplicateExports, nop ),
( "warn-duplicate-constraints", Opt_WarnDuplicateConstraints, nop ),
( "warn-hi-shadowing", Opt_WarnHiShadows, nop ),
@@ -2508,7 +2561,10 @@ fFlags = [
( "prof-cafs", Opt_AutoSccsOnIndividualCafs, nop ),
( "hpc", Opt_Hpc, nop ),
( "pre-inlining", Opt_SimplPreInlining, nop ),
- ( "use-rpaths", Opt_RPath, nop )
+ ( "flat-cache", Opt_FlatCache, nop ),
+ ( "use-rpaths", Opt_RPath, nop ),
+ ( "kill-absence", Opt_KillAbsence, nop),
+ ( "kill-one-shot", Opt_KillOneShot, nop)
]
-- | These @-f\<blah\>@ flags can all be reversed with @-fno-\<blah\>@
@@ -2587,6 +2643,7 @@ xFlags = [
( "MagicHash", Opt_MagicHash, nop ),
( "ExistentialQuantification", Opt_ExistentialQuantification, nop ),
( "KindSignatures", Opt_KindSignatures, nop ),
+ ( "RoleAnnotations", Opt_RoleAnnotations, nop ),
( "EmptyDataDecls", Opt_EmptyDataDecls, nop ),
( "ParallelListComp", Opt_ParallelListComp, nop ),
( "TransformListComp", Opt_TransformListComp, nop ),
@@ -2679,6 +2736,7 @@ xFlags = [
( "IncoherentInstances", Opt_IncoherentInstances, nop ),
( "PackageImports", Opt_PackageImports, nop ),
( "TypeHoles", Opt_TypeHoles, nop ),
+ ( "NegativeLiterals", Opt_NegativeLiterals, nop ),
( "EmptyCase", Opt_EmptyCase, nop )
]
@@ -2698,6 +2756,7 @@ defaultFlags settings
Opt_HelpfulErrors,
Opt_ProfCountEntries,
Opt_SimplPreInlining,
+ Opt_FlatCache,
Opt_RPath
]
@@ -2775,6 +2834,7 @@ optLevelFlags
, ([1,2], Opt_FullLaziness)
, ([1,2], Opt_Specialise)
, ([1,2], Opt_FloatIn)
+ , ([1,2], Opt_UnboxSmallStrictFields)
, ([2], Opt_LiberateCase)
, ([2], Opt_SpecConstr)
@@ -2808,24 +2868,25 @@ optLevelFlags
standardWarnings :: [WarningFlag]
standardWarnings
- = [ Opt_WarnWarningsDeprecations,
+ = [ Opt_WarnOverlappingPatterns,
+ Opt_WarnWarningsDeprecations,
Opt_WarnDeprecatedFlags,
Opt_WarnUnrecognisedPragmas,
- Opt_WarnOverlappingPatterns,
+ Opt_WarnPointlessPragmas,
+ Opt_WarnDuplicateConstraints,
+ Opt_WarnDuplicateExports,
+ Opt_WarnOverflowedLiterals,
+ Opt_WarnEmptyEnumerations,
Opt_WarnMissingFields,
Opt_WarnMissingMethods,
- Opt_WarnDuplicateExports,
Opt_WarnLazyUnliftedBindings,
- Opt_WarnDodgyForeignImports,
Opt_WarnWrongDoBind,
- Opt_WarnAlternativeLayoutRuleTransitional,
- Opt_WarnPointlessPragmas,
Opt_WarnUnsupportedCallingConventions,
- Opt_WarnUnsupportedLlvmVersion,
- Opt_WarnInlineRuleShadowing,
- Opt_WarnDuplicateConstraints,
+ Opt_WarnDodgyForeignImports,
+ Opt_WarnTypeableInstances,
Opt_WarnInlineRuleShadowing,
- Opt_WarnTypeableInstances
+ Opt_WarnAlternativeLayoutRuleTransitional,
+ Opt_WarnUnsupportedLlvmVersion
]
minusWOpts :: [WarningFlag]
@@ -3184,6 +3245,9 @@ setMainIs arg
where
(main_mod, main_fn) = splitLongestPrefix arg (== '.')
+addLdInputs :: Option -> DynFlags -> DynFlags
+addLdInputs p dflags = dflags{ldInputs = ldInputs dflags ++ [p]}
+
-----------------------------------------------------------------------------
-- Paths & Libraries
@@ -3359,6 +3423,7 @@ compilerInfo dflags
("Support SMP", cGhcWithSMP),
("Tables next to code", cGhcEnableTablesNextToCode),
("RTS ways", cGhcRTSWays),
+ ("Support dynamic-too", "YES"),
("Dynamic by default", if dYNAMIC_BY_DEFAULT dflags
then "YES" else "NO"),
("GHC Dynamic", if cDYNAMIC_GHC_PROGRAMS
@@ -3415,7 +3480,7 @@ makeDynFlagsConsistent dflags
else let dflags' = dflags { hscTarget = HscLlvm }
warn = "Compiler not unregisterised, so using LLVM rather than compiling via C"
in loop dflags' warn
- | hscTarget dflags /= HscC && hscTarget dflags /= HscLlvm &&
+ | hscTarget dflags == HscAsm &&
platformUnregisterised (targetPlatform dflags)
= loop (dflags { hscTarget = HscC })
"Compiler unregisterised, so compiling via C"
@@ -3484,3 +3549,14 @@ isSse2Enabled dflags = case platformArch (targetPlatform dflags) of
isSse4_2Enabled :: DynFlags -> Bool
isSse4_2Enabled dflags = sseVersion dflags >= Just (4,2)
+
+-- -----------------------------------------------------------------------------
+-- Linker information
+
+-- LinkerInfo contains any extra options needed by the system linker.
+data LinkerInfo
+ = GnuLD [Option]
+ | GnuGold [Option]
+ | DarwinLD [Option]
+ | UnknownLD
+ deriving Eq
diff --git a/compiler/main/ErrUtils.lhs b/compiler/main/ErrUtils.lhs
index 3fd92ed473..f9f4387120 100644
--- a/compiler/main/ErrUtils.lhs
+++ b/compiler/main/ErrUtils.lhs
@@ -78,6 +78,7 @@ type MsgDoc = SDoc
data Severity
= SevOutput
| SevDump
+ | SevInteractive
| SevInfo
| SevWarning
| SevError
diff --git a/compiler/main/ErrUtils.lhs-boot b/compiler/main/ErrUtils.lhs-boot
index 6f4a373313..fc99c5afde 100644
--- a/compiler/main/ErrUtils.lhs-boot
+++ b/compiler/main/ErrUtils.lhs-boot
@@ -7,6 +7,7 @@ import SrcLoc (SrcSpan)
data Severity
= SevOutput
| SevDump
+ | SevInteractive
| SevInfo
| SevWarning
| SevError
diff --git a/compiler/main/GHC.hs b/compiler/main/GHC.hs
index c72f1f1be6..39e1e0a453 100644
--- a/compiler/main/GHC.hs
+++ b/compiler/main/GHC.hs
@@ -157,7 +157,7 @@ module GHC (
TyCon,
tyConTyVars, tyConDataCons, tyConArity,
isClassTyCon, isSynTyCon, isNewTyCon, isPrimTyCon, isFunTyCon,
- isFamilyTyCon, tyConClass_maybe,
+ isFamilyTyCon, isOpenFamilyTyCon, tyConClass_maybe,
synTyConRhs_maybe, synTyConDefn_maybe, synTyConResKind,
-- ** Type variables
@@ -182,7 +182,7 @@ module GHC (
pprInstance, pprInstanceHdr,
pprFamInst,
- FamInst, Branched,
+ FamInst,
-- ** Types and Kinds
Type, splitForAllTys, funResultTy,
@@ -892,8 +892,10 @@ compileToCoreSimplified = compileCore True
-- The resulting .o, .hi, and executable files, if any, are stored in the
-- current directory, and named according to the module name.
-- This has only so far been tested with a single self-contained module.
-compileCoreToObj :: GhcMonad m => Bool -> CoreModule -> m ()
-compileCoreToObj simplify cm@(CoreModule{ cm_module = mName }) = do
+compileCoreToObj :: GhcMonad m
+ => Bool -> CoreModule -> FilePath -> FilePath -> m ()
+compileCoreToObj simplify cm@(CoreModule{ cm_module = mName })
+ output_fn extCore_filename = do
dflags <- getSessionDynFlags
currentTime <- liftIO $ getCurrentTime
cwd <- liftIO $ getCurrentDirectory
@@ -919,7 +921,7 @@ compileCoreToObj simplify cm@(CoreModule{ cm_module = mName }) = do
}
hsc_env <- getSession
- liftIO $ hscCompileCore hsc_env simplify (cm_safe cm) modSum (cm_binds cm)
+ liftIO $ hscCompileCore hsc_env simplify (cm_safe cm) modSum (cm_binds cm) output_fn extCore_filename
compileCore :: GhcMonad m => Bool -> FilePath -> m CoreModule
@@ -1002,7 +1004,7 @@ getBindings = withSession $ \hsc_env ->
return $ icInScopeTTs $ hsc_IC hsc_env
-- | Return the instances for the current interactive session.
-getInsts :: GhcMonad m => m ([ClsInst], [FamInst Branched])
+getInsts :: GhcMonad m => m ([ClsInst], [FamInst])
getInsts = withSession $ \hsc_env ->
return $ ic_instances (hsc_IC hsc_env)
diff --git a/compiler/main/GhcMake.hs b/compiler/main/GhcMake.hs
index 4970b6725e..c43b18a62a 100644
--- a/compiler/main/GhcMake.hs
+++ b/compiler/main/GhcMake.hs
@@ -332,8 +332,7 @@ load how_much = do
liftIO $ intermediateCleanTempFiles dflags mods_to_keep hsc_env1
-- there should be no Nothings where linkables should be, now
- ASSERT(all (isJust.hm_linkable)
- (eltsUFM (hsc_HPT hsc_env))) do
+ ASSERT(all (isJust.hm_linkable) (eltsUFM (hsc_HPT hsc_env))) do
-- Link everything together
linkresult <- liftIO $ link (ghcLink dflags) dflags False hpt4
diff --git a/compiler/main/HeaderInfo.hs b/compiler/main/HeaderInfo.hs
index f7ae35ff55..2560db37f8 100644
--- a/compiler/main/HeaderInfo.hs
+++ b/compiler/main/HeaderInfo.hs
@@ -8,13 +8,6 @@
--
-----------------------------------------------------------------------------
-{-# OPTIONS -fno-warn-tabs #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and
--- detab the module (please do the detabbing in a separate patch). See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
--- for details
-
module HeaderInfo ( getImports
, mkPrelImports -- used by the renamer too
, getOptionsFromFile, getOptions
@@ -25,7 +18,7 @@ module HeaderInfo ( getImports
import RdrName
import HscTypes
-import Parser ( parseHeader )
+import Parser ( parseHeader )
import Lexer
import FastString
import HsSyn
@@ -39,7 +32,7 @@ import Util
import Outputable
import Pretty ()
import Maybes
-import Bag ( emptyBag, listToBag, unitBag )
+import Bag ( emptyBag, listToBag, unitBag )
import MonadUtils
import Exception
@@ -74,23 +67,23 @@ getImports dflags buf filename source_filename = do
if errorsFound dflags ms
then throwIO $ mkSrcErr errs
else
- case rdr_module of
- L _ (HsModule mb_mod _ imps _ _ _) ->
- let
+ case rdr_module of
+ L _ (HsModule mb_mod _ imps _ _ _) ->
+ let
main_loc = srcLocSpan (mkSrcLoc (mkFastString source_filename) 1 1)
- mod = mb_mod `orElse` L main_loc mAIN_NAME
- (src_idecls, ord_idecls) = partition (ideclSource.unLoc) imps
+ mod = mb_mod `orElse` L main_loc mAIN_NAME
+ (src_idecls, ord_idecls) = partition (ideclSource.unLoc) imps
- -- GHC.Prim doesn't exist physically, so don't go looking for it.
- ordinary_imps = filter ((/= moduleName gHC_PRIM) . unLoc . ideclName . unLoc)
- ord_idecls
+ -- GHC.Prim doesn't exist physically, so don't go looking for it.
+ ordinary_imps = filter ((/= moduleName gHC_PRIM) . unLoc . ideclName . unLoc)
+ ord_idecls
implicit_prelude = xopt Opt_ImplicitPrelude dflags
implicit_imports = mkPrelImports (unLoc mod) main_loc implicit_prelude imps
- in
- return (src_idecls, implicit_imports ++ ordinary_imps, mod)
+ in
+ return (src_idecls, implicit_imports ++ ordinary_imps, mod)
-mkPrelImports :: ModuleName
+mkPrelImports :: ModuleName
-> SrcSpan -- Attribute the "import Prelude" to this location
-> Bool -> [LImportDecl RdrName]
-> [LImportDecl RdrName]
@@ -108,20 +101,20 @@ mkPrelImports this_mod loc implicit_prelude import_decls
where
explicit_prelude_import
= notNull [ () | L _ (ImportDecl { ideclName = mod
- , ideclPkgQual = Nothing })
+ , ideclPkgQual = Nothing })
<- import_decls
- , unLoc mod == pRELUDE_NAME ]
+ , unLoc mod == pRELUDE_NAME ]
preludeImportDecl :: LImportDecl RdrName
preludeImportDecl
= L loc $ ImportDecl { ideclName = L loc pRELUDE_NAME,
- ideclPkgQual = Nothing,
- ideclSource = False,
- ideclSafe = False, -- Not a safe import
- ideclQualified = False,
- ideclImplicit = True, -- Implicit!
- ideclAs = Nothing,
- ideclHiding = Nothing }
+ ideclPkgQual = Nothing,
+ ideclSource = False,
+ ideclSafe = False, -- Not a safe import
+ ideclQualified = False,
+ ideclImplicit = True, -- Implicit!
+ ideclAs = Nothing,
+ ideclHiding = Nothing }
parseError :: DynFlags -> SrcSpan -> MsgDoc -> IO a
parseError dflags span err = throwOneError $ mkPlainErrMsg dflags span err
@@ -138,7 +131,7 @@ getOptionsFromFile :: DynFlags
-> IO [Located String] -- ^ Parsed options, if any.
getOptionsFromFile dflags filename
= Exception.bracket
- (openBinaryFile filename ReadMode)
+ (openBinaryFile filename ReadMode)
(hClose)
(\handle -> do
opts <- fmap (getOptions' dflags)
@@ -226,7 +219,7 @@ getOptions' :: DynFlags
-> [Located String] -- Options.
getOptions' dflags toks
= parseToks toks
- where
+ where
getToken (L _loc tok) = tok
getLoc (L loc _tok) = loc
@@ -313,9 +306,9 @@ unsupportedExtnError dflags loc unsup =
optionsErrorMsgs :: DynFlags -> [String] -> [Located String] -> FilePath -> Messages
optionsErrorMsgs dflags unhandled_flags flags_lines _filename
= (emptyBag, listToBag (map mkMsg unhandled_flags_lines))
- where unhandled_flags_lines = [ L l f | f <- unhandled_flags,
- L l f' <- flags_lines, f == f' ]
- mkMsg (L flagSpan flag) =
+ where unhandled_flags_lines = [ L l f | f <- unhandled_flags,
+ L l f' <- flags_lines, f == f' ]
+ mkMsg (L flagSpan flag) =
ErrUtils.mkPlainErrMsg dflags flagSpan $
text "unknown flag in {-# OPTIONS_GHC #-} pragma:" <+> text flag
diff --git a/compiler/main/HscMain.hs b/compiler/main/HscMain.hs
index c97e3ec724..e884fe5bcf 100644
--- a/compiler/main/HscMain.hs
+++ b/compiler/main/HscMain.hs
@@ -303,7 +303,7 @@ hscTcRcLookupName hsc_env0 name = runInteractiveHsc hsc_env0 $ do
-- "name not found", and the Maybe in the return type
-- is used to indicate that.
-hscTcRnGetInfo :: HscEnv -> Name -> IO (Maybe (TyThing, Fixity, [ClsInst], [FamInst Branched]))
+hscTcRnGetInfo :: HscEnv -> Name -> IO (Maybe (TyThing, Fixity, [ClsInst], [FamInst]))
hscTcRnGetInfo hsc_env0 name = runInteractiveHsc hsc_env0 $ do
hsc_env <- getHscEnv
ioMsgMaybe' $ tcRnGetInfo hsc_env name
@@ -616,10 +616,11 @@ genericHscFrontend mod_summary
-- Compile Haskell, boot and extCore in OneShot mode.
hscCompileOneShot :: HscEnv
+ -> FilePath
-> ModSummary
-> SourceModified
-> IO HscStatus
-hscCompileOneShot hsc_env mod_summary src_changed
+hscCompileOneShot hsc_env extCore_filename mod_summary src_changed
= do
-- One-shot mode needs a knot-tying mutable variable for interface
-- files. See TcRnTypes.TcGblEnv.tcg_type_env_var.
@@ -636,6 +637,7 @@ hscCompileOneShot hsc_env mod_summary src_changed
compile mb_old_hash reason = runHsc hsc_env' $ do
liftIO $ msg reason
tc_result <- genericHscFrontend mod_summary
+ guts0 <- hscDesugar' (ms_location mod_summary) tc_result
dflags <- getDynFlags
case hscTarget dflags of
HscNothing -> return HscNotGeneratingCode
@@ -646,9 +648,8 @@ hscCompileOneShot hsc_env mod_summary src_changed
liftIO $ hscWriteIface dflags iface changed mod_summary
return HscUpdateBoot
_ ->
- do guts0 <- hscDesugar' (ms_location mod_summary) tc_result
- guts <- hscSimplify' guts0
- (iface, changed, _details, cgguts) <- hscNormalIface' guts mb_old_hash
+ do guts <- hscSimplify' guts0
+ (iface, changed, _details, cgguts) <- hscNormalIface' extCore_filename guts mb_old_hash
liftIO $ hscWriteIface dflags iface changed mod_summary
return $ HscRecomp cgguts mod_summary
@@ -1082,16 +1083,18 @@ hscSimpleIface' tc_result mb_old_iface = do
return (new_iface, no_change, details)
hscNormalIface :: HscEnv
+ -> FilePath
-> ModGuts
-> Maybe Fingerprint
-> IO (ModIface, Bool, ModDetails, CgGuts)
-hscNormalIface hsc_env simpl_result mb_old_iface =
- runHsc hsc_env $ hscNormalIface' simpl_result mb_old_iface
+hscNormalIface hsc_env extCore_filename simpl_result mb_old_iface =
+ runHsc hsc_env $ hscNormalIface' extCore_filename simpl_result mb_old_iface
-hscNormalIface' :: ModGuts
+hscNormalIface' :: FilePath
+ -> ModGuts
-> Maybe Fingerprint
-> Hsc (ModIface, Bool, ModDetails, CgGuts)
-hscNormalIface' simpl_result mb_old_iface = do
+hscNormalIface' extCore_filename simpl_result mb_old_iface = do
hsc_env <- getHscEnv
(cg_guts, details) <- {-# SCC "CoreTidy" #-}
liftIO $ tidyProgram hsc_env simpl_result
@@ -1110,7 +1113,7 @@ hscNormalIface' simpl_result mb_old_iface = do
-- This should definitely be here and not after CorePrep,
-- because CorePrep produces unqualified constructor wrapper declarations,
-- so its output isn't valid External Core (without some preprocessing).
- liftIO $ emitExternalCore (hsc_dflags hsc_env) cg_guts
+ liftIO $ emitExternalCore (hsc_dflags hsc_env) extCore_filename cg_guts
liftIO $ dumpIfaceStats hsc_env
-- Return the prepared code.
@@ -1132,13 +1135,13 @@ hscWriteIface dflags iface no_change mod_summary = do
-- TODO: Should handle the dynamic hi filename properly
let dynIfaceFile = replaceExtension ifaceFile (dynHiSuf dflags)
dynIfaceFile' = addBootSuffix_maybe (mi_boot iface) dynIfaceFile
- dynDflags = doDynamicToo dflags
+ dynDflags = dynamicTooMkDynamicDynFlags dflags
writeIfaceFile dynDflags dynIfaceFile' iface
-- | Compile to hard-code.
-hscGenHardCode :: HscEnv -> CgGuts -> ModSummary
+hscGenHardCode :: HscEnv -> CgGuts -> ModSummary -> FilePath
-> IO (FilePath, Maybe FilePath) -- ^ @Just f@ <=> _stub.c is f
-hscGenHardCode hsc_env cgguts mod_summary = do
+hscGenHardCode hsc_env cgguts mod_summary output_filename = do
let CgGuts{ -- This is the last use of the ModGuts in a compilation.
-- From now on, we just use the bits we need.
cg_module = this_mod,
@@ -1184,8 +1187,8 @@ hscGenHardCode hsc_env cgguts mod_summary = do
(output_filename, (_stub_h_exists, stub_c_exists))
<- {-# SCC "codeOutput" #-}
- codeOutput dflags this_mod location foreign_stubs
- dependencies rawcmms1
+ codeOutput dflags this_mod output_filename location
+ foreign_stubs dependencies rawcmms1
return (output_filename, stub_c_exists)
@@ -1226,8 +1229,8 @@ hscInteractive _ _ = panic "GHC not compiled with interpreter"
------------------------------
-hscCompileCmmFile :: HscEnv -> FilePath -> IO ()
-hscCompileCmmFile hsc_env filename = runHsc hsc_env $ do
+hscCompileCmmFile :: HscEnv -> FilePath -> FilePath -> IO ()
+hscCompileCmmFile hsc_env filename output_filename = runHsc hsc_env $ do
let dflags = hsc_dflags hsc_env
cmm <- ioMsgMaybe $ parseCmmFile dflags filename
liftIO $ do
@@ -1236,7 +1239,7 @@ hscCompileCmmFile hsc_env filename = runHsc hsc_env $ do
dumpIfSet_dyn dflags Opt_D_dump_cmm "Parsed Cmm" (ppr cmm)
(_, cmmgroup) <- cmmPipeline hsc_env initTopSRT cmm
rawCmms <- cmmToRawCmm dflags (Stream.yield cmmgroup)
- _ <- codeOutput dflags no_mod no_loc NoStubs [] rawCmms
+ _ <- codeOutput dflags no_mod output_filename no_loc NoStubs [] rawCmms
return ()
where
no_mod = panic "hscCmmFile: no_mod"
@@ -1321,7 +1324,7 @@ myCoreToStg :: DynFlags -> Module -> CoreProgram
myCoreToStg dflags this_mod prepd_binds = do
stg_binds
<- {-# SCC "Core2Stg" #-}
- coreToStg dflags prepd_binds
+ coreToStg dflags this_mod prepd_binds
(stg_binds2, cost_centre_info)
<- {-# SCC "Stg2Stg" #-}
@@ -1556,13 +1559,13 @@ hscParseThingWithLocation source linenumber parser str
return thing
hscCompileCore :: HscEnv -> Bool -> SafeHaskellMode -> ModSummary
- -> CoreProgram -> IO ()
-hscCompileCore hsc_env simplify safe_mode mod_summary binds
+ -> CoreProgram -> FilePath -> FilePath -> IO ()
+hscCompileCore hsc_env simplify safe_mode mod_summary binds output_filename extCore_filename
= runHsc hsc_env $ do
guts <- maybe_simplify (mkModGuts (ms_mod mod_summary) safe_mode binds)
- (iface, changed, _details, cgguts) <- hscNormalIface' guts Nothing
+ (iface, changed, _details, cgguts) <- hscNormalIface' extCore_filename guts Nothing
liftIO $ hscWriteIface (hsc_dflags hsc_env) iface changed mod_summary
- _ <- liftIO $ hscGenHardCode hsc_env cgguts mod_summary
+ _ <- liftIO $ hscGenHardCode hsc_env cgguts mod_summary output_filename
return ()
where
diff --git a/compiler/main/HscTypes.lhs b/compiler/main/HscTypes.lhs
index d9fe88bb80..e022ae3eae 100644
--- a/compiler/main/HscTypes.lhs
+++ b/compiler/main/HscTypes.lhs
@@ -37,7 +37,7 @@ module HscTypes (
PackageInstEnv, PackageRuleBase,
- mkSOName, soExt,
+ mkSOName, mkHsSOName, soExt,
-- * Annotations
prepareAnnotations,
@@ -159,6 +159,7 @@ import StringBuffer ( StringBuffer )
import Fingerprint
import MonadUtils
import Bag
+import Binary
import ErrUtils
import Platform
import Util
@@ -456,7 +457,7 @@ lookupIfaceByModule dflags hpt pit mod
-- modules imported by this one, directly or indirectly, and are in the Home
-- Package Table. This ensures that we don't see instances from modules @--make@
-- compiled before this one, but which are not below this one.
-hptInstances :: HscEnv -> (ModuleName -> Bool) -> ([ClsInst], [FamInst Branched])
+hptInstances :: HscEnv -> (ModuleName -> Bool) -> ([ClsInst], [FamInst])
hptInstances hsc_env want_this_module
= let (insts, famInsts) = unzip $ flip hptAllThings hsc_env $ \mod_info -> do
guard (want_this_module (moduleName (mi_module (hm_iface mod_info))))
@@ -717,6 +718,113 @@ data ModIface
-- See Note [RnNames . Trust Own Package]
}
+instance Binary ModIface where
+ put_ bh (ModIface {
+ mi_module = mod,
+ mi_boot = is_boot,
+ mi_iface_hash= iface_hash,
+ mi_mod_hash = mod_hash,
+ mi_flag_hash = flag_hash,
+ mi_orphan = orphan,
+ mi_finsts = hasFamInsts,
+ mi_deps = deps,
+ mi_usages = usages,
+ mi_exports = exports,
+ mi_exp_hash = exp_hash,
+ mi_used_th = used_th,
+ mi_fixities = fixities,
+ mi_warns = warns,
+ mi_anns = anns,
+ mi_decls = decls,
+ mi_insts = insts,
+ mi_fam_insts = fam_insts,
+ mi_rules = rules,
+ mi_orphan_hash = orphan_hash,
+ mi_vect_info = vect_info,
+ mi_hpc = hpc_info,
+ mi_trust = trust,
+ mi_trust_pkg = trust_pkg }) = do
+ put_ bh mod
+ put_ bh is_boot
+ put_ bh iface_hash
+ put_ bh mod_hash
+ put_ bh flag_hash
+ put_ bh orphan
+ put_ bh hasFamInsts
+ lazyPut bh deps
+ lazyPut bh usages
+ put_ bh exports
+ put_ bh exp_hash
+ put_ bh used_th
+ put_ bh fixities
+ lazyPut bh warns
+ lazyPut bh anns
+ put_ bh decls
+ put_ bh insts
+ put_ bh fam_insts
+ lazyPut bh rules
+ put_ bh orphan_hash
+ put_ bh vect_info
+ put_ bh hpc_info
+ put_ bh trust
+ put_ bh trust_pkg
+
+ get bh = do
+ mod_name <- get bh
+ is_boot <- get bh
+ iface_hash <- get bh
+ mod_hash <- get bh
+ flag_hash <- get bh
+ orphan <- get bh
+ hasFamInsts <- get bh
+ deps <- lazyGet bh
+ usages <- {-# SCC "bin_usages" #-} lazyGet bh
+ exports <- {-# SCC "bin_exports" #-} get bh
+ exp_hash <- get bh
+ used_th <- get bh
+ fixities <- {-# SCC "bin_fixities" #-} get bh
+ warns <- {-# SCC "bin_warns" #-} lazyGet bh
+ anns <- {-# SCC "bin_anns" #-} lazyGet bh
+ decls <- {-# SCC "bin_tycldecls" #-} get bh
+ insts <- {-# SCC "bin_insts" #-} get bh
+ fam_insts <- {-# SCC "bin_fam_insts" #-} get bh
+ rules <- {-# SCC "bin_rules" #-} lazyGet bh
+ orphan_hash <- get bh
+ vect_info <- get bh
+ hpc_info <- get bh
+ trust <- get bh
+ trust_pkg <- get bh
+ return (ModIface {
+ mi_module = mod_name,
+ mi_boot = is_boot,
+ mi_iface_hash = iface_hash,
+ mi_mod_hash = mod_hash,
+ mi_flag_hash = flag_hash,
+ mi_orphan = orphan,
+ mi_finsts = hasFamInsts,
+ mi_deps = deps,
+ mi_usages = usages,
+ mi_exports = exports,
+ mi_exp_hash = exp_hash,
+ mi_used_th = used_th,
+ mi_anns = anns,
+ mi_fixities = fixities,
+ mi_warns = warns,
+ mi_decls = decls,
+ mi_globals = Nothing,
+ mi_insts = insts,
+ mi_fam_insts = fam_insts,
+ mi_rules = rules,
+ mi_orphan_hash = orphan_hash,
+ mi_vect_info = vect_info,
+ mi_hpc = hpc_info,
+ mi_trust = trust,
+ mi_trust_pkg = trust_pkg,
+ -- And build the cached values
+ mi_warn_fn = mkIfaceWarnCache warns,
+ mi_fix_fn = mkIfaceFixCache fixities,
+ mi_hash_fn = mkIfaceHashCache decls })
+
-- | The original names declared of a certain module that are exported
type IfaceExport = AvailInfo
@@ -777,7 +885,7 @@ data ModDetails
md_exports :: [AvailInfo],
md_types :: !TypeEnv, -- ^ Local type environment for this particular module
md_insts :: ![ClsInst], -- ^ 'DFunId's for the instances in this module
- md_fam_insts :: ![FamInst Branched],
+ md_fam_insts :: ![FamInst],
md_rules :: ![CoreRule], -- ^ Domain may include 'Id's from other modules
md_anns :: ![Annotation], -- ^ Annotations present in this module: currently
-- they only annotate things also declared in this module
@@ -823,7 +931,7 @@ data ModGuts
mg_tcs :: ![TyCon], -- ^ TyCons declared in this module
-- (includes TyCons for classes)
mg_insts :: ![ClsInst], -- ^ Class instances declared in this module
- mg_fam_insts :: ![FamInst Branched],
+ mg_fam_insts :: ![FamInst],
-- ^ Family instances declared in this module
mg_rules :: ![CoreRule], -- ^ Before the core pipeline starts, contains
-- See Note [Overall plumbing for rules] in Rules.lhs
@@ -953,7 +1061,7 @@ data InteractiveContext
-- ^ Variables defined automatically by the system (e.g.
-- record field selectors). See Notes [ic_sys_vars]
- ic_instances :: ([ClsInst], [FamInst Branched]),
+ ic_instances :: ([ClsInst], [FamInst]),
-- ^ All instances and family instances created during
-- this session. These are grabbed en masse after each
-- update to be sure that proper overlapping is retained.
@@ -1280,10 +1388,12 @@ implicitTyConThings tc
extras_plus :: TyThing -> [TyThing]
extras_plus thing = thing : implicitTyThings thing
--- For newtypes (only) add the implicit coercion tycon
+-- For newtypes and closed type families (only) add the implicit coercion tycon
implicitCoTyCon :: TyCon -> [TyThing]
implicitCoTyCon tc
| Just co <- newTyConCo_maybe tc = [ACoAxiom $ toBranchedAxiom co]
+ | Just co <- isClosedSynFamilyTyCon_maybe tc
+ = [ACoAxiom co]
| otherwise = []
-- | Returns @True@ if there should be no interface-file declaration
@@ -1379,12 +1489,12 @@ mkTypeEnvWithImplicits things =
`plusNameEnv`
mkTypeEnv (concatMap implicitTyThings things)
-typeEnvFromEntities :: [Id] -> [TyCon] -> [FamInst Branched] -> TypeEnv
+typeEnvFromEntities :: [Id] -> [TyCon] -> [FamInst] -> TypeEnv
typeEnvFromEntities ids tcs famInsts =
mkTypeEnv ( map AnId ids
++ map ATyCon all_tcs
++ concatMap implicitTyConThings all_tcs
- ++ map (ACoAxiom . famInstAxiom) famInsts
+ ++ map (ACoAxiom . toBranchedAxiom . famInstAxiom) famInsts
)
where
all_tcs = tcs ++ famInstsRepTyCons famInsts
@@ -1525,6 +1635,24 @@ data Warnings
-- a Name to its fixity declaration.
deriving( Eq )
+instance Binary Warnings where
+ put_ bh NoWarnings = putByte bh 0
+ put_ bh (WarnAll t) = do
+ putByte bh 1
+ put_ bh t
+ put_ bh (WarnSome ts) = do
+ putByte bh 2
+ put_ bh ts
+
+ get bh = do
+ h <- getByte bh
+ case h of
+ 0 -> return NoWarnings
+ 1 -> do aa <- get bh
+ return (WarnAll aa)
+ _ -> do aa <- get bh
+ return (WarnSome aa)
+
-- | Constructs the cache for the 'mi_warn_fn' field of a 'ModIface'
mkIfaceWarnCache :: Warnings -> Name -> Maybe WarningTxt
mkIfaceWarnCache NoWarnings = \_ -> Nothing
@@ -1623,6 +1751,19 @@ data Dependencies
-- Equality used only for old/new comparison in MkIface.addFingerprints
-- See 'TcRnTypes.ImportAvails' for details on dependencies.
+instance Binary Dependencies where
+ put_ bh deps = do put_ bh (dep_mods deps)
+ put_ bh (dep_pkgs deps)
+ put_ bh (dep_orphs deps)
+ put_ bh (dep_finsts deps)
+
+ get bh = do ms <- get bh
+ ps <- get bh
+ os <- get bh
+ fis <- get bh
+ return (Deps { dep_mods = ms, dep_pkgs = ps, dep_orphs = os,
+ dep_finsts = fis })
+
noDependencies :: Dependencies
noDependencies = Deps [] [] [] []
@@ -1671,6 +1812,49 @@ data Usage
-- import M()
-- And of course, for modules that aren't imported directly we don't
-- depend on their export lists
+
+instance Binary Usage where
+ put_ bh usg@UsagePackageModule{} = do
+ putByte bh 0
+ put_ bh (usg_mod usg)
+ put_ bh (usg_mod_hash usg)
+ put_ bh (usg_safe usg)
+
+ put_ bh usg@UsageHomeModule{} = do
+ putByte bh 1
+ put_ bh (usg_mod_name usg)
+ put_ bh (usg_mod_hash usg)
+ put_ bh (usg_exports usg)
+ put_ bh (usg_entities usg)
+ put_ bh (usg_safe usg)
+
+ put_ bh usg@UsageFile{} = do
+ putByte bh 2
+ put_ bh (usg_file_path usg)
+ put_ bh (usg_mtime usg)
+
+ get bh = do
+ h <- getByte bh
+ case h of
+ 0 -> do
+ nm <- get bh
+ mod <- get bh
+ safe <- get bh
+ return UsagePackageModule { usg_mod = nm, usg_mod_hash = mod, usg_safe = safe }
+ 1 -> do
+ nm <- get bh
+ mod <- get bh
+ exps <- get bh
+ ents <- get bh
+ safe <- get bh
+ return UsageHomeModule { usg_mod_name = nm, usg_mod_hash = mod,
+ usg_exports = exps, usg_entities = ents, usg_safe = safe }
+ 2 -> do
+ fp <- get bh
+ mtime <- get bh
+ return UsageFile { usg_file_path = fp, usg_mtime = mtime }
+ i -> error ("Binary.get(Usage): " ++ show i)
+
\end{code}
@@ -1796,6 +1980,9 @@ mkSOName platform root
OSMinGW32 -> root <.> "dll"
_ -> ("lib" ++ root) <.> "so"
+mkHsSOName :: Platform -> FilePath -> FilePath
+mkHsSOName platform root = ("lib" ++ root) <.> soExt platform
+
soExt :: Platform -> FilePath
soExt platform
= case platformOS platform of
@@ -2055,6 +2242,21 @@ instance Outputable VectInfo where
, ptext (sLit "parallel vars :") <+> ppr (vectInfoParallelVars info)
, ptext (sLit "parallel tycons :") <+> ppr (vectInfoParallelTyCons info)
]
+
+instance Binary IfaceVectInfo where
+ put_ bh (IfaceVectInfo a1 a2 a3 a4 a5) = do
+ put_ bh a1
+ put_ bh a2
+ put_ bh a3
+ put_ bh a4
+ put_ bh a5
+ get bh = do
+ a1 <- get bh
+ a2 <- get bh
+ a3 <- get bh
+ a4 <- get bh
+ a5 <- get bh
+ return (IfaceVectInfo a1 a2 a3 a4 a5)
\end{code}
%************************************************************************
@@ -2106,6 +2308,10 @@ instance Outputable IfaceTrustInfo where
ppr (TrustInfo Sf_Trustworthy) = ptext $ sLit "trustworthy"
ppr (TrustInfo Sf_Safe) = ptext $ sLit "safe"
ppr (TrustInfo Sf_SafeInferred) = ptext $ sLit "safe-inferred"
+
+instance Binary IfaceTrustInfo where
+ put_ bh iftrust = putByte bh $ trustInfoToNum iftrust
+ get bh = getByte bh >>= (return . numToTrustInfo)
\end{code}
%************************************************************************
diff --git a/compiler/main/InteractiveEval.hs b/compiler/main/InteractiveEval.hs
index 391de5a42f..635c194a92 100644
--- a/compiler/main/InteractiveEval.hs
+++ b/compiler/main/InteractiveEval.hs
@@ -45,7 +45,7 @@ import HscMain
import HsSyn
import HscTypes
import InstEnv
-import FamInstEnv ( FamInst, Branched, orphNamesOfFamInst )
+import FamInstEnv ( FamInst, orphNamesOfFamInst )
import TyCon
import Type hiding( typeKind )
import TcType hiding( typeKind )
@@ -890,7 +890,7 @@ moduleIsInterpreted modl = withSession $ \h ->
-- are in scope (qualified or otherwise). Otherwise we list a whole lot too many!
-- The exact choice of which ones to show, and which to hide, is a judgement call.
-- (see Trac #1581)
-getInfo :: GhcMonad m => Bool -> Name -> m (Maybe (TyThing,Fixity,[ClsInst],[FamInst Branched]))
+getInfo :: GhcMonad m => Bool -> Name -> m (Maybe (TyThing,Fixity,[ClsInst],[FamInst]))
getInfo allInfo name
= withSession $ \hsc_env ->
do mb_stuff <- liftIO $ hscTcRnGetInfo hsc_env name
diff --git a/compiler/main/Packages.lhs b/compiler/main/Packages.lhs
index 54d9d1b66b..cc8dfe3eb7 100644
--- a/compiler/main/Packages.lhs
+++ b/compiler/main/Packages.lhs
@@ -1039,13 +1039,24 @@ missingDependencyMsg (Just parent)
-- -----------------------------------------------------------------------------
-- | Will the 'Name' come from a dynamically linked library?
-isDllName :: DynFlags -> PackageId -> Name -> Bool
+isDllName :: DynFlags -> PackageId -> Module -> Name -> Bool
-- Despite the "dll", I think this function just means that
-- the synbol comes from another dynamically-linked package,
-- and applies on all platforms, not just Windows
-isDllName dflags this_pkg name
+isDllName dflags this_pkg this_mod name
| gopt Opt_Static dflags = False
- | Just mod <- nameModule_maybe name = modulePackageId mod /= this_pkg
+ | Just mod <- nameModule_maybe name
+ = if modulePackageId mod /= this_pkg
+ then True
+ else case dllSplit dflags of
+ Nothing -> False
+ Just ss ->
+ let findMod m = let modStr = moduleNameString (moduleName m)
+ in case find (modStr `Set.member`) ss of
+ Just i -> i
+ Nothing -> panic ("Can't find " ++ modStr ++ "in DLL split")
+ in findMod mod /= findMod this_mod
+
| otherwise = False -- no, it is not even an external name
-- -----------------------------------------------------------------------------
diff --git a/compiler/main/PprTyThing.hs b/compiler/main/PprTyThing.hs
index c14b853145..b95c69902a 100644
--- a/compiler/main/PprTyThing.hs
+++ b/compiler/main/PprTyThing.hs
@@ -29,9 +29,11 @@ import GHC ( TyThing(..) )
import DataCon
import Id
import TyCon
-import Coercion( pprCoAxiom )
+import Coercion( pprCoAxiom, pprCoAxBranch )
+import CoAxiom( CoAxiom(..), brListMap )
import HscTypes( tyThingParent_maybe )
import Type( tidyTopType, tidyOpenType )
+import TypeRep( pprTvBndrs )
import TcType
import Name
import VarEnv( emptyTidyEnv )
@@ -106,6 +108,7 @@ ppr_ty_thing pefas _ (AnId id) = pprId pefas id
ppr_ty_thing pefas _ (ADataCon dataCon) = pprDataConSig pefas dataCon
ppr_ty_thing pefas ss (ATyCon tyCon) = pprTyCon pefas ss tyCon
ppr_ty_thing _ _ (ACoAxiom ax) = pprCoAxiom ax
+
pprTyConHdr :: PrintExplicitForalls -> TyCon -> SDoc
pprTyConHdr pefas tyCon
| Just (fam_tc, tys) <- tyConFamInst_maybe tyCon
@@ -113,7 +116,7 @@ pprTyConHdr pefas tyCon
| Just cls <- tyConClass_maybe tyCon
= pprClassHdr pefas cls
| otherwise
- = ptext keyword <+> opt_family <+> opt_stupid <+> ppr_bndr tyCon <+> hsep (map ppr vars)
+ = ptext keyword <+> opt_family <+> opt_stupid <+> ppr_bndr tyCon <+> pprTvBndrs vars
where
vars | GHC.isPrimTyCon tyCon ||
GHC.isFunTyCon tyCon = take (GHC.tyConArity tyCon) GHC.alphaTyVars
@@ -138,10 +141,9 @@ pprDataConSig pefas dataCon
pprClassHdr :: PrintExplicitForalls -> GHC.Class -> SDoc
pprClassHdr _ cls
= ptext (sLit "class") <+>
- GHC.pprThetaArrowTy (GHC.classSCTheta cls) <+>
- ppr_bndr cls <+>
- hsep (map ppr tyVars) <+>
- GHC.pprFundeps funDeps
+ sep [ GHC.pprThetaArrowTy (GHC.classSCTheta cls)
+ , ppr_bndr cls <+> pprTvBndrs tyVars
+ , GHC.pprFundeps funDeps ]
where
(tyVars, funDeps) = GHC.classTvsFds cls
@@ -174,16 +176,25 @@ pprTyCon :: PrintExplicitForalls -> ShowSub -> TyCon -> SDoc
pprTyCon pefas ss tyCon
| Just syn_rhs <- GHC.synTyConRhs_maybe tyCon
= case syn_rhs of
- SynFamilyTyCon {} -> pprTyConHdr pefas tyCon <+> dcolon <+>
- pprTypeForUser pefas (GHC.synTyConResKind tyCon)
+ OpenSynFamilyTyCon -> pprTyConHdr pefas tyCon <+> dcolon <+>
+ pprTypeForUser pefas (GHC.synTyConResKind tyCon)
+ ClosedSynFamilyTyCon (CoAxiom { co_ax_branches = branches }) ->
+ hang closed_family_header
+ 2 (vcat (brListMap (pprCoAxBranch tyCon) branches))
+ AbstractClosedSynFamilyTyCon -> closed_family_header <+> ptext (sLit "..")
SynonymTyCon rhs_ty -> hang (pprTyConHdr pefas tyCon <+> equals)
- 2 (pprTypeForUser pefas rhs_ty)
-
+ 2 (ppr rhs_ty) -- Don't suppress foralls on RHS type!
+ -- e.g. type T = forall a. a->a
| Just cls <- GHC.tyConClass_maybe tyCon
= pprClass pefas ss cls
| otherwise
= pprAlgTyCon pefas ss tyCon
+ where
+ closed_family_header
+ = pprTyConHdr pefas tyCon <+> dcolon <+>
+ pprTypeForUser pefas (GHC.synTyConResKind tyCon) <+> ptext (sLit "where")
+
pprAlgTyCon :: PrintExplicitForalls -> ShowSub -> TyCon -> SDoc
pprAlgTyCon pefas ss tyCon
| gadt = pprTyConHdr pefas tyCon <+> ptext (sLit "where") $$
@@ -228,7 +239,7 @@ pprDataConDecl pefas ss gadt_style dataCon
user_ify bang = bang
maybe_show_label (lbl,bty)
- | showSub ss lbl = Just (ppr lbl <+> dcolon <+> pprBangTy bty)
+ | showSub ss lbl = Just (ppr_bndr lbl <+> dcolon <+> pprBangTy bty)
| otherwise = Nothing
ppr_fields [ty1, ty2]
diff --git a/compiler/main/StaticFlags.hs b/compiler/main/StaticFlags.hs
index c982d14b33..09d5772637 100644
--- a/compiler/main/StaticFlags.hs
+++ b/compiler/main/StaticFlags.hs
@@ -1,10 +1,3 @@
-{-# OPTIONS -fno-warn-tabs #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and
--- detab the module (please do the detabbing in a separate patch). See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#TabsvsSpaces
--- for details
-
{-# OPTIONS -fno-cse #-}
-- -fno-cse is needed for GLOBAL_VAR's to behave properly
@@ -23,27 +16,29 @@ module StaticFlags (
-- entry point
parseStaticFlags,
- staticFlags,
+ staticFlags,
initStaticOpts,
- -- Output style options
- opt_PprStyle_Debug,
+ -- Output style options
+ opt_PprStyle_Debug,
opt_NoDebugOutput,
- -- language opts
- opt_DictsStrict,
+ -- language opts
+ opt_DictsStrict,
- -- optimisation opts
- opt_NoStateHack,
- opt_CprOff,
- opt_NoOptCoercion,
- opt_NoFlatCache,
+ -- optimisation opts
+ opt_NoStateHack,
+ opt_CprOff,
+ opt_NoOptCoercion,
-- For the parser
addOpt, removeOpt, v_opt_C_ready,
-- Saving/restoring globals
- saveStaticFlagGlobals, restoreStaticFlagGlobals
+ saveStaticFlagGlobals, restoreStaticFlagGlobals,
+
+ -- For options autocompletion
+ flagsStatic, flagsStaticNames
) where
#include "HsVersions.h"
@@ -52,13 +47,13 @@ import CmdLineParser
import FastString
import SrcLoc
import Util
--- import Maybes ( firstJusts )
+-- import Maybes ( firstJusts )
import Panic
import Control.Monad
import Data.Char
import Data.IORef
-import System.IO.Unsafe ( unsafePerformIO )
+import System.IO.Unsafe ( unsafePerformIO )
-----------------------------------------------------------------------------
@@ -114,7 +109,7 @@ staticFlags = unsafePerformIO $ do
-- All the static flags should appear in this list. It describes how each
-- static flag should be processed. Two main purposes:
-- (a) if a command-line flag doesn't appear in the list, GHC can complain
--- (b) a command-line flag may remove, or add, other flags; e.g. the "-fno-X"
+-- (b) a command-line flag may remove, or add, other flags; e.g. the "-fno-X"
-- things
--
-- The common (PassFlag addOpt) action puts the static flag into the bunch of
@@ -147,18 +142,16 @@ flagsStatic = [
]
+
isStaticFlag :: String -> Bool
-isStaticFlag f =
- f `elem` [
+isStaticFlag f = f `elem` flagsStaticNames
+
+
+flagsStaticNames :: [String]
+flagsStaticNames = [
"fdicts-strict",
- "fspec-inline-join-points",
- "fno-hi-version-check",
- "dno-black-holing",
"fno-state-hack",
- "fruntime-types",
"fno-opt-coercion",
- "fno-flat-cache",
- "fhardwire-lib-paths",
"fcpr-off"
]
@@ -198,10 +191,10 @@ opt_NoDebugOutput = lookUp (fsLit "-dno-debug-output")
-- language opts
opt_DictsStrict :: Bool
-opt_DictsStrict = lookUp (fsLit "-fdicts-strict")
+opt_DictsStrict = lookUp (fsLit "-fdicts-strict")
opt_NoStateHack :: Bool
-opt_NoStateHack = lookUp (fsLit "-fno-state-hack")
+opt_NoStateHack = lookUp (fsLit "-fno-state-hack")
-- Switch off CPR analysis in the new demand analyser
opt_CprOff :: Bool
@@ -210,9 +203,6 @@ opt_CprOff = lookUp (fsLit "-fcpr-off")
opt_NoOptCoercion :: Bool
opt_NoOptCoercion = lookUp (fsLit "-fno-opt-coercion")
-opt_NoFlatCache :: Bool
-opt_NoFlatCache = lookUp (fsLit "-fno-flat-cache")
-
-----------------------------------------------------------------------------
-- Convert sizes like "3.5M" into integers
@@ -254,45 +244,28 @@ foreign import ccall unsafe "enableTimingStats" enableTimingStats :: IO ()
lookup_str :: String -> Maybe String
lookup_str sw
= case firstJusts (map (stripPrefix sw) staticFlags) of
- Just ('=' : str) -> Just str
- Just str -> Just str
- Nothing -> Nothing
+ Just ('=' : str) -> Just str
+ Just str -> Just str
+ Nothing -> Nothing
lookup_def_int :: String -> Int -> Int
lookup_def_int sw def = case (lookup_str sw) of
- Nothing -> def -- Use default
- Just xx -> try_read sw xx
+ Nothing -> def -- Use default
+ Just xx -> try_read sw xx
lookup_def_float :: String -> Float -> Float
lookup_def_float sw def = case (lookup_str sw) of
- Nothing -> def -- Use default
- Just xx -> try_read sw xx
+ Nothing -> def -- Use default
+ Just xx -> try_read sw xx
try_read :: Read a => String -> String -> a
-- (try_read sw str) tries to read s; if it fails, it
-- bleats about flag sw
try_read sw str
= case reads str of
- ((x,_):_) -> x -- Be forgiving: ignore trailing goop, and alternative parses
- [] -> throwGhcException (UsageError ("Malformed argument " ++ str ++ " for flag " ++ sw))
- -- ToDo: hack alert. We should really parse the arguments
- -- and announce errors in a more civilised way.
--}
-
-
-{-
- Putting the compiler options into temporary at-files
- may turn out to be necessary later on if we turn hsc into
- a pure Win32 application where I think there's a command-line
- length limit of 255. unpacked_opts understands the @ option.
-
-unpacked_opts :: [String]
-unpacked_opts =
- concat $
- map (expandAts) $
- map unpackFS argv -- NOT ARGV any more: v_Static_hsc_opts
- where
- expandAts ('@':fname) = words (unsafePerformIO (readFile fname))
- expandAts l = [l]
+ ((x,_):_) -> x -- Be forgiving: ignore trailing goop, and alternative parses
+ [] -> throwGhcException (UsageError ("Malformed argument " ++ str ++ " for flag " ++ sw))
+ -- ToDo: hack alert. We should really parse the arguments
+ -- and announce errors in a more civilised way.
-}
diff --git a/compiler/main/SysTools.lhs b/compiler/main/SysTools.lhs
index bacd53e937..d43826a046 100644
--- a/compiler/main/SysTools.lhs
+++ b/compiler/main/SysTools.lhs
@@ -24,6 +24,8 @@ module SysTools (
figureLlvmVersion,
readElfSection,
+ getLinkerInfo,
+
linkDynLib,
askCc,
@@ -371,30 +373,35 @@ findTopDir Nothing
\begin{code}
runUnlit :: DynFlags -> [Option] -> IO ()
runUnlit dflags args = do
- let p = pgm_L dflags
- runSomething dflags "Literate pre-processor" p args
+ let prog = pgm_L dflags
+ opts = getOpts dflags opt_L
+ runSomething dflags "Literate pre-processor" prog
+ (map Option opts ++ args)
runCpp :: DynFlags -> [Option] -> IO ()
runCpp dflags args = do
let (p,args0) = pgm_P dflags
- args1 = args0 ++ args
+ args1 = map Option (getOpts dflags opt_P)
args2 = if gopt Opt_WarnIsError dflags
- then Option "-Werror" : args1
- else args1
+ then [Option "-Werror"]
+ else []
mb_env <- getGccEnv args2
- runSomethingFiltered dflags id "C pre-processor" p args2 mb_env
+ runSomethingFiltered dflags id "C pre-processor" p
+ (args0 ++ args1 ++ args2 ++ args) mb_env
runPp :: DynFlags -> [Option] -> IO ()
runPp dflags args = do
- let p = pgm_F dflags
- runSomething dflags "Haskell pre-processor" p args
+ let prog = pgm_F dflags
+ opts = map Option (getOpts dflags opt_F)
+ runSomething dflags "Haskell pre-processor" prog (opts ++ args)
runCc :: DynFlags -> [Option] -> IO ()
runCc dflags args = do
let (p,args0) = pgm_c dflags
- args1 = args0 ++ args
- mb_env <- getGccEnv args1
- runSomethingFiltered dflags cc_filter "C Compiler" p args1 mb_env
+ args1 = map Option (getOpts dflags opt_c)
+ args2 = args0 ++ args1 ++ args
+ mb_env <- getGccEnv args2
+ runSomethingFiltered dflags cc_filter "C Compiler" p args2 mb_env
where
-- discard some harmless warnings from gcc that we can't turn off
cc_filter = unlines . doFilter . lines
@@ -452,9 +459,10 @@ xs `isContainedIn` ys = any (xs `isPrefixOf`) (tails ys)
askCc :: DynFlags -> [Option] -> IO String
askCc dflags args = do
let (p,args0) = pgm_c dflags
- args1 = args0 ++ args
- mb_env <- getGccEnv args1
- runSomethingWith dflags "gcc" p args1 $ \real_args ->
+ args1 = map Option (getOpts dflags opt_c)
+ args2 = args0 ++ args1 ++ args
+ mb_env <- getGccEnv args2
+ runSomethingWith dflags "gcc" p args2 $ \real_args ->
readCreateProcess (proc p real_args){ env = mb_env }
-- Version of System.Process.readProcessWithExitCode that takes an environment
@@ -507,21 +515,24 @@ runSplit dflags args = do
runAs :: DynFlags -> [Option] -> IO ()
runAs dflags args = do
let (p,args0) = pgm_a dflags
- args1 = args0 ++ args
- mb_env <- getGccEnv args1
- runSomethingFiltered dflags id "Assembler" p args1 mb_env
+ args1 = map Option (getOpts dflags opt_a)
+ args2 = args0 ++ args1 ++ args
+ mb_env <- getGccEnv args2
+ runSomethingFiltered dflags id "Assembler" p args2 mb_env
-- | Run the LLVM Optimiser
runLlvmOpt :: DynFlags -> [Option] -> IO ()
runLlvmOpt dflags args = do
let (p,args0) = pgm_lo dflags
- runSomething dflags "LLVM Optimiser" p (args0++args)
+ args1 = map Option (getOpts dflags opt_lo)
+ runSomething dflags "LLVM Optimiser" p (args0 ++ args1 ++ args)
-- | Run the LLVM Compiler
runLlvmLlc :: DynFlags -> [Option] -> IO ()
runLlvmLlc dflags args = do
let (p,args0) = pgm_lc dflags
- runSomething dflags "LLVM Compiler" p (args0++args)
+ args1 = map Option (getOpts dflags opt_lc)
+ runSomething dflags "LLVM Compiler" p (args0 ++ args1 ++ args)
-- | Run the clang compiler (used as an assembler for the LLVM
-- backend on OS X as LLVM doesn't support the OS X system
@@ -533,10 +544,11 @@ runClang dflags args = do
-- be careful what options we call clang with
-- see #5903 and #7617 for bugs caused by this.
(_,args0) = pgm_a dflags
- args1 = args0 ++ args
- mb_env <- getGccEnv args1
+ args1 = map Option (getOpts dflags opt_a)
+ args2 = args0 ++ args1 ++ args
+ mb_env <- getGccEnv args2
Exception.catch (do
- runSomethingFiltered dflags id "Clang (Assembler)" clang args1 mb_env
+ runSomethingFiltered dflags id "Clang (Assembler)" clang args2 mb_env
)
(\(err :: SomeException) -> do
errorMsg dflags $
@@ -586,14 +598,124 @@ figureLlvmVersion dflags = do
text "Make sure you have installed LLVM"]
return Nothing)
return ver
-
+
+
+{- Note [Run-time linker info]
+
+See also: Trac #5240, Trac #6063
+
+Before 'runLink', we need to be sure to get the relevant information
+about the linker we're using at runtime to see if we need any extra
+options. For example, GNU ld requires '--reduce-memory-overheads' and
+'--hash-size=31' in order to use reasonable amounts of memory (see
+trac #5240.) But this isn't supported in GNU gold.
+
+Generally, the linker changing from what was detected at ./configure
+time has always been possible using -pgml, but on Linux it can happen
+'transparently' by installing packages like binutils-gold, which
+change what /usr/bin/ld actually points to.
+
+Clang vs GCC notes:
+
+For gcc, 'gcc -Wl,--version' gives a bunch of output about how to
+invoke the linker before the version information string. For 'clang',
+the version information for 'ld' is all that's output. For this
+reason, we typically need to slurp up all of the standard error output
+and look through it.
+
+Other notes:
+
+We cache the LinkerInfo inside DynFlags, since clients may link
+multiple times. The definition of LinkerInfo is there to avoid a
+circular dependency.
+
+-}
+
+
+neededLinkArgs :: LinkerInfo -> [Option]
+neededLinkArgs (GnuLD o) = o
+neededLinkArgs (GnuGold o) = o
+neededLinkArgs (DarwinLD o) = o
+neededLinkArgs UnknownLD = []
+
+-- Grab linker info and cache it in DynFlags.
+getLinkerInfo :: DynFlags -> IO LinkerInfo
+getLinkerInfo dflags = do
+ info <- readIORef (rtldFlags dflags)
+ case info of
+ Just v -> return v
+ Nothing -> do
+ v <- getLinkerInfo' dflags
+ writeIORef (rtldFlags dflags) (Just v)
+ return v
+
+-- See Note [Run-time linker info].
+getLinkerInfo' :: DynFlags -> IO LinkerInfo
+getLinkerInfo' dflags = do
+ let platform = targetPlatform dflags
+ os = platformOS platform
+ (pgm,_) = pgm_l dflags
+
+ -- Try to grab the info from the process output.
+ parseLinkerInfo stdo _stde _exitc
+ | any ("GNU ld" `isPrefixOf`) stdo =
+ -- GNU ld specifically needs to use less memory. This especially
+ -- hurts on small object files. Trac #5240.
+ return (GnuLD $ map Option ["-Wl,--hash-size=31",
+ "-Wl,--reduce-memory-overheads"])
+
+ | any ("GNU gold" `isPrefixOf`) stdo =
+ -- GNU gold does not require any special arguments.
+ return (GnuGold [])
+
+ -- Unknown linker.
+ | otherwise = fail "invalid --version output, or linker is unsupported"
+
+ -- Process the executable call
+ info <- catchIO (do
+ case os of
+ OSDarwin ->
+ -- Darwin has neither GNU Gold or GNU LD, but a strange linker
+ -- that doesn't support --version. We can just assume that's
+ -- what we're using.
+ return $ DarwinLD []
+ OSMinGW32 ->
+ -- GHC doesn't support anything but GNU ld on Windows anyway.
+ -- Process creation is also fairly expensive on win32, so
+ -- we short-circuit here.
+ return $ GnuLD $ map Option ["-Wl,--hash-size=31",
+ "-Wl,--reduce-memory-overheads"]
+ _ -> do
+ -- In practice, we use the compiler as the linker here. Pass
+ -- -Wl,--version to get linker version info.
+ (exitc, stdo, stde) <- readProcessWithExitCode pgm
+ ["-Wl,--version"] ""
+ -- Split the output by lines to make certain kinds
+ -- of processing easier. In particular, 'clang' and 'gcc'
+ -- have slightly different outputs for '-Wl,--version', but
+ -- it's still easy to figure out.
+ parseLinkerInfo (lines stdo) (lines stde) exitc
+ )
+ (\err -> do
+ debugTraceMsg dflags 2
+ (text "Error (figuring out linker information):" <+>
+ text (show err))
+ errorMsg dflags $ hang (text "Warning:") 9 $
+ text "Couldn't figure out linker information!" $$
+ text "Make sure you're using GNU ld, GNU gold" <+>
+ text "or the built in OS X linker, etc."
+ return UnknownLD)
+ return info
runLink :: DynFlags -> [Option] -> IO ()
runLink dflags args = do
+ -- See Note [Run-time linker info]
+ linkargs <- neededLinkArgs `fmap` getLinkerInfo dflags
let (p,args0) = pgm_l dflags
- args1 = args0 ++ args
- mb_env <- getGccEnv args1
- runSomethingFiltered dflags id "Linker" p args1 mb_env
+ args1 = map Option (getOpts dflags opt_l)
+ args2 = args0 ++ args1 ++ args ++ linkargs
+ mb_env <- getGccEnv args2
+ runSomethingFiltered dflags id "Linker" p args2 mb_env
runMkDLL :: DynFlags -> [Option] -> IO ()
runMkDLL dflags args = do
@@ -606,6 +728,7 @@ runWindres :: DynFlags -> [Option] -> IO ()
runWindres dflags args = do
let (gcc, gcc_args) = pgm_c dflags
windres = pgm_windres dflags
+ opts = map Option (getOpts dflags opt_windres)
quote x = "\"" ++ x ++ "\""
args' = -- If windres.exe and gcc.exe are in a directory containing
-- spaces then windres fails to run gcc. We therefore need
@@ -613,6 +736,7 @@ runWindres dflags args = do
Option ("--preprocessor=" ++
unwords (map quote (gcc :
map showOpt gcc_args ++
+ map showOpt opts ++
["-E", "-xc", "-DRC_INVOKED"])))
-- ...but if we do that then if windres calls popen then
-- it can't understand the quoting, so we have to use
@@ -1051,10 +1175,22 @@ linesPlatform xs =
#endif
linkDynLib :: DynFlags -> [String] -> [PackageId] -> IO ()
-linkDynLib dflags o_files dep_packages
+linkDynLib dflags0 o_files dep_packages
= do
- let verbFlags = getVerbFlags dflags
- let o_file = outputFile dflags
+ let -- This is a rather ugly hack to fix dynamically linked
+ -- GHC on Windows. If GHC is linked with -threaded, then
+ -- it links against libHSrts_thr. But if base is linked
+ -- against libHSrts, then both end up getting loaded,
+ -- and things go wrong. We therefore link the libraries
+ -- with the same RTS flags that we link GHC with.
+ dflags1 = if cGhcThreaded then addWay' WayThreaded dflags0
+ else dflags0
+ dflags2 = if cGhcDebugged then addWay' WayDebug dflags1
+ else dflags1
+ dflags = updateWays dflags2
+
+ verbFlags = getVerbFlags dflags
+ o_file = outputFile dflags
pkgs <- getPreloadPackagesAnd dflags dep_packages
@@ -1089,8 +1225,6 @@ linkDynLib dflags o_files dep_packages
-- probably _stub.o files
let extra_ld_inputs = ldInputs dflags
- let extra_ld_opts = getOpts dflags opt_l
-
case os of
OSMinGW32 -> do
-------------------------------------------------------------
@@ -1110,15 +1244,14 @@ linkDynLib dflags o_files dep_packages
| gopt Opt_SharedImplib dflags
]
++ map (FileOption "") o_files
- ++ map Option (
-- Permit the linker to auto link _symbol to _imp_symbol
-- This lets us link against DLLs without needing an "import library"
- ["-Wl,--enable-auto-import"]
+ ++ [Option "-Wl,--enable-auto-import"]
++ extra_ld_inputs
- ++ lib_path_opts
- ++ extra_ld_opts
+ ++ map Option (
+ lib_path_opts
++ pkg_lib_path_opts
++ pkg_link_opts
))
@@ -1169,19 +1302,19 @@ linkDynLib dflags o_files dep_packages
, Option "-o"
, FileOption "" output_fn
]
- ++ map Option (
- o_files
- ++ [ "-undefined", "dynamic_lookup", "-single_module" ]
+ ++ map Option o_files
+ ++ [ Option "-undefined",
+ Option "dynamic_lookup",
+ Option "-single_module" ]
++ (if platformArch platform == ArchX86_64
then [ ]
- else [ "-Wl,-read_only_relocs,suppress" ])
- ++ [ "-install_name", instName ]
+ else [ Option "-Wl,-read_only_relocs,suppress" ])
+ ++ [ Option "-install_name", Option instName ]
+ ++ map Option lib_path_opts
++ extra_ld_inputs
- ++ lib_path_opts
- ++ extra_ld_opts
- ++ pkg_lib_path_opts
- ++ pkg_link_opts
- ))
+ ++ map Option pkg_lib_path_opts
+ ++ map Option pkg_link_opts
+ )
_ -> do
-------------------------------------------------------------------
-- Making a DSO
@@ -1202,18 +1335,15 @@ linkDynLib dflags o_files dep_packages
++ [ Option "-o"
, FileOption "" output_fn
]
- ++ map Option (
- o_files
- ++ [ "-shared" ]
- ++ bsymbolicFlag
+ ++ map Option o_files
+ ++ [ Option "-shared" ]
+ ++ map Option bsymbolicFlag
-- Set the library soname. We use -h rather than -soname as
-- Solaris 10 doesn't support the latter:
- ++ [ "-Wl,-h," ++ takeFileName output_fn ]
+ ++ [ Option ("-Wl,-h," ++ takeFileName output_fn) ]
+ ++ map Option lib_path_opts
++ extra_ld_inputs
- ++ lib_path_opts
- ++ extra_ld_opts
- ++ pkg_lib_path_opts
- ++ pkg_link_opts
- ))
-
+ ++ map Option pkg_lib_path_opts
+ ++ map Option pkg_link_opts
+ )
\end{code}
diff --git a/compiler/main/TidyPgm.lhs b/compiler/main/TidyPgm.lhs
index 8d152d78fe..7b3695dbed 100644
--- a/compiler/main/TidyPgm.lhs
+++ b/compiler/main/TidyPgm.lhs
@@ -36,7 +36,6 @@ import Name hiding (varName)
import NameSet
import NameEnv
import Avail
-import PrelNames
import IfaceEnv
import TcEnv
import TcRnMonad
@@ -153,7 +152,7 @@ mkBootModDetailsTc hsc_env
}
where
-mkBootTypeEnv :: NameSet -> [Id] -> [TyCon] -> [FamInst Branched] -> TypeEnv
+mkBootTypeEnv :: NameSet -> [Id] -> [TyCon] -> [FamInst] -> TypeEnv
mkBootTypeEnv exports ids tcs fam_insts
= tidyTypeEnv True $
typeEnvFromEntities final_ids tcs fam_insts
@@ -328,7 +327,7 @@ tidyProgram hsc_env (ModGuts { mg_module = mod
-- See Note [Which rules to expose]
; (tidy_env, tidy_binds)
- <- tidyTopBinds hsc_env unfold_env tidy_occ_env binds
+ <- tidyTopBinds hsc_env mod unfold_env tidy_occ_env binds
; let { final_ids = [ id | id <- bindersOfBinds tidy_binds,
isExternalName (idName id)]
@@ -818,7 +817,8 @@ dffvLetBndr vanilla_unfold id
| otherwise -> return ()
_ -> dffvExpr rhs
- go_unf (DFunUnfolding _ _ args) = mapM_ dffvExpr (dfunArgExprs args)
+ go_unf (DFunUnfolding { df_bndrs = bndrs, df_args = args })
+ = extendScopeList bndrs $ mapM_ dffvExpr args
go_unf _ = return ()
go_rule (BuiltinRule {}) = return ()
@@ -974,14 +974,14 @@ rules are externalised (see init_ext_ids in function
-- * subst_env: A Var->Var mapping that substitutes the new Var for the old
tidyTopBinds :: HscEnv
+ -> Module
-> UnfoldEnv
-> TidyOccEnv
-> CoreProgram
-> IO (TidyEnv, CoreProgram)
-tidyTopBinds hsc_env unfold_env init_occ_env binds
- = do mkIntegerId <- liftM tyThingId
- $ initTcForLookup hsc_env (tcLookupGlobal mkIntegerName)
+tidyTopBinds hsc_env this_mod unfold_env init_occ_env binds
+ = do mkIntegerId <- lookupMkIntegerName dflags hsc_env
return $ tidy mkIntegerId init_env binds
where
dflags = hsc_dflags hsc_env
@@ -991,7 +991,7 @@ tidyTopBinds hsc_env unfold_env init_occ_env binds
this_pkg = thisPackage dflags
tidy _ env [] = (env, [])
- tidy mkIntegerId env (b:bs) = let (env1, b') = tidyTopBind dflags this_pkg mkIntegerId unfold_env env b
+ tidy mkIntegerId env (b:bs) = let (env1, b') = tidyTopBind dflags this_pkg this_mod mkIntegerId unfold_env env b
(env2, bs') = tidy mkIntegerId env1 bs
in
(env2, b':bs')
@@ -999,22 +999,23 @@ tidyTopBinds hsc_env unfold_env init_occ_env binds
------------------------
tidyTopBind :: DynFlags
-> PackageId
+ -> Module
-> Id
-> UnfoldEnv
-> TidyEnv
-> CoreBind
-> (TidyEnv, CoreBind)
-tidyTopBind dflags this_pkg mkIntegerId unfold_env (occ_env,subst1) (NonRec bndr rhs)
+tidyTopBind dflags this_pkg this_mod mkIntegerId unfold_env (occ_env,subst1) (NonRec bndr rhs)
= (tidy_env2, NonRec bndr' rhs')
where
Just (name',show_unfold) = lookupVarEnv unfold_env bndr
- caf_info = hasCafRefs dflags this_pkg (mkIntegerId, subst1) (idArity bndr) rhs
+ caf_info = hasCafRefs dflags this_pkg this_mod (mkIntegerId, subst1) (idArity bndr) rhs
(bndr', rhs') = tidyTopPair dflags show_unfold tidy_env2 caf_info name' (bndr, rhs)
subst2 = extendVarEnv subst1 bndr bndr'
tidy_env2 = (occ_env, subst2)
-tidyTopBind dflags this_pkg mkIntegerId unfold_env (occ_env,subst1) (Rec prs)
+tidyTopBind dflags this_pkg this_mod mkIntegerId unfold_env (occ_env,subst1) (Rec prs)
= (tidy_env2, Rec prs')
where
prs' = [ tidyTopPair dflags show_unfold tidy_env2 caf_info name' (id,rhs)
@@ -1031,7 +1032,7 @@ tidyTopBind dflags this_pkg mkIntegerId unfold_env (occ_env,subst1) (Rec prs)
-- the CafInfo for a recursive group says whether *any* rhs in
-- the group may refer indirectly to a CAF (because then, they all do).
caf_info
- | or [ mayHaveCafRefs (hasCafRefs dflags this_pkg (mkIntegerId, subst1) (idArity bndr) rhs)
+ | or [ mayHaveCafRefs (hasCafRefs dflags this_pkg this_mod (mkIntegerId, subst1) (idArity bndr) rhs)
| (bndr,rhs) <- prs ] = MayHaveCafRefs
| otherwise = NoCafRefs
@@ -1167,14 +1168,15 @@ it as a CAF. In these cases however, we would need to use an additional
CAF list to keep track of non-collectable CAFs.
\begin{code}
-hasCafRefs :: DynFlags -> PackageId -> (Id, VarEnv Var) -> Arity -> CoreExpr
+hasCafRefs :: DynFlags -> PackageId -> Module
+ -> (Id, VarEnv Var) -> Arity -> CoreExpr
-> CafInfo
-hasCafRefs dflags this_pkg p arity expr
+hasCafRefs dflags this_pkg this_mod p arity expr
| is_caf || mentions_cafs = MayHaveCafRefs
| otherwise = NoCafRefs
where
mentions_cafs = isFastTrue (cafRefsE dflags p expr)
- is_dynamic_name = isDllName dflags this_pkg
+ is_dynamic_name = isDllName dflags this_pkg this_mod
is_caf = not (arity > 0 || rhsIsStatic (targetPlatform dflags) is_dynamic_name expr)
-- NB. we pass in the arity of the expression, which is expected