On Tue, 3 Dec 2019, Alexandre Oliva wrote:

> On Nov 14, 2019, Alexandre Oliva <ol...@adacore.com> wrote:
> 
> > In order to address this, I propose we add an internal option (not for
> > the driver), -dumpbase-ext, that names the extension to be discarded
> > from dumpbase to form aux output names.
> 
> Here's a WIP patch that implements much of the desired semantics.
> 
> I'm still struggling a bit with -gdwarf-split and -save-temps; -dumpbase
> and multiple inputs, -dumpdir as a prefix, and -flto + -dump*.
> 
> -gdwarf-split uses %b to strip debug info into the .dwo file, so it
> lands in the same location as the .o, rather than in a named -dumpdir as
> specified in the .o debug info skeleton.  I'm thinking of arranging for
> -dump* flags to affect %b and %B, just like -save-temps does.  I've
> reviewed all uses of %b and %B, and it looks like this would enable us
> to fix the .dwo naming mismatch without significant complication.
> 
> Which brings us to the next issue.  This would cause -dumpdir to
> override the -save-temps location.  This is arguably an improvement.  It
> might conflict with -save-temps=cwd, however.
> 
> I'm considering rejecting command lines that specify both an explicit
> -dumpdir and -save-temps=cwd, and in the absence of an explicit
> -dumpdir, arranging for -save-temps=cwd or -save-temps=obj to override
> what would otherwise be the default -dumpdir.
> 
> Or, for the sake of simplifying and bringing more sanity to the logic of
> naming extra output files, we could just discontinue -save-temps=*, and
> require -dumpdir ./ along with plain -save-temps to get the effects of
> -save-temps=cwd.

Making -save-temps=cwd essentially a short-cut to -save-temps -dumpdir ./
is fine I guess (we usually do not start to reject previously accepted
options).  Auto-magically splitting this via the 'Alias' mechanism
isn't (yet) supported I think (split one option into two others).

> 
> When compiling multiple inputs with a single -dumpbase, the current
> implementation arranges for each compilation to take an adjusted
> -dumpbase appending -<input> to the given dumpbase, minus extension.  An
> alternative would be to reject such compilations, just as we reject
> multiple compilations with a single object file named as output.  That
> feels excessive for -dumpbase, however.  OTOH, adjusting -dumpbase only
> when there are multiple inputs causes different behavior comparing:
> 
>   gcc -c foo.c -dumpbase foobar && gcc -c bar.c -dumpbase foobar
> 
> and
> 
>   gcc -c foo.c bar.c -dumpbase foobar
> 
> The latter will name outputs after foobar-foo and foobar-bar,
> respectively, whereas the former will overwrite outputs named foobar
> when compiling bar.c.  Under the proposal to modify %b according to
> -dump*, even object files would be named after an explicit -dumpbase,
> when -o is not explicitly specified.

I think rejecting option combinations that do not make much sense
or would introduce inconsistencies like this is better than trying
to invent creative things second-guessing what the user meant.

> Yet another thing I'm not so sure about is -dumpdir as a prefix, e.g.,
> in cases we're compiling multiple files and then linking them together,
> say 'gcc foo.c bar.c -o foobar', the proposal was to name dumps of the
> compilations after foobar-foo and foobar-bar, respectively.
> 
> If we use -dumpdir as a prefix to dump names, as we historically have,
> if it doesn't end with a slash (or any dir separator) then it could be
> used to specify the prefix for multiple outputs, as in the above.  So
> gcc -dumpdir foobar- foo.c bar.c -o foobar *could* be equivalent to the
> above.  I.e., an executable output name would affect the -dumpdir, but
> not the -dumpbase passed to the compiler, whereas -dumpbase would be
> derived from an asm or obj output or from input.
> 
> In the end, they're pasted together one way or the other, the difference
> is the ability to override one or the other.  E.g.,
> 
>   gcc -dumpbase foobar foo.c bar.c -c
> 
> could then be rejected, just as -o foo+bar.o would be, or foobar could
> be appended to the implicit -dumpdir and then override -dumpbase to
> foo.c or bar.c in each compilation, to get foobar-foo.o and foobar-bar.o
> outputs, getting the same as:
> 
>   gcc -dumpdir foobar- foo.c bar.c -c
> 
> and then
> 
>   gcc -dumpdir temp/foobar- foo.c bar.c -o foo+bar -save-temps
> 
> would still create and preserve .o (and .i and .s) named after
> foobar-foo and foobar-bar within temp, rather than foo+bar-foo and
> foo+bar-bar.

