X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fdriver%2Fghc.lprl;h=6296b9162e3093c31acbe045f926ad2d018fd118;hb=2cb98454fa20db638b7707afa9fbbe93e623ba4c;hp=0e8a3f29b4297b8d5a55a9bb0708c0b3bf509bab;hpb=efda107644789f0af205152cff0cfcd4ed443e7c;p=ghc-hetmet.git diff --git a/ghc/driver/ghc.lprl b/ghc/driver/ghc.lprl index 0e8a3f2..6296b91 100644 --- a/ghc/driver/ghc.lprl +++ b/ghc/driver/ghc.lprl @@ -46,8 +46,8 @@ to stdout or stderr, however). The phase at which to STOP processing is determined by a command-line option: + -E stop after generating preprocessed, de-litted Haskell (used in conjunction with -cpp) -C stop after generating C (.hc output) - -E stop after generating preprocessed C (.i output) -S stop after generating assembler (.s output) -c stop after generating object files (.o output) @@ -64,9 +64,9 @@ Other commonly-used options are: -M Output the Makefile rules recording the dependencies of a list of Haskell files. - (ghc driver just calls upon the help of a - compatible mkdependHS script to do the - actual processing) + (ghc driver script calls upon the help of a + compatible mkdependHS script to do the actual + processing) The User's Guide has more information about GHC's *many* options. @@ -99,11 +99,11 @@ INSTALLING HOSTPLATFORM TARGETPLATFORM -PROJECTNAME PROJECTVERSION PROJECTPATCHLEVEL +ProjectName ProjectVersion ProjectVersionInt ProjectPatchLevel TOP_PWD -bindir libdir datadir +bindir libdir libexecdir datadir CURRENT_DIR TMPDIR @@ -129,11 +129,15 @@ select(STDERR); $| = 1; select(STDOUT); # no STDERR buffering, please. $TargetPlatform = $TARGETPLATFORM; -$TopPwd = "${TOP_PWD}"; -$InstBinDirGhc = "${bindir}"; -$InstLibDirGhc = "${libdir}"; -$InstDataDirGhc = "${datadir}"; -$InstSysLibDir = ( $INSTALLING ) ? "${InstLibDirGhc}/hslibs" : "$TopPwd/hslibs"; +$TopPwd = "${TOP_PWD}"; +$InstBinDirGhc = "${bindir}"; +$InstLibDirGhc = "${libdir}"; +# +# Normally the same as InstLibDirGhc, but we accommodate +# for it being separate. +# +$InstLibExecDirGhc = "${libexecdir}"; +$InstDataDirGhc = "${datadir}"; $Status = 0; # just used for exit() status $Verbose = ''; @@ -156,9 +160,26 @@ if ( $ENV{'TMPDIR'} ) { # where to make tmp file names $ENV{'TMPDIR'} = ${TMPDIR}; # set the env var as well } +# Some shells run into real trouble when command line and environment +# gets big (e.g., cmd lines of >4K to /bin/sh causes havoc on our +# Solaris-2.5.1 boxes - even though sysconf(_SC_ARG_MAX) reports 1M ...). +# To work around any such */bin/sh* problems, we will scribble such +# awfully long command lines into a temp file and exec that temp file +# with $(REAL_SHELL) (don't use the SHELL variable directly as this +# will normally get you the wrong thing when the driver is invoked +# from within `make'). If the REAL_SHELL variable isn't set, you'll +# get SHELL. This is all a terrible hack. (in case you hadn't reached +# the same conclusion by now :-) +# +# TBC.. +# +if ( ! $ENV{'REAL_SHELL'} ) { + $ENV{'REAL_SHELL'} = $ENV{'SHELL'}; +} + @Files_to_tidy = (); # files we nuke in the case of abnormal termination -$Unlit = ( $INSTALLING ) ? "$InstLibDirGhc/unlit" +$Unlit = ( $INSTALLING ) ? "$InstLibExecDirGhc/unlit" : "$TopPwd/${CURRENT_DIR}/${GHC_UNLIT}"; $Cp = $CP; @@ -169,16 +190,16 @@ $Cmp = 'cmp'; $Time = ''; $HsCpp = # but this is re-set to "cat" (after options) if -cpp not seen - ( $INSTALLING ) ? "$InstLibDirGhc/hscpp" + ( $INSTALLING ) ? "$InstLibExecDirGhc/hscpp" : "$TopPwd/${CURRENT_DIR}/${GHC_HSCPP}"; @HsCpp_flags = (); $genSPECS_flag = ''; # See ../utils/hscpp/hscpp.prl -$HsC = ( $INSTALLING ) ? "$InstLibDirGhc/hsc" +$HsC = ( $INSTALLING ) ? "$InstLibExecDirGhc/hsc" : "$TopPwd/${CURRENT_DIR}/${GHC_HSC}"; # For PVM fiends only -$SysMan = ( $INSTALLING ) ? "$InstLibDirGhc/SysMan" +$SysMan = ( $INSTALLING ) ? "$InstLibExecDirGhc/SysMan" : "$TopPwd/${CURRENT_DIR}/${GHC_SYSMAN}"; @Unlit_flags = (); @@ -207,11 +228,12 @@ sub setupOptFlags { $Oopt_FinalStgProfilingMassage = ''; $Oopt_StgStats = ''; $Oopt_SpecialiseUnboxed = ''; - $Oopt_DoSpecialise = ''; # ToDo:LATER: '-fspecialise'; + $Oopt_DoSpecialise = '-fspecialise'; $Oopt_FoldrBuild = 0; # *Off* by default! $Oopt_FB_Support = ''; # was '-fdo-arity-expand'; # $Oopt_FoldrBuildWW = 0; # Off by default $Oopt_FoldrBuildInline = ''; # was '-fdo-inline-foldr-build'; + $Oopt_ShowSimplifierProgress = ''; } # end of setupOptFlags # Assign defaults to these right away. @@ -244,7 +266,30 @@ $Lnkr = ''; # "linker" is normally GCC $Nm = ($TargetPlatform =~ /^alpha-/) ? 'nm -B' : 'nm'; \end{code} +Warning packages that are controlled by -W and -Wall. The 'standard' +warnings that you get all the time are + + -fwarn-overlapping-patterns + -fwarn-missing-methods + -fwarn-duplicate-exports + +these are turned off by -Wnot. + +\begin{code} +@StandardWarnings = ('-fwarn-overlapping-patterns', + '-fwarn-missing-methods', + '-fwarn-duplicate-exports'); +@MinusWOpts = (@StandardWarnings, + '-fwarn-incomplete-patterns', + '-fwarn-unused-binds', + '-fwarn-unused-imports'); +@MinusWallOpts = (@MinusWOpts, + '-fwarn-unused-matches', + '-fwarn-name-shadowing'); +\end{code} + What options \tr{-user-setup-a} turn into (user-defined ``packages'' + of options). Note that a particular user-setup implies a particular Prelude ({\em including} its interface file(s)). \begin{code} @@ -317,75 +362,6 @@ $BuildTag = ''; # default is sequential build w/ Appel-style GC '_1s', "$WAY_1s_HC_OPTS", '_du', "$WAY_B_HC_OPTS" ); -# per-build code fragments which are eval'd -#%EvaldSetupOpts = ('', '', # this one must *not* be set! - -# # profiled sequential -# '_p', 'push(@HsC_flags, \'-fscc-profiling\'); -# push(@CcBoth_flags, \'-DPROFILING\');', - -# #and maybe ... -# #push(@CcBoth_flags, '-DPROFILING_DETAIL_COUNTS'); - -# # ticky-ticky sequential -# '_t', 'push(@HsC_flags, \'-fticky-ticky\'); -# push(@CcBoth_flags, \'-DTICKY_TICKY\');', - -##OLD: # unregisterized (ToDo????) -## '_u', '', - -# # concurrent -# '_mc', '$StkChkByPageFaultOK = 0; -# push(@HsC_flags, \'-fconcurrent\'); -# push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\'); -# push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\');', - -# # profiled concurrent -# '_mr', '$StkChkByPageFaultOK = 0; -# push(@HsC_flags, \'-fconcurrent\', \'-fscc-profiling\'); -# push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\'); -# push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DPROFILING\');', - -# # ticky-ticky concurrent -# '_mt', '$StkChkByPageFaultOK = 0; -# push(@HsC_flags, \'-fconcurrent\', \'-fticky-ticky\'); -# push(@HsCpp_flags,\'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\'); -# push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DTICKY_TICKY\');', - -# # parallel -# '_mp', '$StkChkByPageFaultOK = 0; -# push(@HsC_flags, \'-fconcurrent\'); -# push(@HsCpp_flags,\'-D__PARALLEL_HASKELL__\', \'-DPAR\'); -# push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DPAR\');', - -# # GranSim -# '_mg', '$StkChkByPageFaultOK = 0; -# push(@HsC_flags, \'-fconcurrent\', \'-fgransim\'); -# push(@HsCpp_flags,\'-D__GRANSIM__\', \'-DGRAN\'); -# push(@Cpp_define, \'-D__CONCURRENT_HASKELL__\', \'-DCONCURRENT\', \'-DGRAN\');', - -# '_2s', 'push (@CcBoth_flags, \'-DGC2s\');', -# '_1s', 'push (@CcBoth_flags, \'-DGC1s\');', -# '_du', 'push (@CcBoth_flags, \'-DGCdu\');', - -# '_a', '', # these user-way guys should not be set! -# '_b', '', -# '_c', '', -# '_d', '', -# '_e', '', -# '_f', '', -# '_g', '', -# '_h', '', -# '_i', '', -# '_j', '', -# '_k', '', -# '_l', '', -# '_m', '', -# '_n', '', -# '_o', '', -# '_A', '', -# '_B', '' ); - \end{code} Import/include directories (\tr{-I} options) are sufficiently weird to @@ -395,18 +371,15 @@ require special handling. @Import_dir = ('.'); #-i things @Include_dir = ('.'); #-I things; other default(s) stuck on AFTER option processing -# where to look for interface files (system hi's, i.e., prelude and hslibs) +# where to look for interface files (system hi's, i.e., prelude and syslibs) @SysImport_dir = ( $INSTALLING ) - ? ( "$InstLibDirGhc/imports" ) - : ( "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/required" - , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/ghc" - , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/glaExts" - , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/concurrent" ); + ? ( "$InstLibDirGhc/imports/std" ) + : ( "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std" ); # We need to look in ghc/ and glaExts/ when searching for implicitly needed .hi files, but # we should really *not* look there for explicitly imported modules. -$GhcVersionInfo = int ($PROJECTVERSION * 100); +$GhcVersionInfo = $ProjectVersionInt; $Haskell1Version = 4; # i.e., Haskell 1.4 @Cpp_define = (); @@ -417,8 +390,8 @@ $Haskell1Version = 4; # i.e., Haskell 1.4 ? $InstLibDirGhc : ( "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR" , "$TopPwd/$CURRENT_DIR/$GHC_RUNTIME_DIR/gmp" - , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR" - , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/cbits" + , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std" + , "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/std/cbits" ) ); @SysLibrary = (); # will be built up as we go along @@ -432,7 +405,7 @@ $MkDependHS = ( $INSTALLING ) ? "$InstBinDirGhc/mkdependHS" : "$TopPwd/$CURRENT_DIR/$GHC_UTILS_DIR/mkdependHS/mkdependHS"; # Fill in later -@MkDependHS_flags = ( ); +@MkDependHS_flags = (); # do_link flag should not be reset while rescanning the cmd-line. $Do_lnkr = 1; @@ -490,7 +463,8 @@ Here are the initial defaults applied to all files: \begin{code} $Cpp_flag_set = 0; # (hack) $Only_preprocess_C = 0; # pretty hackish -$Only_generate_deps = 0; # +$Only_preprocess_hc = 0; # ditto +$Only_generate_deps = 0; # " $PostprocessCcOutput = 0; # native code-gen or via C? @@ -499,9 +473,11 @@ $HscOut = '-C='; # '-C=' ==> .hc output; '-S=' ==> .s output; '-N=' ==> neither $HscOut = '-S=' if $HaveNativeCodeGen && $TargetPlatform =~ /^(alpha|sparc)-/; # TEMP: disable x86 if $HaveNativeCodeGen && $TargetPlatform =~ /^(i386|alpha|sparc)-/; -$ProduceHi = '-hifile='; -$HiOnStdout = 0; -$HiDiff_flag = ''; +$ProduceHi = '-hifile='; +$HiOnStdout = 0; +$HiWith = ''; +$HiDiff_flag = ''; +$Keep_HiDiffs = 0; $CollectingGCstats = 0; $CollectGhcTimings = 0; @@ -552,6 +528,9 @@ $NoImplicitPrelude = 0; # and whatever else @Cmd_opts = (); +# cmd line options prefixing the unit we're compiling +@File_options = (); + \end{code} We inject consistency-checking information into \tr{.hc} files (both @@ -566,10 +545,10 @@ $LinkChk = 1; # set to 0 if the link check should *not* be done # major & minor version numbers; major numbers must always agree; # minor disagreements yield a warning. -$HsC_major_version = 31; +$HsC_major_version = 33; $HsC_minor_version = 0; $Cc_major_version = 36; -$Cc_minor_version = 0; +$Cc_minor_version = 1; # options: these must always agree $HsC_consist_options = ''; # we record, in this order: @@ -587,37 +566,6 @@ $Cc_consist_options = ''; # we record, in this order: Now slurp through the arguments. \begin{code} -#---------- user defined prelude --------------------------------------- - -if (grep(/^-user-prelude$/, @ARGV)) { - - # If ARGV contains -user-prelude we are compiling a piece of - # prelude for the user, probably with additional specialise pragmas - - # We strip out the -O -f and -user-prelude flags provided on - # the command line and add the ones used to compile the prelude - # ToDo: get these options from a common definition in mkworld - - # We also enable any options forced through with -user-prelude-force - - # Hey, Check out this grep statement ;-) (PS) - - @ARGV = grep((!/^-O/ && !/^-f/ && !/^-user-prelude$/) || s/^-user-prelude-force//, - @ARGV); - - unshift(@ARGV, - '-fcompiling-ghc-internals=???', # ToDo!!!! - '-O', - '-fshow-pragma-name-errs', - '-fshow-import-specs', - '-fglasgow-exts', - '-genSPECS', - '-DUSE_FOLDR_BUILD', - '-dcore-lint'); - - print STDERR "ghc: -user-prelude options:\n", "@ARGV", "\n"; -} - &initDriverGlobals(); &splitCmdLine(@ARGV); # Run through the cmd-line first time. @@ -629,6 +577,11 @@ if ( $Status == 0 && $Only_generate_deps ) { push (@MkDependHS_flags, "-o$Osuffix") if $Osuffix; push (@MkDependHS_flags, "-s$BuildTag") if $BuildTag; + push (@MkDependHS_flags, "-D__HASKELL1__=$Haskell1Version"); + # They're not (currently) needed, but we need to quote any -#include options + foreach (@Cmd_opts) { + s/-#include.*$/'$&'/g; + }; local($to_do) = "$MkDependHS @MkDependHS_flags -- @Cmd_opts -- @Input_file" ; &run_something($to_do, 'Haskell dependencies'); exit $Status; @@ -733,22 +686,30 @@ sub setupOptimiseFlags { @HsC_minusNoO_flags = ( '-fsimplify', - '\(', + '[', $Oopt_FB_Support, -# '-falways-float-lets-from-lets', # no idea why this was here (WDP 95/09) '-ffloat-lets-exposing-whnf', '-ffloat-primops-ok', '-fcase-of-case', + '-fdo-case-elim', # '-fdo-lambda-eta-expansion', # too complicated '-freuse-con', -# '-flet-to-case', # no strictness analysis, so... +# '-flet-to-case', # no strictness analysis, so... $Oopt_PedanticBottoms, # $Oopt_MonadEtaExpansion, # no thanks - '-fsimpl-uf-use-threshold0', - '-fessential-unfoldings-only', -# $Oopt_UnfoldingUseThreshold, # no thanks + +# These two work fine, if you really want no simplification at all, +# for bizarre test reasons. But you get really terrible code if you use them, +# for example: let x = e in x +# with dozens of redundant thunks etc. So I'm leaving them out. +# +# '-fsimpl-uf-use-threshold0', +# '-fessential-unfoldings-only', + + $Oopt_UnfoldingUseThreshold, $Oopt_MaxSimplifierIterations, - '\)', + $Oopt_ShowSimplifierProgress, + ']', $Oopt_AddAutoSccs, # '-ffull-laziness', # removed 95/04 WDP following Andr\'e's lead @@ -761,14 +722,29 @@ sub setupOptimiseFlags { # initial simplify: mk specialiser happy: minimum effort please '-fsimplify', - '\(', + '[', $Oopt_FB_Support, '-fkeep-spec-pragma-ids', # required before specialisation - '-fsimpl-uf-use-threshold0', - '-fessential-unfoldings-only', + +# I don't understand why we want -fessential-unfoldings-only here +# If we have it, the following nasty thing happens: +# f = E +# g* = f +# ...g... +# where "*" means exported. +# In the essential-unfoldings pass we still substitute f for g +# but we don't substitute E for f first. So we get +# f = E +# g* = f +# ...f... +# The g=f will get reverse-substituted later, but it's untidy. +# +# '-fessential-unfoldings-only', +# '-fsimpl-uf-use-threshold0', + '-fmax-simplifier-iterations1', $Oopt_PedanticBottoms, - '\)', + ']', ($Oopt_DoSpecialise) ? ( '-fspecialise-overloaded', @@ -777,7 +753,7 @@ sub setupOptimiseFlags { ) : (), '-fsimplify', # need dependency anal after specialiser ... - '\(', # need tossing before calc-inlinings ... + '[', # need tossing before calc-inlinings ... $Oopt_FB_Support, '-ffloat-lets-exposing-whnf', '-ffloat-primops-ok', @@ -791,7 +767,17 @@ sub setupOptimiseFlags { $Oopt_MonadEtaExpansion, $Oopt_UnfoldingUseThreshold, $Oopt_MaxSimplifierIterations, - '\)', + $Oopt_ShowSimplifierProgress, + # + # The presence of -fclone-binds is *crucial* here as + # -ffull-laziness (which we're about to do next) floats + # bindings outwards, so we better make sure that this + # doesn't result in the floating out of bindings + # with identical uniques, i.e., -ffull-laziness needs + # to be preceeded by a simplifier pass with -fclone-binds + # set. + '-fclone-binds', + ']', #LATER: '-fcalc-inlinings1', -- pointless for 2.01 @@ -799,7 +785,7 @@ sub setupOptimiseFlags { # '-ffoldr-build-ww-anal', # '-ffoldr-build-worker-wrapper', # '-fsimplify', -# '\(', +# '[', # $Oopt_FB_Support, # '-ffloat-lets-exposing-whnf', # '-ffloat-primops-ok', @@ -813,7 +799,8 @@ sub setupOptimiseFlags { # $Oopt_MonadEtaExpansion, # $Oopt_UnfoldingUseThreshold, # $Oopt_MaxSimplifierIterations, -# '\)', +# $Oopt_ShowSimplifierProgress, +# ']', # ) : (), # this pass-ordering sequence was agreed by Simon and Andr\'e @@ -824,7 +811,7 @@ sub setupOptimiseFlags { '-ffoldr-build-on', # desugar list comprehensions for foldr/build '-fsimplify', - '\(', + '[', '-fignore-inline-pragma', # **** NB! '-fdo-foldr-build', # NB $Oopt_FB_Support, @@ -840,13 +827,14 @@ sub setupOptimiseFlags { $Oopt_MonadEtaExpansion, $Oopt_UnfoldingUseThreshold, $Oopt_MaxSimplifierIterations, - '\)', + $Oopt_ShowSimplifierProgress, + ']', ) : (), '-ffloat-inwards', '-fsimplify', - '\(', + '[', $Oopt_FB_Support, '-ffloat-lets-exposing-whnf', '-ffloat-primops-ok', @@ -864,12 +852,13 @@ sub setupOptimiseFlags { $Oopt_MonadEtaExpansion, $Oopt_UnfoldingUseThreshold, $Oopt_MaxSimplifierIterations, - '\)', + $Oopt_ShowSimplifierProgress, + ']', '-fstrictness', '-fsimplify', - '\(', + '[', $Oopt_FB_Support, '-ffloat-lets-exposing-whnf', '-ffloat-primops-ok', @@ -884,7 +873,8 @@ sub setupOptimiseFlags { $Oopt_MonadEtaExpansion, $Oopt_UnfoldingUseThreshold, $Oopt_MaxSimplifierIterations, - '\)', + $Oopt_ShowSimplifierProgress, + ']', '-ffloat-inwards', @@ -893,12 +883,12 @@ sub setupOptimiseFlags { # ( ($OptLevel != 2) # ? '' -# : "-fliberate-case -fsimplify \\( $Oopt_FB_Support -ffloat-lets-exposing-whnf -ffloat-primops-ok -fcase-of-case -fdo-case-elim -fcase-merge -fdo-eta-reduction -fdo-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MonadEtaExpansion $Oopt_UnfoldingUseThreshold $Oopt_MaxSimplifierIterations \\)" ), +# : "-fliberate-case -fsimplify [ $Oopt_FB_Support -ffloat-lets-exposing-whnf -ffloat-primops-ok -fcase-of-case -fdo-case-elim -fcase-merge -fdo-eta-reduction -fdo-lambda-eta-expansion -freuse-con -flet-to-case $Oopt_PedanticBottoms $Oopt_MonadEtaExpansion $Oopt_UnfoldingUseThreshold $Oopt_MaxSimplifierIterations $Oopt_ShowSimplifierProgress ]" ), # Final clean-up simplification: '-fsimplify', - '\(', + '[', $Oopt_FB_Support, '-ffloat-lets-exposing-whnf', '-ffloat-primops-ok', @@ -917,14 +907,14 @@ sub setupOptimiseFlags { $Oopt_MonadEtaExpansion, $Oopt_UnfoldingUseThreshold, $Oopt_MaxSimplifierIterations, - '\)', + $Oopt_ShowSimplifierProgress, + ']', # '-fstatic-args', #LATER: '-fcalc-inlinings2', -- pointless for 2.01 # stg2stg passes - '-fupdate-analysis', '-flambda-lift', $Oopt_FinalStgProfilingMassage, $Oopt_StgStats, @@ -934,6 +924,7 @@ sub setupOptimiseFlags { # SPECIAL FLAGS for -O2 ($OptLevel == 2) ? ( + '-fupdate-analysis', # virtually useless; relegated to -O2 '-fsemi-tagging', ) : (), ); @@ -964,6 +955,8 @@ if ( $OptLevel <= 0 ) { } else { # -Ofile, then... &add_Hsc_flags( @HsC_minusO3_flags ); + push(@HsC_flags, $Oopt_FinalStgProfilingMassage) if $Oopt_FinalStgProfilingMassage; + push(@CcBoth_flags, ($MinusO2ForC) ? '-O2' : '-O'); # possibly to be elaborated... } @@ -998,6 +991,9 @@ sub setupBuildFlags { $Oopt_FinalStgProfilingMassage = '-fmassage-stg-for-profiling'; + # Ignore user sccs when auto annotating, but warn when doing so. + $PROFignore_scc = '-W' if $PROFauto; + push(@HsP_flags, (($PROFignore_scc) ? $PROFignore_scc : '-S')); if ( $SplitObjFiles ) { @@ -1080,8 +1076,8 @@ Decide what the consistency-checking options are in force for this run: $Tag = "${Tag}_" if $Tag ne ''; $HiSuffix_prelude="${Tag}hi"; } - push(@HsC_flags, "-hisuf-prelude=.${HiSuffix_prelude}"); # use appropriate Prelude .hi files - push(@HsC_flags, "-hisuf=.${HiSuffix}"); + #push(@HsC_flags, "-hisuf-prelude=.${HiSuffix_prelude}"); # use appropriate Prelude .hi files + #push(@HsC_flags, "-hisuf=.${HiSuffix}"); } # setupBuildFlags \end{code} @@ -1126,9 +1122,7 @@ sub setupMachOpts { } elsif ($TargetPlatform =~ /^i386-/) { # we know how to *mangle* asm for X86 unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); - unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) - if $StkChkByPageFaultOK; - && $TargetPlatform !~ /nextstep/; + unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK && $TargetPlatform !~ /nextstep/; # I do not know how to do STACK_CHECK_BY_PAGE_FAULT # on NeXTs (my fault, not theirs), so I don't. # CaS @@ -1146,13 +1140,11 @@ sub setupMachOpts { } elsif ($TargetPlatform =~ /^m68k-/) { # we know how to *mangle* asm for m68k unshift (@CcRegd_flags, ('-D__STG_REV_TBLS__')); - unshift (@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) - if $StkChkByPageFaultOK; - && $TargetPlatform !~ /nextstep/; + unshift (@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK && $TargetPlatform !~ /nextstep/; # I do not know how to do STACK_CHECK_BY_PAGE_FAULT # on NeXTs (my fault, not theirs), so I don't. # CaS - && + # -fno-defer-pop : for the .hc files, we want all the pushing/ # popping of args to routines to be explicit; if we let things # be deferred 'til after an STGJUMP, imminent death is certain! @@ -1174,13 +1166,12 @@ sub setupMachOpts { unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK; unshift(@CcBoth_flags, ('-static')); - } elsif ($TargetPlatform =~ /^powerpc-/) { + } elsif ($TargetPlatform =~ /^powerpc-|^rs6000-/) { # we know how to *mangle* asm for PowerPC - unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); +# :-( unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); unshift(@CcRegd_flags, ('-DSTACK_CHECK_BY_PAGE_FAULT=1')) if $StkChkByPageFaultOK; unshift(@CcBoth_flags, ('-static')); # always easier to start with unshift(@CcRegd_flags, ('-finhibit-size-directive')); # avoids traceback tables - } elsif ($TargetPlatform =~ /^sparc-/) { # we know how to *mangle* asm for SPARC unshift(@CcRegd_flags, ('-D__STG_REV_TBLS__')); @@ -1190,6 +1181,23 @@ sub setupMachOpts { } # end of setupMachOpts \end{code} +%************************************************************************ +%* * +\subsection{Set up for warnings} +%* * +%************************************************************************ + +Several warnings are turned on by default. These are supposed to be +the 'I'm pretty sure you've made a mistake here' kind of warnings. +The rest are turned on by the -W and -Wall options, or individually +via their -fwarn and -fno-warn flags. + +\begin{code} +sub setupWarningFlags { +&add_Hsc_flags( @StandardWarnings ); +} +\end{code} + Same unshifting magic, but for special linker flags. The configure script determines whether the object file symbol tables @@ -1202,19 +1210,20 @@ sub setupLinkOpts { local($uscore) = ( ${LeadingUnderscore} eq 'YES' ) ? '_' : ''; unshift(@Ld_flags, - (($Ld_main) ? ( - '-u', "${uscore}Main_" . $Ld_main . '_closure', - ) : () -# What are these? -- SOF -# , '-u', "${uscore}STbase_unsafePerformPrimIO_fast1" -# , '-u', "${uscore}Prelude_Z91Z93_closure" # i.e., [] -# , '-u', "${uscore}Prelude_IZh_static_info" -# , '-u', "${uscore}Prelude_False_inregs_info" -# , '-u', "${uscore}Prelude_True_inregs_info" -# , '-u', "${uscore}Prelude_CZh_static_info" -# , '-u', "${uscore}DEBUG_REGS" - )) - ; # just for fun, now... + (($Ld_main) ? ( '-u', "${uscore}Main_" . $Ld_main . '_closure' ) : ())); + unshift(@Ld_flags, + ( '-u', "${uscore}PrelBase_Z91Z93_closure" # i.e., [] + ,'-u', "${uscore}PrelBase_IZh_static_info" + ,'-u', "${uscore}PrelBase_CZh_static_info" + ,'-u', "${uscore}PrelBase_False_inregs_info" + ,'-u', "${uscore}PrelBase_True_inregs_info" + ,'-u', "${uscore}DEBUG_REGS" + )); + if ($TargetPlatform =~ /^powerpc-|^rs6000-/) { + # sometimes we have lots of toc entries... + # unshift(@Ld_flags, ('-Xlinker -bbigtoc -Xlinker -bnoquiet')); + unshift(@Ld_flags, ('-Xlinker -bbigtoc')); + } } # end of setupLinkOpts @@ -1329,8 +1338,8 @@ if ($#Input_file < 0 && $#Link_file < 0) { @Input_file = ( '-' ); open(INF, "> $Tmp_prefix.hs") || &tidy_up_and_die(1,"Can't open $Tmp_prefix.hs\n"); - print STDERR "Enter your Haskell program, end with ^D (on a line of its own):\n"; - while (<>) { print INF $_; } + print STDERR "Enter your Haskell program, end with ^D (on a line of its own):\n" if -t; + while () { print INF $_; } close(INF) || &tidy_up_and_die(1,"Failed writing to $Tmp_prefix.hs\n"); } @@ -1338,7 +1347,7 @@ if ($#Input_file < 0 && $#Link_file < 0) { Tell the world who we are, if they asked. \begin{code} -print STDERR "${PROJECTNAME}, version ${PROJECTVERSION}, patchlevel ${PROJECTPATCHLEVEL}\n" +print STDERR "${ProjectName}, version ${ProjectVersion}, patchlevel ${ProjectPatchLevel}\n" if $Verbose; \end{code} @@ -1381,8 +1390,14 @@ if ($Do_lnkr) { # for a linker, use an explicitly given one, or the going C compiler ... local($lnkr) = ( $Lnkr ) ? $Lnkr : $CcRegd; + if ( ($Specific_output_file eq '') && + ($TargetPlatform eq 'i386-unknown-cygwin32') ) { + $Specific_output_file = 'main.exe'; + print STDERR "Output file not specified, defaulting to \"main.exe\"\n"; + } + local($output) = ($Specific_output_file ne '') ? "-o $Specific_output_file" : ''; - @Files_to_tidy = ($Specific_output_file ne '') ? $Specific_output_file : 'a.out'; + @Files_to_tidy = ($Specific_output_file ne '') ? $Specific_output_file : 'a.out'; local($to_do) = "$lnkr $Verbose @Ld_flags $output @Link_file $TopClosureFile $libdirs @UserLibrary @SysLibrary"; &run_something($to_do, 'Linker'); @@ -1429,7 +1444,7 @@ eval 'exec perl -S \$0 \${1+"\$@"}' if \$running_under_some_shell; # =!=!=!=!=!=!=!=!=!=!=! # This script is automatically generated: DO NOT EDIT!!! -# Generated by Glasgow Haskell, version ${PROJECTVERSION} ${PROJECTPATCHLEVEL} +# Generated by Glasgow Haskell, version ${ProjectVersion} ${ProjectPatchLevel} # \$pvm_executable = '$pvm_executable'; \$pvm_executable_base = '$pvm_executable_base'; @@ -1550,26 +1565,32 @@ Again, we'll do the post-recompilation-checker parts of this later. local($is_hc_file) = 1; #Is the C code .hc or .c? Assume .hc for now - $lit2pgm_hscpp = $ifile if ($ifile =~ /\.hs$/); + # OK, let's strip off some literate junk.. + if ($do_lit2pgm) { + &runLit2pgm($in_lit2pgm, $lit2pgm_hscpp) + } else { + $lit2pgm_hscpp = $ifile; + } - # OK, let's strip off some literate junk: - &runLit2pgm($in_lit2pgm, $lit2pgm_hscpp) if ($ifile =~ /\.lhs$/); # @File_options = (); # Scan the top of the de-litted file for {-# OPTIONS #-} pragmas - &check_for_source_options($lit2pgm_hscpp); - # options found in the source file take a back seat, i.e., we scan + &check_for_source_options($lit2pgm_hscpp,$ifile); + + # Options found in the source file take a back seat, i.e., we scan # them first. Only process the command line again if source file # contained anything of interest *or* there's more than one # input file (we have to reset the options). # if ( $#Input_file >= 0 || $#File_options >= 0) { - @File_options = (@File_options, @Cmd_opts); + #@File_options = (@File_options, @Cmd_opts); # Now process the command line &initDriverGlobals(); - &processArgs(@File_options); + &processArgs((@File_options,@Cmd_opts)); + print STDERR "\nEffective command line: " . + join(' ',(@File_options,@Cmd_opts)) . "\n" if $Verbose; } # # Having got the effective command line scanned, set up @@ -1583,6 +1604,7 @@ Again, we'll do the post-recompilation-checker parts of this later. &setupOptimiseFlags(); &setupMachOpts(); &setupIncPaths(); + &setupWarningFlags(); &setupHeapStackSize(); # @@ -1597,7 +1619,12 @@ Again, we'll do the post-recompilation-checker parts of this later. local($do_as) = $Do_as; local($hsc_out) = ( $HscOut eq '-C=' ) ? "$Tmp_prefix.hc" : "$Tmp_prefix.s" ; - if ($ifile =~ /.lhs$/ || $ifile =~ /.hs$/ ) { + if ($Only_preprocess_hc) { # stop after having run $Cc -E + $do_as=0; + } + if ($Only_preprocess_C) { # stop after having run $hscpp + $do_hsc=0; $do_cc = 0; $do_as=0; + } elsif ($ifile =~ /.lhs$/ || $ifile =~ /.hs$/ ) { ; } elsif ($ifile =~ /\.hc$/ || $ifile =~ /_hc$/ ) { # || $ifile =~ /\.$Isuffix$/o) # ToDo: better $do_hscpp = 0; $do_hsc = 0; $do_cc = 1; @@ -1615,8 +1642,8 @@ Again, we'll do the post-recompilation-checker parts of this later. # hack to avoid running hscpp $HsCpp = $Cat if ! $Cpp_flag_set; - &runHscpp($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) - if $do_hscpp; + &runHscpp($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) if $do_hscpp; + \end{code} We now think about whether to run hsc/cc or not (when hsc produces .s @@ -1625,6 +1652,7 @@ stuff, it effectively takes the place of both phases). To get the output file name right: for each phase that we are {\em not} going to run, set its input (i.e., the output of its preceding phase) to @"$ifile_root."@. + \begin{code} local($going_interactive) = $HscOut eq '-N=' || $ifile_root eq '_stdin'; @@ -1633,7 +1661,7 @@ phase) to @"$ifile_root."@. # -fvia-C (or the equivalent) # if ( $HscOut ne '-C=' && $Keep_hc_file_too ) { - print STDERR "Warning: Native code generator to be used, -keep-hc-file-too will be ignored\n"; + print STDERR "$Pgm: warning: Native code generator to be used, -keep-hc-file-too will be ignored\n"; } if (! $do_cc && ! $do_as) { # stopping after hsc @@ -1647,7 +1675,7 @@ phase) to @"$ifile_root."@. if (! $do_as) { # stopping after gcc (or hsc) $cc_as = ($Specific_output_file ne '') ? $Specific_output_file - : &odir_ify($ifile_root, ( $Only_preprocess_C ) ? 'i' : 's'); + : &odir_ify($ifile_root, ( $Only_preprocess_hc ) ? 'i' : 's'); $ofile_target = $cc_as; # reset } @@ -1665,11 +1693,13 @@ Now the Haskell compiler, C compiler, and assembler if ($do_cc) { &runGcc ($is_hc_file, $hsc_out, $cc_as_o); - &runMangler($is_hc_file, $cc_as_o, $cc_as, $ifile_root); + &runMangler($is_hc_file, $cc_as_o, $cc_as, $ifile_root) if ! $Only_preprocess_hc; } &split_asm_file($cc_as) if $do_as && $SplitObjFiles; + # save a copy of the .s file.. + &saveIntermediate($ifile_root , "s" , $cc_as) if ($do_as && $Keep_s_file_too); &runAs($as_out, $ifile_root) if $do_as; \end{code} @@ -1680,10 +1710,15 @@ Finally, decide what to queue up for linker input. #ToDo: local($or_isuf) = ($Isuffix eq '') ? '' : "|$Isuffix"; - if ( $ifile !~ /\.(lhs|hs|hc|c|s)$/ && $ifile !~ /_hc$/ ) { - print STDERR "$Pgm: don't recognise suffix on `$ifile'; passing it through to linker\n" - if $ifile !~ /\.a$/; + if ( $ifile !~ /\.(lhs|hs|hc|c|s|a)$/ && $ifile !~ /_hc$/ ) { + # There's sometimes confusion regarding .hi files; users + # supplying them on the command line. + if ( $ifile =~ /\.hi$/ ) { + print STDERR "$Pgm: warning: found `$ifile' on command line; interface files should not be supplied here - ignoring it.\n"; + } else { + print STDERR "$Pgm: don't recognise suffix on `$ifile'; passing it through to linker\n"; + } # oops; we tentatively pushed the wrong thing; fix & do the right thing pop(@Link_file); push(@Link_file, $ifile); } @@ -1702,9 +1737,13 @@ Finally, decide what to queue up for linker input. sub runLit2pgm { local($in_lit2pgm, $lit2pgm_hscpp) = @_; - local($to_do) = "echo '#line 1 \"$in_lit2pgm\"' > $lit2pgm_hscpp && ". - "$Unlit @Unlit_flags $in_lit2pgm - >> $lit2pgm_hscpp"; - @Files_to_tidy = ( $lit2pgm_hscpp ); + local($to_do) = ""; + + # Only add #line pragma if we're going to need it. + $to_do = "echo '#line 1 \"$in_lit2pgm\"' > $lit2pgm_hscpp && " if ($Cpp_flag_set); + $to_do .= "$Unlit @Unlit_flags $in_lit2pgm - >> $lit2pgm_hscpp"; + + push(@Files_to_tidy, $lit2pgm_hscpp ); &run_something($to_do, 'literate pre-processor'); } @@ -1714,20 +1753,32 @@ sub runLit2pgm { sub runHscpp { local($in_lit2pgm, $lit2pgm_hscpp, $hscpp_hsc) = @_; - local($to_do); + local($to_do) = ""; + + # Strictly speaking, echoing of the following line pragma is only required + # on non-delit'ed input, as we've already added it during de-lit. However, + # hscpp will then add a {-# LINE 1 "$lit2pgm_hsc" -} to the top of the file, + # which is not very informative (but harmless). Hence, we uniformly have + # {-# LINE 1 "$in_lit2pgm" #-} as the first line to all cpp'ed hsc input. + # + $to_do = "echo '{-# LINE 1 \"$in_lit2pgm\" -}' > $hscpp_hsc && "; if ($HsCpp eq $Cat) { - $to_do = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsc && ". - "$HsCpp $lit2pgm_hscpp >> $hscpp_hsc"; - @Files_to_tidy = ( $hscpp_hsc ); + $to_do .= "$HsCpp $lit2pgm_hscpp >> $hscpp_hsc"; + push(@Files_to_tidy, $hscpp_hsc ); &run_something($to_do, 'Ineffective C pre-processor'); } else { local($includes) = '-I' . join(' -I',@Include_dir); - $to_do = "echo '#line 1 \"$in_lit2pgm\"' > $hscpp_hsc && ". - "$HsCpp $Verbose $genSPECS_flag @HsCpp_flags -D__HASKELL1__=$Haskell1Version -D__GLASGOW_HASKELL__=$GhcVersionInfo $includes $lit2pgm_hscpp >> $hscpp_hsc"; - @Files_to_tidy = ( $hscpp_hsc ); + $to_do .= "$HsCpp $Verbose $genSPECS_flag @HsCpp_flags -D__HASKELL1__=$Haskell1Version -D__GLASGOW_HASKELL__=$GhcVersionInfo $includes $lit2pgm_hscpp >> $hscpp_hsc"; + push(@Files_to_tidy, $hscpp_hsc ); &run_something($to_do, 'Haskellised C pre-processor'); } + + if ( $Only_preprocess_C ) { + $to_do = "$Cat $hscpp_hsc"; + &run_something($to_do, ''); + } + } \end{code} @@ -1744,31 +1795,32 @@ sub runHscAndProcessInterfaces { local($source_unchanged) = 1; -# Check if the source file is up to date relative to the target; in -# that case we say "source is unchanged" and let the compiler bail out -# early if the import usage information allows it. + # Check if the source file is up to date relative to the target; in + # that case we say "source is unchanged" and let the compiler bail out + # early if the import usage information allows it. ($i_dev,$i_ino,$i_mode,$i_nlink,$i_uid,$i_gid,$i_rdev,$i_size, $i_atime,$i_mtime,$i_ctime,$i_blksize,$i_blocks) = stat($ifile); - if ( ! -f $ofile_target ) { -# print STDERR "$Pgm:compile:Output file $ofile_target doesn't exist\n"; + # The informational messages below are now conditional on -v being set -- SOF + if ( $ofile_target ne "_stdin.s" && ! -f $ofile_target ) { + print STDERR "$Pgm:compile:Output file $ofile_target doesn't exist\n" if $Verbose; $source_unchanged = 0; } ($o_dev,$o_ino,$o_mode,$o_nlink,$o_uid,$o_gid,$o_rdev,$o_size, $o_atime,$o_mtime,$o_ctime,$o_blksize,$o_blocks) = stat(_); # stat info from -f test - if ( ! -f $hifile_target ) { -# print STDERR "$Pgm:compile:Interface file $hifile_target doesn't exist\n"; + if ( $hifile_target ne "_stdout" && ! -f $hifile_target ) { + print STDERR "$Pgm:compile:Interface file $hifile_target doesn't exist\n" if $Verbose; $source_unchanged = 0; } ($hi_dev,$hi_ino,$hi_mode,$hi_nlink,$hi_uid,$hi_gid,$hi_rdev,$hi_size, $hi_atime,$hi_mtime,$hi_ctime,$hi_blksize,$hi_blocks) = stat(_); # stat info from -f test - if ($i_mtime > $o_mtime) { -# print STDERR "$Pgm:recompile:Input file $ifile newer than $ofile_target\n"; + if ( $ofile_target ne "_stdin.s" && $i_mtime > $o_mtime) { + print STDERR "$Pgm:recompile:Input file $ifile newer than $ofile_target\n" if $Verbose; $source_unchanged = 0; } @@ -1778,14 +1830,14 @@ sub runHscAndProcessInterfaces { push(@HsC_flags, '-fsource-unchanged'); } -# Run the compiler + # Run the compiler &runHsc($ifile_root, $hsc_out, $hsc_hi, $going_interactive); -# See if it bailed out early, saying nothing needed doing. -# We work this out by seeing if it created an output .hi file + # See if it bailed out early, saying nothing needed doing. + # We work this out by seeing if it created an output .hi file - if ( ! -f $hsc_hi ) { + if ( ! -f $hsc_hi && $ProduceHi !~ /-nohifile=/ ) { # Doesn't exist, so we bailed out early. # Tell the C compiler and assembler not to run $do_cc = 0; $do_as = 0; @@ -1803,8 +1855,10 @@ sub runHscAndProcessInterfaces { # out early, we still need to touch the interface file of B. The reason # for this is that B may export A's interface. # - &run_something("touch $ofile_target $hifile_target", - "Touch $ofile_target $hifile_target, to propagate dependencies"); + &run_something("touch $ofile_target", + "Touch $ofile_target, to propagate dependencies") if $HscOut ne '-N='; + &run_something("touch $hifile_target", + "Touch $hifile_target, to propagate dependencies") if $ProduceHi =~ /-nohifile=/ ; } else { @@ -1829,28 +1883,21 @@ sub runHscAndProcessInterfaces { # Interface-handling is important enough to live off by itself - require('ghc-iface.prl') - || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-iface.prl!\n"); - - &postprocessHiFile($hsc_hi, $hifile_target, $going_interactive); - - # save a copy of the .hc file, even if we are carrying on... - if ($HscOut eq '-C=' && $do_cc && $Keep_hc_file_too) { - local($to_do) = "$Rm $ifile_root.hc; $Cp $hsc_out $ifile_root.hc"; - &run_something($to_do, 'Saving copy of .hc file'); + if ( $ProduceHi !~ /-nohifile=/ ) { # If we've produced one, process it. + require('ghc-iface.prl') || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-iface.prl!\n"); + &postprocessHiFile($hsc_hi, $hifile_target, $going_interactive); } - - # save a copy of the .s file, even if we are carrying on... - if ($HscOut eq '-S=' && $do_as && $Keep_s_file_too) { - local($to_do) = "$Rm $ifile_root.s; $Cp $hsc_out $ifile_root.s"; - &run_something($to_do, 'Saving copy of .s file'); - } - # if we're going to split up object files, # we inject split markers into the .hc file now if ( $HscOut eq '-C=' && $SplitObjFiles ) { &inject_split_markers ( $hsc_out ); } + + # save a copy of the .hc file, even if we are carrying on... + if ($HscOut eq '-C=' && $do_cc && $Keep_hc_file_too) { + &saveIntermediate($ifile_root , "hc" , $hsc_out); + } + } } \end{code} @@ -1864,13 +1911,12 @@ sub runHsc { foreach $a ( @HsP_flags ) { $a = ",$a" unless $a =~ /^,/; } &makeHiMap() unless $HiMapDone; -# print STDERR "HiIncludes: $HiIncludeString\n"; + #print STDERR "HiIncludes: $HiIncludeString\n"; push(@HsC_flags, "-himap=$HiIncludeString"); -# push(@HsC_flags, "-himap=$HiMapFile"); # here, we may produce .hc/.s and/or .hi files local($output) = ''; - @Files_to_tidy = (); + #@Files_to_tidy = (); if ( $going_interactive ) { # don't need .hi unless going to show it on stdout: @@ -1881,7 +1927,7 @@ sub runHsc { # set up for producing output/.hi; note that flag twiddling # may mean that nothing will actually be produced: $output = "$ProduceHi$hsc_hi $HscOut$hsc_out"; - @Files_to_tidy = ( $hsc_hi, $hsc_out ); + push(@Files_to_tidy, $hsc_hi, $hsc_out ); # if we're compiling foo.hs, we want the GC stats to end up in foo.stat if ( $CollectingGCstats ) { @@ -1892,6 +1938,7 @@ sub runHsc { if ( $CollectGhcTimings ) { # assume $RTS_style eq 'ghc' # emit nofibbish time/bytes-alloc stats to stderr; # see later .stat file post-processing + print STDERR "warning: both -Rgc-stats and -Rghc-timing used, -Rghc-timing wins." if $CollectingGCstats; push(@HsC_rts_flags, "-s$Tmp_prefix.stat"); push(@Files_to_tidy, "$Tmp_prefix.stat"); } @@ -1914,9 +1961,7 @@ sub runHsc { Use \tr{@Import_dir} and \tr{@SysImport_dir} to make a tmp file of (module-name, pathname) pairs, one per line, separated by a space. \begin{code} -#%HiMap = (); $HiMapDone = 0; -$HiMapFile = ''; $HiIncludeString = (); # dir1:dir2:dir3, to pass to GHC sub makeHiMap { @@ -1926,86 +1971,29 @@ sub makeHiMap { local($mod, $path, $d, $e); # reset the global variables: - #%HiMap = (); $HiMapDone = 0; - $HiMapFile = ''; $HiIncludeString = (); # dir1:dir2:dir3, to pass to GHC foreach $d ( @Import_dir ) { - if ($HiIncludeString) { $HiIncludeString = "$HiIncludeString:$d"; - } else { $HiIncludeString = $d; } + if ($HiIncludeString) { + $HiIncludeString = "$HiIncludeString:${d}%.${HiSuffix}"; + } else { + $HiIncludeString = "$d%.${HiSuffix}"; + } -# The compiler does the searching now -# -# opendir(DIR, $d) || &tidy_up_and_die(1,"$Pgm: error when reading directory: $d\n"); -# local(@entry) = readdir(DIR); -# foreach $e ( @entry ) { -# next unless $e =~ /\b([A-Z][A-Za-z0-9_]*)\.${HiSuffix_prelude}$/o; -# $mod = $1; -# $path = "$d/$e"; -# $path =~ s,^\./,,; -# -# if ( ! defined($HiMap{$mod}) ) { -# $HiMap{$mod} = $path; -# } else { -# &already_mapped_err($mod, $HiMap{$mod}, $path); -# } -# } -# closedir(DIR); # || &tidy_up_and_die(1,"$Pgm: error when closing directory: $d\n"); } foreach $d ( @SysImport_dir ) { - if ($HiIncludeString) { $HiIncludeString = "$HiIncludeString:$d"; - } else { $HiIncludeString = $d; } - -# opendir(DIR, $d) || &tidy_up_and_die(1,"$Pgm: error when reading directory: $d\n"); -# local(@entry) = readdir(DIR); -# foreach $e ( @entry ) { -# next unless $e =~ /([A-Z][A-Za-z0-9_]*)\.$HiSuffix$/o; -# next if $NoImplicitPrelude && $e =~ /Prelude\.$HiSuffix$/o; -# -# $mod = $1; -# $path = "$d/$e"; -# $path =~ s,^\./,,; -# -# if ( ! defined($HiMap{$mod}) ) { -# $HiMap{$mod} = $path; -# } elsif ( $mod ne 'Main' ) { # saves useless warnings... -# &already_mapped_err($mod, $HiMap{$mod}, $path); -# } -# } -# closedir(DIR); # || &tidy_up_and_die(1,"$Pgm: error when closing directory: $d\n"); + if ($HiIncludeString) { + $HiIncludeString = "$HiIncludeString:${d}%.${HiSuffix_prelude}"; + } else { + $HiIncludeString = "${d}%.${HiSuffix_prelude}"; + } } -# -# Not currently used: -# -# $HiMapFile = "$Tmp_prefix.himap"; -# unlink($HiMapFile); -# open(HIMAP, "> $HiMapFile") || &tidy_up_and_die(1,"$Pgm: can't open $HiMapFile\n"); -# foreach $d (keys %HiMap) { -# print HIMAP $d, ' ', $HiMap{$d}, "\n"; -# } -# close(HIMAP) || &tidy_up_and_die(1,"$Pgm: error when closing $HiMapFile\n"); - $HiMapDone = 1; } -sub already_mapped_err { - local($mod, $mapped_to, $path) = @_; - - # OK, it isn't really an error if $mapped_to and $path turn - # out to be the same thing. - ($m_dev,$m_ino,$m_mode,$m_nlink,$m_uid,$m_gid,$m_rdev,$m_size, - $m_atime,$m_mtime,$m_ctime,$m_blksize,$m_blocks) = stat($mapped_to); - ($p_dev,$p_ino,$p_mode,$p_nlink,$p_uid,$p_gid,$p_rdev,$p_size, - $p_atime,$p_mtime,$p_ctime,$p_blksize,$p_blocks) = stat($path); - - return if $m_ino == $p_ino; # same inode number - - print STDERR "$Pgm: module $mod already mapped to $mapped_to"; - print STDERR ";\n\tignoring: $path\n"; -} \end{code} %************************************************************************ @@ -2055,7 +2043,7 @@ sub runGcc { local($cc_help_s) = "ghc$$.s"; $cc = $CcRegd; - $s_output = ($is_hc_file || $TargetPlatform =~ /^(hppa|i386)/) ? $cc_as_o : $cc_as; + $s_output = ($is_hc_file || $TargetPlatform =~ /^(powerpc|rs6000|hppa|i386)/) ? $cc_as_o : $cc_as; $c_flags .= " @CcRegd_flags"; $c_flags .= ($is_hc_file) ? " @CcRegd_flags_hc" : " @CcRegd_flags_c"; @@ -2081,15 +2069,21 @@ EOINCL print TMP "#include \"$hsc_out\"\n"; close(TMP) || &tidy_up_and_die(1,"Failed writing to $cc_help\n"); - local($to_do) = "$cc $Verbose $ddebug_flag $c_flags @Cpp_define -D__HASKELL1__=$Haskell1Version $includes $cc_help > $Tmp_prefix.ccout 2>&1 && ( if [ $cc_help_s != $s_output ] ; then mv $cc_help_s $s_output ; else exit 0 ; fi )"; + # Don't redirect stderr into intermediate file if slamming output onto stdout (e.g., with -E) + local($fuse_stderr) = "2>&1" if ! $Only_preprocess_hc; + local($to_do) = "$cc $Verbose $ddebug_flag $c_flags @Cpp_define -D__HASKELL1__=$Haskell1Version $includes $cc_help > $Tmp_prefix.ccout $fuse_stderr && ( if [ $cc_help_s != $s_output ] ; then mv $cc_help_s $s_output ; else exit 0 ; fi )"; # note: __GLASGOW_HASKELL__ is pointedly *not* #defined at the C level. - if ( $Only_preprocess_C ) { # HACK ALERT! + + if ( $Only_preprocess_hc ) { # HACK ALERT! $to_do =~ s/ -S\b//g; } - @Files_to_tidy = ( $cc_help, $cc_help_s, $s_output ); - $PostprocessCcOutput = 1; # hack, dear hack... + push(@Files_to_tidy, $cc_help, $cc_help_s, $s_output ); + $PostprocessCcOutput = 1 if ! $Only_preprocess_hc; # hack, dear hack... &run_something($to_do, 'C compiler'); $PostprocessCcOutput = 0; + if ( $Only_preprocess_hc ) { + system("$Cat $Tmp_prefix.ccout"); + } unlink($cc_help, $cc_help_s); } \end{code} @@ -2136,6 +2130,11 @@ sub runMangler { || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-hppa.prl!\n"); &mini_mangle_asm_hppa($cc_as_o, $cc_as); + } elsif ($TargetPlatform =~ /^powerpc|^rs6000/) { + # minor mangling of non-threaded files for powerpcs and rs6000s + require('ghc-asm.prl') + || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-asm-powerpc.prl!\n"); + &mini_mangle_asm_powerpc($cc_as_o, $cc_as); } elsif ($TargetPlatform =~ /^i386/) { # extremely-minor OFFENSIVE mangling of non-threaded just one file require('ghc-asm.prl') @@ -2144,10 +2143,9 @@ sub runMangler { } # save a copy of the .s file, even if we are carrying on... - if ($do_as && $Keep_s_file_too) { - local($to_do) = "$Rm $ifile_root.s; $Cp $cc_as $ifile_root.s"; - &run_something($to_do, 'Saving copy of .s file'); - } + #if ($do_as && $Keep_s_file_too) { + # &saveIntermediate($ifile_root , "s" , $cc_as); + #} } \end{code} @@ -2159,7 +2157,7 @@ sub runAs { if ( ! $SplitObjFiles ) { local($to_do) = "$asmblr -o $as_out -c @As_flags $cc_as"; - @Files_to_tidy = ( $as_out ); + push(@Files_to_tidy, $as_out ); &run_something($to_do, 'Unix assembler'); } else { # more complicated split-ification... @@ -2179,7 +2177,7 @@ sub runAs { for ($f = 1; $f <= $NoOfSplitFiles; $f++ ) { local($split_out) = &odir_ify("${ifile_root}__${f}",'o'); local($to_do) = "$asmblr -o $split_out -c @As_flags ${Tmp_prefix}__${f}.s"; - @Files_to_tidy = ( $split_out ); + push(@Files_to_tidy, $split_out ); &run_something($to_do, 'Unix assembler'); } @@ -2209,8 +2207,29 @@ sub run_something { } local($return_val) = 0; - system("$Time $str_to_do"); - $return_val = $?; + + if ( length($str_to_do) > 4000) { + # 4000 - on the random side, just like the *real* ARG_MAX + # for some shells. + + # With some shells, command lines of this length may + # very well cause trouble. To safeguard against this, we squirrel the + # command into a file and exec that. + local ($sh) = $ENV{'REAL_SHELL'}; + print STDERR "Backup plan A: saving cmd line in ${Tmp_prefix}.sh and executing that with $sh\n" if $Verbose; + open (TEMP, "> ${Tmp_prefix}.sh") || + &tidy_up_and_die(1,"$Pgm: failed to open `$Tmp_prefix.sh'\n"); + print TEMP "$Time $str_to_do\n"; + close (TEMP) || + &tidy_up_and_die(1,"$Pgm: failed closing `$Tmp_prefix.sh'\n"); + system("$sh $Tmp_prefix.sh"); + $return_val = $?; + + unlink "${Tmp_prefix}.sh"; + } else { + system("$Time $str_to_do"); + $return_val = $?; + } if ( $PostprocessCcOutput ) { # hack, continued open(CCOUT, "< $Tmp_prefix.ccout") @@ -2247,7 +2266,7 @@ sub run_something { %************************************************************************ %* * -\subsection[Driver-ghctiming]{Emit nofibbish GHC timings} +\subsection[Driver-ghc-timing]{Emit nofibbish GHC timings} %* * %************************************************************************ @@ -2259,20 +2278,27 @@ sub process_ghc_timings { local($SysSpecificTiming) = 'ghc'; open(STATS, $StatsFile) || die "Failed when opening $StatsFile\n"; - local($tot_live) = 0; # for calculating avg residency + local($max_live) = 0; + local($tot_live) = 0; # for calculating residency stuff + local($tot_samples) = 0; while () { - $tot_live += $1 if /^\s*\d+\s+\d+\s+\d+\.\d+\%\s+(\d+)\s+\d+\.\d+\%/; - - $BytesAlloc = $1 if /^\s*([0-9,]+) bytes allocated in the heap/; + if (! /Minor/ && /^\s*\d+\s+\d+\s+(\d+)\s+\d+\.\d+\%/ ) { + $max_live = $1 if $max_live < $1; + $tot_live += $1; + $tot_samples += 1; + } + $BytesAlloc = $1 if /^\s*([0-9,]+) bytes allocated in the heap/; if ( /^\s*([0-9,]+) bytes maximum residency .* (\d+) sample/ ) { $MaxResidency = $1; $ResidencySamples = $2; } - $GCs = $1 if /^\s*([0-9,]+) garbage collections? performed/; + $GCs = $1 if /^\s*([0-9,]+) garbage collections? performed/; - if ( /^\s*INIT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) { + # The presence of -? in the following pattern is only there to + # accommodate 0.29 && <= 2.05 RTS' + if ( /^\s*INIT\s+time\s*(\d+\.\d\d)s\s*\(\s*-?(\d+\.\d\d)s elapsed\)/ ) { $InitTime = $1; $InitElapsed = $2; } elsif ( /^\s*MUT\s+time\s*(\d+\.\d\d)s\s*\(\s*(\d+\.\d\d)s elapsed\)/ ) { $MutTime = $1; $MutElapsed = $2; @@ -2281,8 +2307,10 @@ sub process_ghc_timings { } } close(STATS) || die "Failed when closing $StatsFile\n"; - if ( defined($ResidencySamples) && $ResidencySamples > 0 ) { - $AvgResidency = int ($tot_live / $ResidencySamples) ; + if ( $tot_samples > 0 ) { + $ResidencySamples = $tot_samples; + $MaxResidency = $max_live; + $AvgResidency = int ($tot_live / $tot_samples) ; } # warn about what we didn't find @@ -2367,7 +2395,7 @@ nonsensical). sub grab_arg_arg { local(*Args, $option, $rest_of_arg) = @_; - if ($rest_of_arg) { + if ($rest_of_arg ne '') { return($rest_of_arg); } elsif ($#Args >= 0) { local($temp) = $Args[0]; shift(@Args); @@ -2414,6 +2442,26 @@ sub add_Hsc_flags { } \end{code} +\begin{code} +sub add_syslib { + local($syslib) = @_; + + unshift(@SysImport_dir, + $INSTALLING ? "$InstLibDirGhc/imports/$syslib" + : "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/$syslib"); + + push(@SysLibrary_dir, + $INSTALLING ? ("$InstLibDirGhc") + : ("$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/$syslib", + "$TopPwd/$CURRENT_DIR/$GHC_LIB_DIR/$syslib/cbits")); + + push(@SysLibrary, "-lHS$syslib"); + push(@SysLibrary, "-lHS${syslib}_cbits") + unless $syslib eq 'contrib' || $syslib eq 'exts' || $syslib eq 'concurrent'; + #HACK! they have no cbits +} +\end{code} + Source files may have {-# OPTIONS ... #-} pragmas at the top, containing command line options we want to append to collection of commands specified directly. @check_for_source_options@ looks at the top of a de-lit'ified Haskell @@ -2421,22 +2469,41 @@ file for any such pragmas: \begin{code} sub check_for_source_options { - local($file) = @_; + local($file,$ifile) = @_; + local($comment_start,$comment_end); + + if ($ifile =~ /\.hc$/ || + $ifile =~ /_hc$/ || + $ifile =~ /\.s$/ || + $ifile =~ /_s$/ ) { # `Real' C intermediate + $comment_start = "/\\*"; + $comment_end = "\\*/"; + } else { # Assume it is a file containing Haskell source + $comment_start = "{-#"; + $comment_end = "#-}"; + } open(FILE,$file) || return(1); # No big loss - + while () { - if ( /^{-# OPTIONS (.*)#-}/ ) { + if ( /^${comment_start} OPTIONS (.*)${comment_end}$/ ) { # add the options found at the back of the command line. local(@entries) = split(/\s+/,$1); + print STDERR "Found OPTIONS " . join(' ',@entries) . " in $file\n" if $Verbose; push(@File_options, @entries); } elsif ( /^$/ ) { # ignore empty lines ; } + elsif ( /^#line.+$/ ) { # ignore comment lines (unused..ToDo: rm ) + ; + } + elsif ( /^{-# LINE.+$/ ) { # ignore line pragmas + ; + } else { # stop looking, something non-empty / not - # {-# OPTIONS .. #-} encountered. - break; + # ${comment_start} OPTIONS .. ${comment_end} encountered. + close(FILE);return(0); } } close(FILE); @@ -2461,11 +2528,11 @@ sub splitCmdLine { arg: while($_ = $args[0]) { shift(@args); # sigh, we have to deal with these -option arg specially here. - /^-(tmpdir|odir|o|isuf|osuf|hisuf|hisuf-prelude|odump|syslib)$/ && + /^-(tmpdir|odir|ohi|o|isuf|osuf|hisuf|hisuf-prelude|odump|syslib)$/ && do { push(@Cmd_opts, $_); push(@Cmd_opts,$args[0]); shift(@args); next arg; }; - /^-./ && do { push(@Cmd_opts, $_); next arg; }; + /^--?./ && do { push(@Cmd_opts, $_); next arg; }; - if (/\.[oa]$/) { + if (/\.([^_]+_)?[oa]$/) { push(@Link_file, $_); } else { push(@Input_file, $_); @@ -2481,6 +2548,35 @@ arg: while($_ = $args[0]) { \end{code} +When saving an intermediate file (.hc or .s) away, we +have to prefix any OPTIONS found in the original source file. + +\begin{code} +sub saveIntermediate { + local ($final,$suffix,$tmp)= @_ ; + local ($to_do); + + # $final -- root of where to park ${final}.${suffix} + # $tmp -- temporary file where hsc put the intermediate file. + + # Delete the old file + $to_do = "$Rm ${final}.${suffix}"; &run_something($to_do, "Removing old .${suffix} file"); + + if ( $#File_options >= 0 ) { # OPTIONS found in Haskell source unit + # Add OPTION comment to the top of the generated .${suffix} file + open(TEMP, "> ${final}.${suffix}") || &tidy_up_and_die(1,"Can't open ${final}.${suffix}\n"); + print TEMP "/* OPTIONS " . join(' ',@File_options) . " */\n"; + close(TEMP); + print STDERR "Prepending OPTIONS: " . join(' ',@File_options) . " to ${final}.${suffix}\n" if $Verbose; + } + $to_do = "$Cat $tmp >> ${final}.${suffix}"; + &run_something($to_do, "Saving copy of .${suffix} file"); + +} + +\end{code} + + Command-line processor \begin{code} @@ -2496,13 +2592,13 @@ arg: while($_ = $Args[0]) { if (/^-\?$/ || /^--?help$/) { print $LongUsage; exit $Status; } #-----------version ---------------------------------------------------- - /^--version$/ && do { print STDERR "${PROJECTNAME}, version ${PROJECTVERSION}, patchlevel ${PROJECTPATCHLEVEL}\n"; exit $Status; }; + /^--version$/ && do { print STDERR "${ProjectName}, version ${ProjectVersion}, patchlevel ${ProjectPatchLevel}\n"; exit $Status; }; #---------- verbosity and such ----------------------------------------- /^-v$/ && do { $Verbose = '-v'; $Time = 'time'; next arg; }; #---------- what phases are to be run ---------------------------------- - /^-recomp/ && do { $Do_recomp_chkr = 1; next arg; }; + /^-(no-)?recomp/ && do { $Do_recomp_chkr = ($1 eq '') ? 1 : 0; next arg; }; /^-cpp$/ && do { $Cpp_flag_set = 1; next arg; }; # change the global default: @@ -2517,15 +2613,20 @@ arg: while($_ = $Args[0]) { next arg; }; # leave out actual C generation (debugging) [also turns off interface gen] - /^-hi$/ && do { $HiOnStdout = 1; $ProduceHi = '-hifile='; next arg; }; + + /^-hi$/ && do { $HiOnStdout = 1; $ProduceHi = '-hifile='; next arg; }; # _do_ generate an interface; usually used as: -noC -hi + /^-hi-with-(.*)$/ && do { $HiOnStdout = 1; $HiWith .= " $1" ; $ProduceHi = '-hifile='; next arg; }; + # limit ourselves to outputting a particular section. /^-nohi$/ && do { $ProduceHi = '-nohifile='; next arg; }; # don't generate an interface (even if generating C) - /^-hi-diffs$/ && do { $HiDiff_flag = 'normal'; next arg; }; - /^-hi-diffs-with-usages$/ && do { $HiDiff_flag = 'usages'; next arg; }; - /^-no-hi-diffs$/ && do { $HiDiff_flag = ''; next arg; }; + /^-hi-diffs$/ && do { $HiDiff_flag = 'normal'; next arg; }; + /^-hi-diffs-with-usages$/ && do { $HiDiff_flag = 'usages'; next arg; }; + /^-no-hi-diffs$/ && do { $HiDiff_flag = ''; next arg; }; + /^-keep-hi-diffs$/ && do { $Keep_HiDiffs = 1; next arg; }; + # show/disable diffs if the interface file changes /^-E$/ && do { push(@CcBoth_flags, '-E'); @@ -2665,7 +2766,8 @@ arg: while($_ = $Args[0]) { #--------- ticky/concurrent/parallel ----------------------------------- # we sort out the details a bit later on - /^-concurrent$/ && do { $CONCURing = 'c'; next arg; }; # concurrent Haskell + /^-concurrent$/ && do { $CONCURing = 'c'; &add_syslib('concurrent'); next arg; }; + # concurrent Haskell; implies -syslib conc /^-gransim$/ && do { $GRANing = 'g'; next arg; }; # GranSim /^-ticky$/ && do { $TICKYing = 't'; next arg; }; # ticky-ticky /^-parallel$/ && do { $PARing = 'p'; next arg; }; # parallel Haskell @@ -2705,26 +2807,23 @@ arg: while($_ = $Args[0]) { /^-syslib(.*)/ && do { local($syslib) = &grab_arg_arg(*Args,'-syslib',$1); print STDERR "$Pgm: no such system library (-syslib): $syslib\n", - $Status++ unless $syslib =~ /^(hbc|ghc|posix|contrib)$/; - - unshift(@SysImport_dir, - ${INSTALLING} - ? "$InstSysLibDir/$syslib/imports" - : "$TopPwd/hslibs/$syslib/src"); + $Status++ unless $syslib =~ /^(exts|misc|posix)$/; - if ( ${INSTALLING} ) { - push(@SysLibrary_dir, - ("$InstSysLibDir")); - } else { - push(@SysLibrary_dir, - ("$TopPwd/hslibs/$syslib" - ,"$TopPwd/hslibs/$syslib/cbits")); + # + # The posix library is a `special' in that it relies on + # the ghc system library (packed strings). Wielding our + # sledgehammer, the problem is solved by silently including + # the ghc system library as well. + # (ToDo: `nub' -syslib list) + # + &add_syslib($syslib); + if ( $syslib eq 'posix' ) { + &add_syslib('misc'); + } elsif ( $syslib eq 'misc' && + $TargetName =~ /-solaris2$/ ) { + # needed for Berkeley socket/nwork stuff. + push(@SysLibrary, '-lnsl'); } - - push(@SysLibrary, "-lHS$syslib"); - push(@SysLibrary, "-lHS${syslib}_cbits") - unless $syslib eq 'contrib'; #HACK! it has no cbits - next arg; }; #======================================================================= @@ -2748,7 +2847,8 @@ arg: while($_ = $Args[0]) { /^-optP(.*)$/ && do { push(@HsCpp_flags, $1); next arg; }; /^-optCrts(.*)$/&& do { push(@HsC_rts_flags, $1); next arg; }; /^-optC(.*)$/ && do { push(@HsC_flags, $1); next arg; }; - /^-optcpp(.*)$/ && do { push(@Cpp_define, $1); next arg; }; + /^-optp(.*)$/ && do { push(@HsP_flags, $1); next arg; }; + /^-optcpp(.*)$/ && do { push(@Cpp_define, $1); $Only_preprocess_hc = ($1 eq "-E"); next arg; }; /^-optc(.*)$/ && do { push(@CcBoth_flags, $1); next arg; }; /^-opta(.*)$/ && do { push(@As_flags, $1); next arg; }; /^-optl(.*)$/ && do { push(@Ld_flags, $1); next arg; }; @@ -2792,11 +2892,8 @@ arg: while($_ = $Args[0]) { /^-fticky-ticky$/ && do { push(@HsC_flags,$_); next arg; }; /^-fgransim$/ && do { push(@HsC_flags,$_); next arg; }; - /^-user-prelude-force/ && do { # ignore if not -user-prelude - next arg; }; - /^-split-objs/ && do { - if ( $TargetPlatform !~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|sparc)-/ ) { + if ( $TargetPlatform !~ /^(alpha|hppa1\.1|i386|m68k|mips|powerpc|rs6000|sparc)-/ ) { $SplitObjFiles = 0; print STDERR "WARNING: don't know how to split objects on this platform: $TargetPlatform\n`-split-objs' option ignored\n"; } else { @@ -2816,6 +2913,9 @@ arg: while($_ = $Args[0]) { push(@HsP_flags, '-N'); # push(@HsC_flags, '-fshow-import-specs'); + + # -fglasgow-exts implies -syslib exts + &add_syslib('exts'); next arg; }; @@ -2854,10 +2954,16 @@ arg: while($_ = $Args[0]) { && do { $Oopt_FoldrBuildInline .= ' -fdo-not-fold-back-append '; next arg; }; + # --------------- Renamer ------------- + + + /^-fno-prune-tydecls$/ && do { push(@HsC_flags, $_); next arg; }; + /^-fno-prune-instdecls$/ && do { push(@HsC_flags, $_); next arg; }; + # --------------- /^-fasm-(.*)$/ && do { $HscOut = '-S='; next arg; }; # force using nativeGen - /^-fvia-C$/ && do { $HscOut = '-C='; next arg; }; # force using C compiler + /^-fvia-[cC]$/ && do { $HscOut = '-C='; next arg; }; # force using C compiler # --------------- @@ -2868,6 +2974,9 @@ arg: while($_ = $Args[0]) { /^(-fmax-simplifier-iterations)(.*)$/ && do { $Oopt_MaxSimplifierIterations = $1 . &grab_arg_arg(*Args,$1, $2); next arg; }; + /^(-fshow-simplifier-progress)/ + && do { $Oopt_ShowSimplifierProgress = $1; + next arg; }; /^-fno-pedantic-bottoms$/ && do { $Oopt_PedanticBottoms = ''; next arg; }; @@ -2892,15 +3001,26 @@ arg: while($_ = $Args[0]) { # --------------- Warnings etc. ------ - /^-f(show-import-specs)/ + /^-fshow-import-specs/ && do { push(@HsC_flags, $_); next arg; }; - # for now, just -fwarn-name-shadowing - /^-fwarn-(.*)$/ && do { push(@HsC_flags, $_); next arg; }; + /^-fsignatures-required/ + && do { push(@HsC_flags, $_); next arg; }; + + /^-fwarn-(.*)$/ && do { push(@HsC_flags, $_); next arg; }; + /^-fno-(.*)$/ && do { push(@HsC_antiflags, "-f$1"); &squashHscFlag("-f$1"); next arg; }; + /^-W$/ && do { push(@HsC_flags, @MinusWOpts); next arg; }; + /^-Wall$/ && do { push(@HsC_flags, @MinusWallOpts); next arg; }; + /^(-Wnot|w)$/ && do { foreach (@Hsc_flags) { + /^-fwarn-(.*)$/ && do { $_=''; }; + }; + push(@HsC_antiflags, @StandardWarnings); + next arg; }; + # --------------- platform specific flags (for gcc mostly) ---------------- /^-mlong-calls$/ && do { # for GCC for HP-PA boxes, @@ -2930,6 +3050,7 @@ arg: while($_ = $Args[0]) { /^-d(dump|ppr)-/ && do { push(@HsC_flags, $_); next arg; }; /^-dverbose-(simpl|stg)/ && do { push(@HsC_flags, $_); next arg; }; /^-dshow-passes/ && do { push(@HsC_flags, $_); next arg; }; + /^-dshow-rn-stats/ && do { push(@HsC_flags, $_); next arg; }; /^-dshow-rn-trace/ && do { push(@HsC_flags, $_); next arg; }; /^-dsource-stats/ && do { push(@HsC_flags, $_); next arg; }; /^-dsimplifier-stats/ && do { push(@HsC_flags, $_); next arg; }; @@ -2962,7 +3083,7 @@ arg: while($_ = $Args[0]) { } next arg; }; - /^-(K|Rmax-(stk|stack)size)(.*)/ && do { + /^(-K|Rmax-(stk|stack)size)(.*)/ && do { local($flag) = $1; local($stk_size) = &grab_arg_arg(*Args,'-Rmax-stksize', $3); if ($stk_size =~ /(\d+)[Kk]$/) {