+ # show/disable diffs if the interface file changes
+
+ /^-E$/ && do { push(@CcBoth_flags, '-E');
+ $Only_preprocess_C = 1;
+ $Do_as = 0; $Do_lnkr = 0; next arg; };
+ # stop after preprocessing C
+ /^-M$/ && do { $Only_generate_deps = 1; $Do_as = 0; $Do_lnkr = 0; next arg; };
+ # only generate dependency information.
+ /^-S$/ && do { $Do_as = 0; $Do_lnkr = 0; next arg; };
+ # stop after generating assembler
+
+ /^-c$/ && do { $Do_lnkr = 0; next arg; };
+ # stop after generating .o files
+
+ /^-link-chk$/ && do { $LinkChk = 1; next arg; };
+ /^-no-link-chk$/ && do { $LinkChk = 0; next arg; };
+ # don't do consistency-checking after a link
+
+ /^-tmpdir$/ && do { $Tmp_prefix = &grab_arg_arg(*Args,'-tmpdir', '');
+ $Tmp_prefix = "$Tmp_prefix/ghc$$";
+ $ENV{'TMPDIR'} = $Tmp_prefix; # for those who use it...
+ next arg; };
+ # use an alternate directory for temp files
+
+ #---------- redirect output --------------------------------------------
+
+ # -o <file>; applies to the last phase, whatever it is
+ # "-o -" sends it to stdout
+ # if <file> has a directory component, that dir must already exist
+
+ /^-odir$/ && do { $Specific_output_dir = &grab_arg_arg(*Args,'-odir', '');
+ #
+ # Hack, of the worst sort: don't do validation of
+ # odir argument if you're using -M (dependency generation).
+ #
+ if ( ! $Only_generate_deps && ! -d $Specific_output_dir) {
+ print STDERR "$Pgm: -odir: no such directory: $Specific_output_dir\n";
+ $Status++;
+ }
+ next arg; };
+
+ /^-o$/ && do { $Specific_output_file = &grab_arg_arg(*Args,'-o', '');
+ if ($Specific_output_file ne '-'
+ && $Specific_output_file =~ /(.*)\/[^\/]*$/) {
+ local($dir_part) = $1;
+ if (! -d $dir_part) {
+ print STDERR "$Pgm: no such directory: $dir_part\n";
+ $Status++;
+ }
+ }
+ next arg; };
+
+ # NB: -isuf not documented yet (because it doesn't work yet)
+ /^-isuf$/ && do { $Isuffix = &grab_arg_arg(*Args,'-isuf', '');
+ if ($Isuffix =~ /\./ ) {
+ print STDERR "$Pgm: -isuf suffix shouldn't contain a .\n";
+ $Status++;
+ }
+ next arg; };
+
+ /^-osuf$/ && do { $Osuffix = &grab_arg_arg(*Args,'-osuf', '');
+ if ($Osuffix =~ /\./ ) {
+ print STDERR "$Pgm: -osuf suffix shouldn't contain a .\n";
+ $Status++;
+ }
+ next arg; };
+
+ # -ohi <file>; send the interface to <file>; "-ohi -" to send to stdout
+ /^-ohi$/ && do { $Specific_hi_file = &grab_arg_arg(*Args,'-ohi', '');
+ if ($Specific_hi_file ne '-'
+ && $Specific_hi_file =~ /(.*)\/[^\/]*$/) {
+ local($dir_part) = $1;
+ if (! -d $dir_part) {
+ print STDERR "$Pgm: no such directory: $dir_part\n";
+ $Status++;
+ }
+ }
+ next arg; };
+
+ # The suffix to use when looking for interface files
+ /^-hisuf$/ && do { $HiSuffix = &grab_arg_arg(*Args,'-hisuf', '');
+ if ($HiSuffix =~ /\./ ) {
+ print STDERR "$Pgm: -hisuf suffix shouldn't contain a .\n";
+ $Status++;
+ }
+ next arg; };
+ # ToDo: remove, not a `normal' user thing to do (should be automatic)
+ /^-hisuf-prelude$/ && do { $HiSuffix_prelude = &grab_arg_arg(*Args,'-hisuf-prelude', '');
+ if ($HiSuffix =~ /\./ ) {
+ print STDERR "$Pgm: -hisuf-prelude suffix shouldn't contain a .\n";
+ $Status++;
+ }
+ next arg; };
+ /^-odump$/ && do { $Specific_dump_file = &grab_arg_arg(*Args,'-odump', '');
+ if ($Specific_dump_file =~ /(.*)\/[^\/]*$/) {
+ local($dir_part) = $1;
+ if (! -d $dir_part) {
+ print STDERR "$Pgm: no such directory: $dir_part\n";
+ $Status++;
+ }
+ }
+ next arg; };
+
+ #-------------- scc & Profiling Stuff ----------------------------------
+
+ /^-prof$/ && do { $PROFing = 'p'; next arg; }; # profiling -- details later!
+
+ /^-auto/ && do {
+ # generate auto SCCs on top level bindings
+ # -auto-all = all top level bindings
+ # -auto = only top level exported bindings
+ $PROFauto = ( /-all/ )
+ ? '-fauto-sccs-on-all-toplevs'
+ : '-fauto-sccs-on-exported-toplevs';
+ next arg; };
+
+ /^-caf-all/ && do { # generate individual CAF SCC annotations
+ $PROFcaf = '-fauto-sccs-on-individual-cafs';
+ next arg; };
+
+ /^-ignore-scc$/ && do {
+ # forces ignore of scc annotations even if profiling
+ $PROFignore_scc = '-W';
+ next arg; };
+
+ /^-G(.*)$/ && do { push(@HsC_flags, "-G=$1"); # set group for cost centres
+ next arg; };
+
+ /^-unprof-scc-auto/ && do {
+ # generate auto SCCs on top level bindings when not profiling.
+ # Used to measure optimisation effects of presence of sccs.
+ $UNPROFscc_auto = ( /-all/ )
+ ? '-fauto-sccs-on-all-toplevs'
+ : '-fauto-sccs-on-exported-toplevs';
+ next arg; };
+
+ #--------- ticky/concurrent/parallel -----------------------------------
+ # we sort out the details a bit later on
+
+ /^-concurrent$/ && do { $CONCURing = 'c'; &add_syslib('concurrent'); next arg; };
+ # concurrent Haskell; implies -syslib conc
+ /^-gransim$/ && do { $GRANing = 'g'; &add_syslib('concurrent'); next arg; }; # GranSim
+ /^-ticky$/ && do { $TICKYing = 't'; next arg; }; # ticky-ticky
+ /^-parallel$/ && do { $PARing = 'p'; &add_syslib('concurrent'); next arg; }; # parallel Haskell
+
+ #-------------- "user ways" --------------------------------------------
+
+ (/^-user-setup-([a-oA-Z])$/ ) &&
+ do {
+ /^-user-setup-([a-oA-Z])$/ && do { $BuildTag = "_$1"; };
+
+ local($stuff) = $UserSetupOpts{$BuildTag};
+ local(@opts) = split(/\s+/, $stuff);
+
+ # feed relevant ops into the arg-processing loop (if any)
+ unshift(@Args, @opts) if $#opts >= 0;
+
+ next arg; };
+
+ #---------- set search paths for libraries and things ------------------
+
+ # we do -i just like HBC (-i clears the list; -i<colon-separated-items>
+ # prepends the items to the list); -I is for including C .h files.
+
+ /^-i$/ && do { @Import_dir = (); # import path cleared!
+ @SysImport_dir = ();
+ print STDERR "WARNING: import paths cleared by `-i'\n";
+ next arg; };
+
+ /^-i(.*)/ && do { local(@new_items)
+ = split( /:/, &grab_arg_arg(*Args,'-i', $1));
+ unshift(@Import_dir, @new_items);
+ next arg; };
+
+ /^-I(.*)/ && do { push(@Include_dir, &grab_arg_arg(*Args,'-I', $1)); next arg; };
+ /^-L(.*)/ && do { push(@UserLibrary_dir, &grab_arg_arg(*Args,'-L', $1)); next arg; };
+ /^-l(.*)/ && do { push(@UserLibrary,'-l'.&grab_arg_arg(*Args,'-l', $1)); next arg; };
+
+ /^-syslib(.*)/ && do { local($syslib) = &grab_arg_arg(*Args,'-syslib',$1);
+ &add_syslib($syslib);
+ next arg; };
+
+ #=======================================================================
+ # various flags that we can harmlessly send to one program or another
+ # (we will later "reclaim" some of the compiler ones now sent to gcc)
+ #=======================================================================
+
+ #---------- this driver itself (ghc) -----------------------------------
+ # these change what executable is run for each phase:
+ /^-pgmL(.*)$/ && do { $Unlit = $1; next arg; };
+ /^-pgmP(.*)$/ && do { $HsCpp = $1; next arg; };
+ /^-pgmC(.*)$/ && do { $HsC = $1; next arg; };
+ /^-pgmcO?(.*)$/ && do { $CcRegd = $1; next arg; }; # the O? for back compat
+ /^-pgma(.*)$/ && do { $As = $1; next arg; };
+ /^-pgml(.*)$/ && do { $Lnkr = $1; next arg; };
+ /^-pgmdep(.*)$/ && do { $MkDependHS = $1; next arg; };
+
+ #---------- the get-anything-through opts (all pgms) -------------------
+ # these allow arbitrary option-strings to go to any phase:
+ /^-optL(.*)$/ && do { push(@Unlit_flags, $1); next arg; };
+ /^-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; };
+ /^-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; };
+ /^-optdep(.*)$/ && do { push(@MkDependHS_flags, $1); next arg; };
+
+ #---------- Haskell C pre-processor (hscpp) ----------------------------
+ /^-D(.*)/ && do { push(@HsCpp_flags, "'-D".&grab_arg_arg(*Args,'-D',$1)."'"); next arg; };
+ /^-U(.*)/ && do { push(@HsCpp_flags, "'-U".&grab_arg_arg(*Args,'-U',$1)."'"); next arg; };
+
+ #---------- post-Haskell "assembler"------------------------------------
+ /^-ddump-raw-asm$/ && do { $Dump_raw_asm = 1; next arg; };
+ /^-ddump-asm-splitting-info$/ && do { $Dump_asm_splitting_info = 1; next arg; };
+
+ #---------- Haskell compiler (hsc) -------------------------------------
+
+ /^-keep-hc-files?-too$/ && do { $Keep_hc_file_too = 1; next arg; };
+ /^-keep-s-files?-too$/ && do { $Keep_s_file_too = 1; next arg; };
+
+ /^-fhaskell-1\.3$/ && do { next arg; }; # a no-op right now
+
+ /^-fignore-interface-pragmas$/ && do { push(@HsC_flags, $_); next arg; };
+
+ /^-fno-implicit-prelude$/ && do { $NoImplicitPrelude= 1; push(@HsC_flags, $_); next arg; };
+ # don't do stack checking using page fault `trick'.
+ # (esoteric).
+ /^-fstack-check$/ && do { $StkChkByPageFaultOK = 0; next arg; };
+ #
+ # have the compiler proper generate concurrent code,
+ # really only used when you want to configure your own
+ # special user compilation way. (Use -concurrent when
+ # compiling `Concurrent Haskell' programs).
+ #
+ # (ditto for -fgransim, fscc-profiling and -fticky-ticky)
+ #
+ /^-fconcurrent$/ && do { push(@HsC_flags,$_); next arg; };
+ /^-fscc-profiling$/ && do { push(@HsC_flags,$_); next arg; };
+ /^-fticky-ticky$/ && do { push(@HsC_flags,$_); next arg; };
+ /^-fgransim$/ && do { push(@HsC_flags,$_); next arg; };
+
+ /^-split-objs/ && do {
+ 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 {
+ $SplitObjFiles = 1;
+ $HscOut = '-C=';
+
+ push(@HsC_flags, "-fglobalise-toplev-names");
+ push(@CcBoth_flags, '-DUSE_SPLIT_MARKERS');
+
+ require('ghc-split.prl')
+ || &tidy_up_and_die(1,"$Pgm: panic: can't load ghc-split.prl!\n");
+ }
+ next arg; };
+
+ /^-fallow-overlapping-instances$/ && do { push(@HsC_flags, $_);
+ next arg; };
+ /^-fglasgow-exts$/
+ && do { push(@HsC_flags, $_);
+ push(@HsP_flags, '-N');
+
+ # -fglasgow-exts implies -syslib exts
+ &add_syslib('exts');
+
+ next arg; };
+
+ /^-fspeciali[sz]e-unboxed$/
+ && do { $Oopt_DoSpecialise = '-fspecialise';
+ $Oopt_SpecialiseUnboxed = '-fspecialise-unboxed';
+ next arg; };
+ /^-fspeciali[sz]e$/
+ && do { $Oopt_DoSpecialise = '-fspecialise'; next arg; };
+ /^-fno-speciali[sz]e$/
+ && do { $Oopt_DoSpecialise = ''; next arg; };
+
+
+# Now the foldr/build options, which are *on* by default (for -O).
+
+ /^-ffoldr-build$/
+ && do { $Oopt_FoldrBuild = 1;
+ $Oopt_FB_Support = '-fdo-arity-expand';
+ #print "Yes F/B\n";
+ next arg; };
+
+ /^-fno-foldr-build$/
+ && do { $Oopt_FoldrBuild = 0;
+ $Oopt_FB_Support = '';
+ next arg; };
+
+ /^-fno-foldr-build-rule$/
+ && do { $Oopt_FoldrBuild = 0;
+ next arg; };
+
+ /^-fno-enable-tech$/
+ && do { $Oopt_FB_Support = '';
+ next arg; };
+
+ /^-fno-snapback-to-append$/
+ && 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-[cC]$/ && do { $HscOut = '-C='; next arg; }; # force using C compiler
+
+ # ---------------
+
+ /^-funfolding-.*$/
+ && do { push(@HsC_flags, $_); next arg };
+
+ /^-funfold-casms-in-hi-file$/
+ && do { push(@HsC_flags, $_); next arg };
+
+ /^(-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; };
+
+ /^-fdo-monad-eta-expansion$/
+ && do { $Oopt_MonadEtaExpansion = $_; next arg; };
+
+ /^-fno-let-from-(case|app|strict-let)$/ # experimental, really (WDP 95/10)
+ && do { push(@HsC_flags, $_); next arg; };
+
+ /^(-freturn-in-regs-threshold)(.*)$/
+ && do { local($what) = $1;
+ local($num) = &grab_arg_arg(*Args,$what, $2);
+ if ($num < 2 || $num > 8) {
+ die "Bad experimental flag: $_\n";
+ } else {
+ $HscOut = '-C='; # force using C compiler
+ push(@HsC_flags, "$what$num");
+ push(@CcRegd_flags, "-D__STG_REGS_AVAIL__=$num");
+ }
+ next arg; };
+
+ # --------------- Warnings etc. ------
+
+ /^-fshow-import-specs/
+ && do { push(@HsC_flags, $_); next arg; };