Hum.  I didn't notice -dumpdir is just a prefix and I wouldn't object
to make it errorneous if it doesn't specify an acutal directory.

I also note that neither -dumpdir nor -dumpbase are documented
in invoke.texi (as opposed to -auxbase and -auxbase-strip which
are not user-accessible as they are rejected by the driver).
Not sure if all this means we should document the altered behavior
or if we should take it as a hint we can alter behavior at will
(in future) ;)

> Now, the implementation in the patch below places the link output name,
> implicit or not, in the default -dumpbase rather than -dumpdir, so the
> last command above would create temp/foobar-foo+bar-foo.o and
> temp/foobar-foo+bar-bar.o.  It's this ability to override the
> executable-name prefix we're adding to outputs separately from -dumpbase
> that I find somewhat appealing, in that it enables even the effect of
> such prefixing to be canceled out with e.g. -dumpdir ./
> 
> Any thoughts for or against (or requests for clarification on :-) any of
> the above proposed changes?

I like the streamlining a lot, but yeah, looks like a quite messy area.
Thanks again for digging through all of this.

> As for -flto + -dump*, the problem is that lto-wrapper doesn't take any
> -dump* flags into account, it just overrides them all as if none had
> been specified, which is undesirable.  That's fixable, it's just that
> I haven't got to it yet.

Sure.

Thanks,
Richard.

> I haven't brought in the design/documentation into a .texi file yet.
> Please refer to posts upthread for the proposal.
>
> 
> Here's the WIP patch, FTR: 
> ---
>  gcc/ada/gcc-interface/lang-specs.h |    7 +
>  gcc/ada/switch.adb                 |    4 -
>  gcc/common.opt                     |   19 ++-
>  gcc/dwarf2out.c                    |    3 -
>  gcc/fortran/options.c              |    4 -
>  gcc/gcc.c                          |  213 
> ++++++++++++++++++++++--------------
>  gcc/lto-wrapper.c                  |   38 +++++-
>  gcc/opts.c                         |   35 ------
>  gcc/toplev.c                       |   36 +++++-
>  9 files changed, 211 insertions(+), 148 deletions(-)
> 
> diff --git a/gcc/ada/gcc-interface/lang-specs.h 
> b/gcc/ada/gcc-interface/lang-specs.h
> index 374fc1e..344fe64 100644
> --- a/gcc/ada/gcc-interface/lang-specs.h
> +++ b/gcc/ada/gcc-interface/lang-specs.h
> @@ -34,11 +34,10 @@
>   %{!S:%{!c:%e-c or -S required for Ada}}\
>   gnat1 %{I*} %{k8:-gnatk8} %{Wall:-gnatwa} %{w:-gnatws} %{!Q:-quiet}\
>      %{nostdinc*} %{nostdlib*}\
> -    -dumpbase %{.adb:%b.adb}%{.ads:%b.ads}%{!.adb:%{!.ads:%b.ada}}\
> -    %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b) -gnatd_A} \
> -    %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase 
> %b}}%{!c:%{!S:-auxbase %b}}} \
> -    %{O*} %{W*} %{w} %{p} %{pg:-p} %{d*} \
> +    %{fcompare-debug-second:-gnatd_A} \
> +    %{O*} %{W*} %{w} %{p} %{pg:-p} %{d*} %:dumps() \
>      %{coverage:-fprofile-arcs -ftest-coverage} "
> +/* -dumpbase %{.adb:%b.adb}%{.ads:%b.ads}%{!.adb:%{!.ads:%b.ada}} */
>  #if defined(TARGET_VXWORKS_RTP)
>     "%{fRTS=rtp|fRTS=rtp-smp|fRTS=ravenscar-cert-rtp:-mrtp} "
>  #endif
> diff --git a/gcc/ada/switch.adb b/gcc/ada/switch.adb
> index 7cdaa196..b6f4e00 100644
> --- a/gcc/ada/switch.adb
> +++ b/gcc/ada/switch.adb
> @@ -163,9 +163,9 @@ package body Switch is
>        return Is_Switch (Switch_Chars)
>          and then
>            (Switch_Chars (First .. Last) = "-param"        or else
> +           Switch_Chars (First .. Last) = "dumpdir"       or else
>             Switch_Chars (First .. Last) = "dumpbase"      or else
> -           Switch_Chars (First .. Last) = "auxbase-strip" or else
> -           Switch_Chars (First .. Last) = "auxbase");
> +           Switch_Chars (First .. Last) = "dumpbase-ext");
>     end Is_Internal_GCC_Switch;
>  
>     ---------------
> diff --git a/gcc/common.opt b/gcc/common.opt
> index 404b6aa..e37e324 100644
> --- a/gcc/common.opt
> +++ b/gcc/common.opt
> @@ -188,6 +188,12 @@ const char *main_input_basename
>  Variable
>  int main_input_baselength
>  
> +; The base name used for auxiliary output files.
> +; dump_base_name minus dump_base_ext.
> +
> +Variable
> +const char *aux_base_name
> +
>  ; Which options have been printed by --help.
>  Variable
>  char *help_printed
> @@ -254,6 +260,9 @@ Common Joined Alias(d)
>  -dumpbase
>  Common Separate Alias(dumpbase)
>  
> +-dumpbase-ext
> +Common Separate Alias(dumpbase-ext)
> +
>  -dumpdir
>  Common Separate Alias(dumpdir)
>  
> @@ -840,12 +849,6 @@ Common Separate Var(aux_info_file_name)
>  aux-info=
>  Common Joined Alias(aux-info)
>  
> -auxbase
> -Common Separate RejectDriver Var(aux_base_name)
> -
> -auxbase-strip
> -Common Separate RejectDriver
> -
>  coverage
>  Driver
>  
> @@ -860,6 +863,10 @@ dumpbase
>  Common Separate Var(dump_base_name)
>  -dumpbase <file>     Set the file basename to be used for dumps.
>  
> +dumpbase-ext
> +Common Separate Var(dump_base_ext)
> +-dumpbase-ext .<ext>    Drop a trailing .<ext> from the dump basename to 
> name auxiliary output files.
> +
>  dumpdir
>  Common Separate Var(dump_dir_name)
>  -dumpdir <dir>       Set the directory name to be used for dumps.
> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
> index 6fb345b..06154d9 100644
> --- a/gcc/dwarf2out.c
> +++ b/gcc/dwarf2out.c
> @@ -24466,9 +24466,8 @@ gen_producer_string (void)
>        case OPT_o:
>        case OPT_d:
>        case OPT_dumpbase:
> +      case OPT_dumpbase_ext:
>        case OPT_dumpdir:
> -      case OPT_auxbase:
> -      case OPT_auxbase_strip:
>        case OPT_quiet:
>        case OPT_version:
>        case OPT_v:
> diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
> index f7a5299c..6a4b9eb 100644
> --- a/gcc/fortran/options.c
> +++ b/gcc/fortran/options.c
> @@ -833,8 +833,8 @@ gfc_get_option_string (void)
>          case OPT_o:
>          case OPT_d:
>          case OPT_dumpbase:
> +        case OPT_dumpbase_ext:
>          case OPT_dumpdir:
> -        case OPT_auxbase:
>          case OPT_quiet:
>          case OPT_version:
>          case OPT_fintrinsic_modules_path:
> @@ -859,8 +859,8 @@ gfc_get_option_string (void)
>          case OPT_o:
>          case OPT_d:
>          case OPT_dumpbase:
> +        case OPT_dumpbase_ext:
>          case OPT_dumpdir:
> -        case OPT_auxbase:
>          case OPT_quiet:
>          case OPT_version:
>          case OPT_fintrinsic_modules_path:
> diff --git a/gcc/gcc.c b/gcc/gcc.c
> index 4428d50..b284842 100644
> --- a/gcc/gcc.c
> +++ b/gcc/gcc.c
> @@ -402,8 +402,8 @@ static const char *find_plugindir_spec_function (int, 
> const char **);
>  static const char *print_asm_header_spec_function (int, const char **);
>  static const char *compare_debug_dump_opt_spec_function (int, const char **);
>  static const char *compare_debug_self_opt_spec_function (int, const char **);
> -static const char *compare_debug_auxbase_opt_spec_function (int, const char 
> **);
>  static const char *pass_through_libs_spec_func (int, const char **);
> +static const char *dumps_spec_func (int, const char **);
>  static const char *replace_extension_spec_func (int, const char **);
>  static const char *greater_than_spec_func (int, const char **);
>  static const char *debug_level_greater_than_spec_func (int, const char **);
> @@ -642,7 +642,7 @@ proper position among the other output files.  */
>    "%{gsplit-dwarf: \n\
>         objcopy --extract-dwo \
>        %{c:%{o*:%*}%{!o*:%b%O}}%{!c:%U%O} \
> -      %{c:%{o*:%:replace-extension(%{o*:%*} .dwo)}%{!o*:%b.dwo}}%{!c:%b.dwo} 
> \n\
> +      %{c:%{o*:%.dwo%*}%{!o*:%b.dwo}}%{!c:%b.dwo} \n\
>         objcopy --strip-dwo \
>        %{c:%{o*:%*}%{!o*:%b%O}}%{!c:%U%O} \
>      }"
> @@ -1145,9 +1145,7 @@ static const char *cpp_debug_options = "%{d*}";
>  static const char *cc1_options =
>  "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are 
> incompatible}}\
>   %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
> - %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{aux-info*}\
> - %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)} \
> - %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase 
> %b}}}%{!c:%{!S:-auxbase %b}} \
> + %1 %{!Q:-quiet} %{d*} %{m*} %{aux-info*} %:dumps()\
>   %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
>   %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
>   %{Qn:-fno-ident} %{Qy:} %{-help:--help}\
> @@ -1642,9 +1640,8 @@ static const struct spec_function 
> static_spec_functions[] =
>    { "print-asm-header",              print_asm_header_spec_function },
>    { "compare-debug-dump-opt",        compare_debug_dump_opt_spec_function },
>    { "compare-debug-self-opt",        compare_debug_self_opt_spec_function },
> -  { "compare-debug-auxbase-opt", compare_debug_auxbase_opt_spec_function },
>    { "pass-through-libs",     pass_through_libs_spec_func },
> -  { "replace-extension",     replace_extension_spec_func },
> +  { "dumps",                    dumps_spec_func },
>    { "gt",                    greater_than_spec_func },
>    { "debug-level-gt",                debug_level_greater_than_spec_func },
>    { "fortran-preinclude-file",       find_fortran_preinclude_file},
> @@ -9787,8 +9784,6 @@ compare_debug_dump_opt_spec_function (int arg,
>    return ret;
>  }
>  
> -static const char *debug_auxbase_opt;
> -
>  /* %:compare-debug-self-opt spec function.  Expands to the options
>      that are to be passed in the second compilation of
>      compare-debug.  */
> @@ -9807,13 +9802,6 @@ compare_debug_self_opt_spec_function (int arg,
>    do_spec_2 ("%{c|S:%{o*:%*}}", NULL);
>    do_spec_1 (" ", 0, NULL);
>  
> -  if (argbuf.length () > 0)
> -    debug_auxbase_opt = concat ("-auxbase-strip ",
> -                             argbuf.last (),
> -                             NULL);
> -  else
> -    debug_auxbase_opt = NULL;
> -
>    return concat ("\
>  %<o %<MD %<MMD %<MF* %<MG %<MP %<MQ* %<MT* \
>  %<fdump-final-insns=* -w -S -o %j \
> @@ -9821,50 +9809,6 @@ compare_debug_self_opt_spec_function (int arg,
>  ", compare_debug_opt, NULL);
>  }
>  
> -/* %:compare-debug-auxbase-opt spec function.  Expands to the auxbase
> -    options that are to be passed in the second compilation of
> -    compare-debug.  It expects, as an argument, the basename of the
> -    current input file name, with the .gk suffix appended to it.  */
> -
> -static const char *
> -compare_debug_auxbase_opt_spec_function (int arg,
> -                                      const char **argv)
> -{
> -  char *name;
> -  int len;
> -
> -  if (arg == 0)
> -    fatal_error (input_location,
> -              "too few arguments to %%:compare-debug-auxbase-opt");
> -
> -  if (arg != 1)
> -    fatal_error (input_location,
> -              "too many arguments to %%:compare-debug-auxbase-opt");
> -
> -  if (compare_debug >= 0)
> -    return NULL;
> -
> -  len = strlen (argv[0]);
> -  if (len < 3 || strcmp (argv[0] + len - 3, ".gk") != 0)
> -    fatal_error (input_location, "argument to %%:compare-debug-auxbase-opt "
> -              "does not end in %<.gk%>");
> -
> -  if (debug_auxbase_opt)
> -    return debug_auxbase_opt;
> -
> -#define OPT "-auxbase "
> -
> -  len -= 3;
> -  name = (char*) xmalloc (sizeof (OPT) + len);
> -  memcpy (name, OPT, sizeof (OPT) - 1);
> -  memcpy (name + sizeof (OPT) - 1, argv[0], len);
> -  name[sizeof (OPT) - 1 + len] = '\0';
> -
> -#undef OPT
> -
> -  return name;
> -}
> -
>  /* %:pass-through-libs spec function.  Finds all -l options and input
>     file names in the lib spec passed to it, and makes a list of them
>     prepended with the plugin option to cause them to be passed through
> @@ -9908,34 +9852,143 @@ pass_through_libs_spec_func (int argc, const char 
> **argv)
>    return prepended;
>  }
>  
> -/* %:replace-extension spec function.  Replaces the extension of the
> -   first argument with the second argument.  */
> +static bool
> +not_actual_file_p (const char *name)
> +{
> +  return (strcmp (name, "-") == 0
> +       || strcmp (output_file, HOST_BIT_BUCKET) == 0);
> +}
>  
> +/* %:dumps spec function.  Take no arguments.
> +    Return -dumpdir, -dumpbase and -dumpbase-ext, if needed.  */
>  const char *
> -replace_extension_spec_func (int argc, const char **argv)
> +dumps_spec_func (int argc, const char **argv)
>  {
> -  char *name;
> -  char *p;
> -  char *result;
> +  bool found_dumpdir = false;
> +  const char *found_dumpbase = NULL;
> +  bool found_dumpext = false;
> +  bool found_cS = false;
> +  const char *oname = NULL;
>    int i;
>  
> -  if (argc != 2)
> -    fatal_error (input_location, "too few arguments to 
> %%:replace-extension");
> +  char *args[3] = { NULL, NULL, NULL };
> +  int nargs = 0;
>  
> -  name = xstrdup (argv[0]);
> +  if (argc != 0)
> +    fatal_error (input_location, "too few arguments for %%:dumps");
>  
> -  for (i = strlen (name) - 1; i >= 0; i--)
> -    if (IS_DIR_SEPARATOR (name[i]))
> -      break;
> +  for (i = 0; i < n_switches; i++)
> +    {
> +      const char *s = switches[i].part1;
> +      switch (s[0])
> +     {
> +     case 'c':
> +       if (!s[1] && check_live_switch (i, 1))
> +         found_cS = true;
> +       break;
>  
> -  p = strrchr (name + i + 1, '.');
> -  if (p != NULL)
> -      *p = '\0';
> +     case 'S':
> +       if (!s[1] && check_live_switch (i, 1))
> +         found_cS = true;
> +       break;
>  
> -  result = concat (name, argv[1], NULL);
> +     case 'o':
> +       if (!s[1] && check_live_switch (i, 1))
> +         oname = switches[i].args[0];
> +       break;
>  
> -  free (name);
> -  return result;
> +     case 'd':
> +       if (strncmp (s, "dump", 4) != 0)
> +         break;
> +       switch (s[4])
> +         {
> +         case 'd':
> +           if (strcmp (s + 4, "dir") == 0
> +               && check_live_switch (i, 7))
> +             found_dumpdir = true;
> +           break;
> +
> +         case 'b':
> +           if (strncmp (s + 4, "base", 4) == 0
> +               && check_live_switch (i, 8))
> +             {
> +               if (!s[8])
> +                 found_dumpbase = switches[i].args[0];
> +               else if (strcmp (s + 8, "-ext") == 0)
> +                 found_dumpext = true;
> +             }
> +           break;
> +
> +         default:
> +           break;
> +         }
> +
> +     default:
> +       break;
> +     }
> +    }
> +
> +  if (oname && not_actual_file_p (oname))
> +    oname = NULL;
> +
> +  char *dir = NULL;
> +  if (oname)
> +    {
> +      for (i = strlen (oname) - 1; i >= 0; i--)
> +     if (IS_DIR_SEPARATOR (oname[i]))
> +       break;
> +
> +      if (!found_dumpdir && i >= 0)
> +     {
> +       dir = xstrdup (oname);
> +       int j = i + 1;
> +
> +       do
> +         dir[j] = '\0';
> +       while (j > 0 && IS_DIR_SEPARATOR (oname[j]));
> +     }
> +
> +      oname += i + 1;
> +    }
> +
> +  /* A "./" would be redundant, so omit -dumpdir for NULL dir.  */
> +  if (!found_dumpdir && dir)
> +    args[nargs++] = concat (" -dumpdir ",
> +                         dir ? convert_white_space (dir) : "./",
> +                         NULL);
> +  free (dir);
> +
> +  char *ext = xstrdup (input_basename + basename_length);
> +
> +  if (!found_dumpbase || n_infiles > 1)
> +    {
> +      char *base = xstrdup (found_dumpbase ? found_dumpbase
> +                         : oname ? oname : found_cS ? input_basename : "a");
> +      char *p = *base ? strrchr (base + 1, '.') : NULL;
> +      if (p)
> +     *p = '\0';
> +
> +      if (!found_dumpbase && found_cS)
> +     p = concat (base, ext, NULL);
> +      else
> +     p = concat (base, "-", input_basename, NULL);
> +
> +      free (base);
> +      base = p;
> +
> +      args[nargs++] = concat (" -dumpbase ", convert_white_space (base), 
> NULL);
> +      free (base);
> +    }
> +
> +  if (!found_dumpext && *ext)
> +    args[nargs++] = concat (" -dumpbase-ext ", convert_white_space (ext), 
> NULL);
> +  free (ext);
> +
> +  const char *ret = concat (args[0], args[1], args[2], NULL);
> +  while (nargs > 0)
> +    free (args[--nargs]);
> +
> +  return ret;
>  }
>  
>  /* Returns "" if ARGV[ARGC - 2] is greater than ARGV[ARGC-1].
> @@ -10085,7 +10138,7 @@ convert_white_space (char *orig)
>       }
>        free (orig);
>        return new_spec;
> -  }
> +    }
>    else
>      return orig;
>  }
> @@ -10264,8 +10317,6 @@ driver::finalize ()
>    mdswitches = NULL;
>    n_mdswitches = 0;
>  
> -  debug_auxbase_opt = NULL;
> -
>    used_arg.finalize ();
>  }
>  
> diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
> index 9a7bbd0..7099e6b 100644
> --- a/gcc/lto-wrapper.c
> +++ b/gcc/lto-wrapper.c
> @@ -1250,6 +1250,7 @@ run_gcc (unsigned argc, char *argv[])
>    const char **argv_ptr;
>    char *list_option_full = NULL;
>    const char *linker_output = NULL;
> +  const char *linker_output_or_a = "a";
>    const char *collect_gcc, *collect_gcc_options;
>    int parallel = 0;
>    int jobserver = 0;
> @@ -1462,6 +1463,21 @@ run_gcc (unsigned argc, char *argv[])
>         obstack_ptr_grow (&argv_obstack, output_dir);
>       }
>  
> +      obstack_ptr_grow (&argv_obstack, "-dumpbase-ext");
> +      obstack_ptr_grow (&argv_obstack, ".");
> +
> +      obstack_ptr_grow (&argv_obstack, "-dumpbase");
> +      linker_output_or_a = linker_output;
> +    }
> +  else
> +    {
> +      static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
> +      obstack_ptr_grow (&argv_obstack, "-dumpdir");
> +      obstack_ptr_grow (&argv_obstack, current_dir);
> +
> +      obstack_ptr_grow (&argv_obstack, "-dumpbase-ext");
> +      obstack_ptr_grow (&argv_obstack, ".");
> +
>        obstack_ptr_grow (&argv_obstack, "-dumpbase");
>      }
>  
> @@ -1578,7 +1594,7 @@ cont1:
>         strcat (flto_out, ".lto.o");
>       }
>        else
> -     flto_out = make_temp_file (".lto.o");
> +     flto_out = make_temp_file_with_prefix ("a.", ".lto.o");
>        obstack_ptr_grow (&argv_obstack, "-o");
>        obstack_ptr_grow (&argv_obstack, flto_out);
>      }
> @@ -1588,11 +1604,11 @@ cont1:
>        size_t list_option_len = strlen (list_option);
>        char *tmp;
>  
> -      if (linker_output)
> +      if (linker_output_or_a)
>       {
> -       char *dumpbase = (char *) xmalloc (strlen (linker_output)
> +       char *dumpbase = (char *) xmalloc (strlen (linker_output_or_a)
>                                            + sizeof (".wpa") + 1);
> -       strcpy (dumpbase, linker_output);
> +       strcpy (dumpbase, linker_output_or_a);
>         strcat (dumpbase, ".wpa");
>         obstack_ptr_grow (&argv_obstack, dumpbase);
>       }
> @@ -1607,10 +1623,10 @@ cont1:
>        else
>       {
>         char *prefix = NULL;
> -       if (linker_output)
> +       if (linker_output_or_a)
>           {
> -           prefix = (char *) xmalloc (strlen (linker_output) + 2);
> -           strcpy (prefix, linker_output);
> +           prefix = (char *) xmalloc (strlen (linker_output_or_a) + 2);
> +           strcpy (prefix, linker_output_or_a);
>             strcat (prefix, ".");
>           }
>  
> @@ -1781,14 +1797,14 @@ cont:
>         output_name = XOBFINISH (&env_obstack, char *);
>  
>         /* Adjust the dumpbase if the linker output file was seen.  */
> -       if (linker_output)
> +       if (linker_output_or_a)
>           {
>             char *dumpbase
> -               = (char *) xmalloc (strlen (linker_output)
> +               = (char *) xmalloc (strlen (linker_output_or_a)
>                                     + sizeof (DUMPBASE_SUFFIX) + 1);
>             snprintf (dumpbase,
> -                     strlen (linker_output) + sizeof (DUMPBASE_SUFFIX),
> -                     "%s.ltrans%u", linker_output, i);
> +                     strlen (linker_output_or_a) + sizeof (DUMPBASE_SUFFIX),
> +                     "%s.ltrans%u", linker_output_or_a, i);
>             argv_ptr[0] = dumpbase;
>           }
>  
> diff --git a/gcc/opts.c b/gcc/opts.c
> index 3c53fbe..411652c 100644
> --- a/gcc/opts.c
> +++ b/gcc/opts.c
> @@ -845,30 +845,6 @@ finish_options (struct gcc_options *opts, struct 
> gcc_options *opts_set,
>       /* We have a DUMP_DIR_NAME, prepend that.  */
>       opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name,
>                                             opts->x_dump_base_name, NULL);
> -      else if (opts->x_aux_base_name
> -            && strcmp (opts->x_aux_base_name, HOST_BIT_BUCKET) != 0)
> -     /* AUX_BASE_NAME is set and is not the bit bucket.  If it
> -        contains a directory component, prepend those directories.
> -        Typically this places things in the same directory as the
> -        object file.  */
> -     {
> -       const char *aux_base;
> -
> -       base_of_path (opts->x_aux_base_name, &aux_base);
> -       if (opts->x_aux_base_name != aux_base)
> -         {
> -           int dir_len = aux_base - opts->x_aux_base_name;
> -           char *new_dump_base_name
> -             = XOBNEWVEC (&opts_obstack, char,
> -                          strlen (opts->x_dump_base_name) + dir_len + 1);
> -
> -           /* Copy directory component from OPTS->X_AUX_BASE_NAME.  */
> -           memcpy (new_dump_base_name, opts->x_aux_base_name, dir_len);
> -           /* Append existing OPTS->X_DUMP_BASE_NAME.  */
> -           strcpy (new_dump_base_name + dir_len, opts->x_dump_base_name);
> -           opts->x_dump_base_name = new_dump_base_name;
> -         }
> -     }
>  
>        /* It is definitely prefixed now.  */
>        opts->x_dump_base_name_prefixed = true;
> @@ -2314,17 +2290,6 @@ common_handle_option (struct gcc_options *opts,
>        opts->x_flag_gen_aux_info = 1;
>        break;
>  
> -    case OPT_auxbase_strip:
> -      {
> -     char *tmp = xstrdup (arg);
> -     strip_off_ending (tmp, strlen (tmp));
> -     if (tmp[0])
> -       opts->x_aux_base_name = tmp;
> -     else
> -       free (tmp);
> -      }
> -      break;
> -
>      case OPT_d:
>        decode_d_option (arg, opts, loc, dc);
>        break;
> diff --git a/gcc/toplev.c b/gcc/toplev.c
> index 059046f..0c6e096 100644
> --- a/gcc/toplev.c
> +++ b/gcc/toplev.c
> @@ -796,8 +796,8 @@ print_switch_values (print_switch_fn_type print_fn)
>       case OPT_o:
>       case OPT_d:
>       case OPT_dumpbase:
> +     case OPT_dumpbase_ext:
>       case OPT_dumpdir:
> -     case OPT_auxbase:
>       case OPT_quiet:
>       case OPT_version:
>         /* Ignore these.  */
> @@ -1401,18 +1401,44 @@ process_options (void)
>    if (flag_short_enums == 2)
>      flag_short_enums = targetm.default_short_enums ();
>  
> +  if (dump_base_ext)
> +    ;
> +  else if (main_input_filename)
> +    {
> +      const char *name = lbasename (main_input_filename);
> +      const char *ext = strrchr (name, '.');
> +      if (ext)
> +     dump_base_ext = ext;
> +      else
> +     dump_base_ext = "";
> +    }
> +  else
> +    dump_base_ext = "";
> +
>    /* Set aux_base_name if not already set.  */
>    if (aux_base_name)
>      ;
> -  else if (main_input_filename)
> +  else if (dump_base_name)
>      {
> -      char *name = xstrdup (lbasename (main_input_filename));
> +      const char *name = dump_base_name;
> +      int nlen, len;
> +
> +      if (dump_base_ext && (len = strlen (dump_base_ext))
> +       && (nlen = strlen (name)) && nlen > len
> +       && strcmp (name + nlen - len, dump_base_ext) == 0)
> +     {
> +       char *p = xstrdup (name);
> +       p[nlen - len] = '\0';
> +       name = (const char *) xrealloc (p, nlen - len + 1);
> +     }
>  
> -      strip_off_ending (name, strlen (name));
>        aux_base_name = name;
>      }
>    else
> -    aux_base_name = "gccaux";
> +    {
> +      if (dump_dir_name)
> +      aux_base_name = "gccaux";
> +    }
>  
>  #ifndef HAVE_isl
>    if (flag_graphite
> 
> 
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)

Reply via email to