Message ID | Pine.LNX.4.64.1009111215060.9335@digraph.polyomino.org.uk |
---|---|
State | New |
Headers | show |
On Sat, Sep 11, 2010 at 2:15 PM, Joseph S. Myers <joseph@codesourcery.com> wrote: > This patch, based on a tree with > <http://gcc.gnu.org/ml/gcc-patches/2010-09/msg00669.html> (pending > review) applied, makes prune_options work with decoded options and > moves it into decode_cmdline_options_to_array, so ensuring that both > the driver and the core compilers decode options as the next step in > argv processing after calling expandargv and so that they decode > the sequence of options in the same way (subject to any differences > arising from different lang_mask values). This also means that > prune_options will now automatically work properly with option > aliases. > > prune_options should only be needed in the driver, for specs > processing; option handlers are meant to handle successive mutually > overriding options properly, so that prune_options is only needed for > specs. But if any corner case arises where prune_options affects how > the core compiler interprets options, consistency between the driver > and the core compiler seems desirable. (Option handlers still need to > handle overriding options rather than relying on the previous pruning, > in order to work properly with the attributes that cause options to be > processed for particular functions.) > > The main complication in making the driver start using decoded options > as early as it should is GCC_DRIVER_HOST_INITIALIZATION. This is a > macro with rather poorly defined semantics. Documented as a host > macro, it is in fact defined both as a host macro (for DJGPP) and as a > target macro (for Cygwin, Xtensa bare-metal and Darwin native). This > would cause conflicts if a cross compiler is built from DJGPP to > Cygwin or Xtensa bare-metal. The macro does not take parameters; > instead, it uses the caller's local variables, such as argc and argv. > The definition in xtensa/elf.h should probably not be there (I see no > good reason for xtensa-elf to have different directory search logic > from all other *-elf targets). This patch fixes the affected > definitions of GCC_DRIVER_HOST_INITIALIZATION, those for Cygwin and > Darwin, to work with decoded options. Yet another relic of -b and -V > handling, in darwin_default_min_version, is removed. > > Bootstrapped with no regressions on x86_64-unknown-linux-gnu. Tested > building xgcc for a cross to i686-cygwin and for a native Darwin > compiler (build = x86_64-unknown-linux-gnu, host = target = > i686-darwin) as a sanity check on those changes. OK to commit? Ok. Thanks, Richard. > 2010-09-11 Joseph Myers <joseph@codesourcery.com> > > * opts-common.c (prune_options): Make static. Work with decoded > options. > (decode_cmdline_options_to_array): Call prune_options. Don't > resize option array here. > * opts.h (prune_options): Remove prototype. > * gcc.c (process_command): Take decoded options; don't call > decode_cmdline_options_to_array here. Use decoded options for > argv[0]. > (main): Call decode_cmdline_options_to_array here instead of > prune_options. Update call to process_command. > * config/darwin-driver.c: Include opts.h. > (darwin_default_min_version): Work with decoded options. Don't > handle -b or -V here. > * config/darwin.h (darwin_default_min_version): Update prototype. > (GCC_DRIVER_HOST_INITIALIZATION): Update call to > darwin_default_min_version. > * config/i386/cygwin.h (mingw_scan): Update prototype. > (GCC_DRIVER_HOST_INITIALIZATION): Update call to mingw_scan. > * config/i386/cygwin1.c: Include opts.h. > (mingw_scan): Work with decoded options. > * config/i386/t-cygwin (cygwin1.o): Update dependencies. > * config/t-darwin (darwin-driver.o): Update dependencies. > > diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/darwin-driver.c gcc-mainline/gcc/config/darwin-driver.c > --- gcc-mainline-0trans/gcc/config/darwin-driver.c 2010-07-27 16:46:56.000000000 -0700 > +++ gcc-mainline/gcc/config/darwin-driver.c 2010-09-10 17:35:03.000000000 -0700 > @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. > #include "coretypes.h" > #include "tm.h" > #include "gcc.h" > +#include "opts.h" > #include <sys/sysctl.h> > #include "xregex.h" > > @@ -32,11 +33,12 @@ along with GCC; see the file COPYING3. > of the system on which the compiler is running. */ > > void > -darwin_default_min_version (int * argc_p, char *** argv_p) > +darwin_default_min_version (unsigned int *decoded_options_count, > + struct cl_decoded_option **decoded_options) > { > - const int argc = *argc_p; > - char ** const argv = *argv_p; > - int i; > + const unsigned int argc = *decoded_options_count; > + struct cl_decoded_option *const argv = *decoded_options; > + unsigned int i; > char osversion[32]; > size_t osversion_len = sizeof (osversion) - 1; > static int osversion_name[2] = { CTL_KERN, KERN_OSRELEASE }; > @@ -44,34 +46,17 @@ darwin_default_min_version (int * argc_p > char * version_pend; > int major_vers; > char minor_vers[6]; > - static char new_flag[sizeof ("-mmacosx-version-min=10.0.0") + 6]; > + static char new_flag[sizeof ("10.0.0") + 6]; > > /* If the command-line is empty, just return. */ > if (argc <= 1) > return; > - /* Don't do this if the user has specified -b or -V at the start > - of the command-line. */ > - if (argv[1][0] == '-' > - && (argv[1][1] == 'V' || > - ((argv[1][1] == 'b') && (NULL != strchr(argv[1] + 2,'-'))))) > - return; > > /* Don't do this if the user specified -mmacosx-version-min= or > -mno-macosx-version-min. */ > for (i = 1; i < argc; i++) > - if (argv[i][0] == '-') > - { > - const char * const p = argv[i]; > - if (strncmp (p, "-mno-macosx-version-min", 23) == 0 > - || strncmp (p, "-mmacosx-version-min", 20) == 0) > - return; > - > - /* It doesn't count if it's an argument to a different switch. */ > - if (p[0] == '-' > - && ((SWITCH_TAKES_ARG (p[1]) > (p[2] != 0)) > - || WORD_SWITCH_TAKES_ARG (p + 1))) > - i++; > - } > + if (argv[i].opt_index == OPT_mmacosx_version_min_) > + return; > > /* Retrieve the deployment target from the environment and insert > it as a flag. */ > @@ -84,12 +69,14 @@ darwin_default_min_version (int * argc_p > to ignore the environment variable, as if it was never set. */ > && macosx_deployment_target[0]) > { > - ++*argc_p; > - *argv_p = XNEWVEC (char *, *argc_p); > - (*argv_p)[0] = argv[0]; > - (*argv_p)[1] = concat ("-mmacosx-version-min=", > - macosx_deployment_target, NULL); > - memcpy (*argv_p + 2, argv + 1, (argc - 1) * sizeof (char *)); > + ++*decoded_options_count; > + *decoded_options = XNEWVEC (struct cl_decoded_option, > + *decoded_options_count); > + (*decoded_options)[0] = argv[0]; > + generate_option (OPT_mmacosx_version_min_, macosx_deployment_target, > + 1, CL_DRIVER, &(*decoded_options)[1]); > + memcpy (*decoded_options + 2, argv + 1, > + (argc - 1) * sizeof (struct cl_decoded_option *)); > return; > } > } > @@ -128,17 +115,20 @@ darwin_default_min_version (int * argc_p > if (major_vers - 4 <= 4) > /* On 10.4 and earlier, the old linker is used which does not > support three-component system versions. */ > - sprintf (new_flag, "-mmacosx-version-min=10.%d", major_vers - 4); > + sprintf (new_flag, "10.%d", major_vers - 4); > else > - sprintf (new_flag, "-mmacosx-version-min=10.%d.%s", major_vers - 4, > + sprintf (new_flag, "10.%d.%s", major_vers - 4, > minor_vers); > > /* Add the new flag. */ > - ++*argc_p; > - *argv_p = XNEWVEC (char *, *argc_p); > - (*argv_p)[0] = argv[0]; > - (*argv_p)[1] = new_flag; > - memcpy (*argv_p + 2, argv + 1, (argc - 1) * sizeof (char *)); > + ++*decoded_options_count; > + *decoded_options = XNEWVEC (struct cl_decoded_option, > + *decoded_options_count); > + (*decoded_options)[0] = argv[0]; > + generate_option (OPT_mmacosx_version_min_, new_flag, > + 1, CL_DRIVER, &(*decoded_options)[1]); > + memcpy (*decoded_options + 2, argv + 1, > + (argc - 1) * sizeof (struct cl_decoded_option *)); > return; > > parse_failed: > diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/darwin.h gcc-mainline/gcc/config/darwin.h > --- gcc-mainline-0trans/gcc/config/darwin.h 2010-08-22 05:22:04.000000000 -0700 > +++ gcc-mainline/gcc/config/darwin.h 2010-09-10 13:45:48.000000000 -0700 > @@ -1059,9 +1059,10 @@ extern int flag_apple_kext; > #define TARGET_HAS_TARGETCM 1 > > #ifndef CROSS_DIRECTORY_STRUCTURE > -extern void darwin_default_min_version (int * argc, char *** argv); > +extern void darwin_default_min_version (unsigned int *decoded_options_count, > + struct cl_decoded_option **decoded_options); > #define GCC_DRIVER_HOST_INITIALIZATION \ > - darwin_default_min_version (&argc, &argv) > + darwin_default_min_version (&decoded_options_count, &decoded_options) > #endif /* CROSS_DIRECTORY_STRUCTURE */ > > /* The Apple assembler and linker do not support constructor priorities. */ > diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/i386/cygwin.h gcc-mainline/gcc/config/i386/cygwin.h > --- gcc-mainline-0trans/gcc/config/i386/cygwin.h 2010-09-02 04:45:25.000000000 -0700 > +++ gcc-mainline/gcc/config/i386/cygwin.h 2010-09-10 17:03:22.000000000 -0700 > @@ -252,12 +252,13 @@ char *cvt_to_mingw[] = > #undef GEN_CVT_ARRAY > #endif /*GEN_CVT_ARRAY*/ > > -void mingw_scan (int, const char * const *, const char **); > +void mingw_scan (unsigned int, const struct cl_decoded_option *, > + const char **); > #if 1 > #define GCC_DRIVER_HOST_INITIALIZATION \ > do \ > { \ > - mingw_scan(argc, (const char * const *) argv, &spec_machine); \ > + mingw_scan (decoded_options_count, decoded_options, &spec_machine); \ > } \ > while (0) > #else > @@ -277,7 +278,7 @@ do \ > add_prefix (&startfile_prefixes,\ > concat (standard_startfile_prefix, "w32api", NULL),\ > "GCC", PREFIX_PRIORITY_LAST, 0, NULL);\ > - mingw_scan(argc, (const char * const *) argv, &spec_machine); \ > + mingw_scan (decoded_options_count, decoded_options, &spec_machine); \ > } \ > while (0) > #endif > diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/i386/cygwin1.c gcc-mainline/gcc/config/i386/cygwin1.c > --- gcc-mainline-0trans/gcc/config/i386/cygwin1.c 2009-03-28 00:38:15.000000000 -0700 > +++ gcc-mainline/gcc/config/i386/cygwin1.c 2010-09-10 17:03:32.000000000 -0700 > @@ -22,32 +22,42 @@ along with GCC; see the file COPYING3. > #include "system.h" > #include "coretypes.h" > #include "tm.h" > +#include "opts.h" > #include <string.h> > > void > -mingw_scan (int argc ATTRIBUTE_UNUSED, > - const char *const *argv, > +mingw_scan (unsigned int decoded_options_count, > + const struct cl_decoded_option *decoded_options, > const char **spec_machine) > { > + unsigned int i; > putenv (xstrdup ("GCC_CYGWIN_MINGW=0")); > > - while (*++argv) > - if (strcmp (*argv, "-mno-win32") == 0) > - putenv (xstrdup ("GCC_CYGWIN_WIN32=0")); > - else if (strcmp (*argv, "-mwin32") == 0) > - putenv (xstrdup ("GCC_CYGWIN_WIN32=1")); > - else if (strcmp (*argv, "-mno-cygwin") == 0) > + for (i = 1; i < decoded_options_count; i++) > + switch (decoded_options[i].opt_index) > { > - char *p = strstr (*spec_machine, "-cygwin"); > - if (p) > + case OPT_mwin32: > + if (decoded_options[i].value == 0) > + putenv (xstrdup ("GCC_CYGWIN_WIN32=0")); > + else > + putenv (xstrdup ("GCC_CYGWIN_WIN32=1")); > + break; > + > + case OPT_mcygwin: > + if (decoded_options[i].value == 0) > { > - int len = p - *spec_machine; > - char *s = XNEWVEC (char, strlen (*spec_machine) + 3); > - memcpy (s, *spec_machine, len); > - strcpy (s + len, "-mingw32"); > - *spec_machine = s; > + char *p = strstr (*spec_machine, "-cygwin"); > + if (p) > + { > + int len = p - *spec_machine; > + char *s = XNEWVEC (char, strlen (*spec_machine) + 3); > + memcpy (s, *spec_machine, len); > + strcpy (s + len, "-mingw32"); > + *spec_machine = s; > + } > + putenv (xstrdup ("GCC_CYGWIN_MINGW=1")); > } > - putenv (xstrdup ("GCC_CYGWIN_MINGW=1")); > + break; > } > return; > } > diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/i386/t-cygwin gcc-mainline/gcc/config/i386/t-cygwin > --- gcc-mainline-0trans/gcc/config/i386/t-cygwin 2010-09-02 04:45:25.000000000 -0700 > +++ gcc-mainline/gcc/config/i386/t-cygwin 2010-09-10 17:04:44.000000000 -0700 > @@ -1,4 +1,4 @@ > -# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2008, 2009 > +# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2008, 2009, 2010 > # Free Software Foundation, Inc. > # > # This file is part of GCC. > @@ -24,7 +24,7 @@ LIBGCC2_INCLUDES += -I$(srcdir)/../winsu > -I$(srcdir)/../winsup/cygwin/include > > cygwin1.o: $(srcdir)/config/i386/cygwin1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ > - $(TM_H) $(TM_P_H) > + $(TM_H) $(TM_P_H) opts.h > $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ > $(srcdir)/config/i386/cygwin1.c > > diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/t-darwin gcc-mainline/gcc/config/t-darwin > --- gcc-mainline-0trans/gcc/config/t-darwin 2010-06-07 02:48:58.000000000 -0700 > +++ gcc-mainline/gcc/config/t-darwin 2010-09-10 17:04:34.000000000 -0700 > @@ -36,7 +36,7 @@ darwin-f.o: $(srcdir)/config/darwin-f.c > $(srcdir)/config/darwin-f.c $(PREPROCESSOR_DEFINES) > > darwin-driver.o: $(srcdir)/config/darwin-driver.c \ > - $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) > + $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) opts.h > $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ > $(srcdir)/config/darwin-driver.c > > diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/gcc.c gcc-mainline/gcc/gcc.c > --- gcc-mainline-0trans/gcc/gcc.c 2010-09-08 03:32:16.000000000 -0700 > +++ gcc-mainline/gcc/gcc.c 2010-09-10 14:12:13.000000000 -0700 > @@ -261,7 +261,7 @@ static void display_help (void); > static void add_preprocessor_option (const char *, int); > static void add_assembler_option (const char *, int); > static void add_linker_option (const char *, int); > -static void process_command (int, const char **); > +static void process_command (unsigned int, struct cl_decoded_option *); > static int execute (void); > static void alloc_args (void); > static void clear_args (void); > @@ -3516,7 +3516,8 @@ driver_handle_option (const struct cl_de > Store its length in `n_switches'. */ > > static void > -process_command (int argc, const char **argv) > +process_command (unsigned int decoded_options_count, > + struct cl_decoded_option *decoded_options) > { > const char *temp; > char *temp1; > @@ -3524,8 +3525,7 @@ process_command (int argc, const char ** > char *(*get_relative_prefix) (const char *, const char *, > const char *) = NULL; > struct cl_option_handlers handlers; > - struct cl_decoded_option *decoded_options; > - unsigned int decoded_options_count, j; > + unsigned int j; > > GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX"); > > @@ -3546,9 +3546,6 @@ process_command (int argc, const char ** > } > } > > - decode_cmdline_options_to_array (argc, argv, CL_DRIVER, > - &decoded_options, &decoded_options_count); > - > /* Handle any -no-canonical-prefixes flag early, to assign the function > that builds relative prefixes. This function creates default search > paths that are needed later in normal option handling. */ > @@ -3565,17 +3562,18 @@ process_command (int argc, const char ** > get_relative_prefix = make_relative_prefix; > > /* Set up the default search paths. If there is no GCC_EXEC_PREFIX, > - see if we can create it from the pathname specified in argv[0]. */ > + see if we can create it from the pathname specified in > + decoded_options[0].arg. */ > > gcc_libexec_prefix = standard_libexec_prefix; > #ifndef VMS > /* FIXME: make_relative_prefix doesn't yet work for VMS. */ > if (!gcc_exec_prefix) > { > - gcc_exec_prefix = get_relative_prefix (argv[0], > + gcc_exec_prefix = get_relative_prefix (decoded_options[0].arg, > standard_bindir_prefix, > standard_exec_prefix); > - gcc_libexec_prefix = get_relative_prefix (argv[0], > + gcc_libexec_prefix = get_relative_prefix (decoded_options[0].arg, > standard_bindir_prefix, > standard_libexec_prefix); > if (gcc_exec_prefix) > @@ -3602,7 +3600,8 @@ process_command (int argc, const char ** > #endif > /* From this point onward, gcc_exec_prefix is non-null if the toolchain > is relocated. The toolchain was either relocated using GCC_EXEC_PREFIX > - or an automatically created GCC_EXEC_PREFIX from argv[0]. */ > + or an automatically created GCC_EXEC_PREFIX from > + decoded_options[0].arg. */ > > /* Do language-specific adjustment/addition of flags. */ > lang_specific_driver (&decoded_options, &decoded_options_count, > @@ -3898,7 +3897,7 @@ process_command (int argc, const char ** > ``make_relative_prefix'' is not compiled for VMS, so don't call it. */ > if (target_system_root && !target_system_root_changed && gcc_exec_prefix) > { > - char *tmp_prefix = get_relative_prefix (argv[0], > + char *tmp_prefix = get_relative_prefix (decoded_options[0].arg, > standard_bindir_prefix, > target_system_root); > if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0) > @@ -6109,6 +6108,8 @@ main (int argc, char **argv) > const char *p; > struct user_specs *uptr; > char **old_argv = argv; > + struct cl_decoded_option *decoded_options; > + unsigned int decoded_options_count; > > /* Initialize here, not in definition. The IRIX 6 O32 cc sometimes chokes > on ?: in file-scope variable initializations. */ > @@ -6127,7 +6128,10 @@ main (int argc, char **argv) > if (argv != old_argv) > at_file_supplied = true; > > - prune_options (&argc, &argv); > + decode_cmdline_options_to_array (argc, CONST_CAST2 (const char **, char **, > + argv), > + CL_DRIVER, > + &decoded_options, &decoded_options_count); > > #ifdef GCC_DRIVER_HOST_INITIALIZATION > /* Perform host dependent initialization when needed. */ > @@ -6217,7 +6221,7 @@ main (int argc, char **argv) > Make a table of specified input files (infiles, n_infiles). > Decode switches that are handled locally. */ > > - process_command (argc, CONST_CAST2 (const char **, char **, argv)); > + process_command (decoded_options_count, decoded_options); > > /* Initialize the vector of specs to just the default. > This means one element containing 0s, as a terminator. */ > diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/opts-common.c gcc-mainline/gcc/opts-common.c > --- gcc-mainline-0trans/gcc/opts-common.c 2010-09-08 06:56:29.000000000 -0700 > +++ gcc-mainline/gcc/opts-common.c 2010-09-10 14:47:56.000000000 -0700 > @@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. > #include "tm.h" /* For SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG and > TARGET_OPTION_TRANSLATE_TABLE. */ > > +static void prune_options (struct cl_decoded_option **, unsigned int *); > + > /* Perform a binary search to find which option the command-line INPUT > matches. Returns its index in the option array, and > OPT_SPECIAL_unknown on failure. > @@ -698,10 +700,9 @@ decode_cmdline_options_to_array (unsigne > > if (argv_copied) > free (argv); > - opt_array = XRESIZEVEC (struct cl_decoded_option, opt_array, > - num_decoded_options); > *decoded_options = opt_array; > *decoded_options_count = num_decoded_options; > + prune_options (decoded_options, decoded_options_count); > } > > /* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the > @@ -724,119 +725,77 @@ cancel_option (int opt_idx, int next_opt > > /* Filter out options canceled by the ones after them. */ > > -void > -prune_options (int *argcp, char ***argvp) > +static void > +prune_options (struct cl_decoded_option **decoded_options, > + unsigned int *decoded_options_count) > { > - int argc = *argcp; > - int *options = XNEWVEC (int, argc); > - /* We will only return this replacement argv if we remove at least > - one argument, so it does not need to be size (argc + 1) to > - make room for the terminating NULL because we will always have > - freed up at least one slot when we end up using it at all. */ > - char **argv = XNEWVEC (char *, argc); > - int i, arg_count, need_prune = 0; > + unsigned int old_decoded_options_count = *decoded_options_count; > + struct cl_decoded_option *old_decoded_options = *decoded_options; > + unsigned int new_decoded_options_count; > + struct cl_decoded_option *new_decoded_options > + = XNEWVEC (struct cl_decoded_option, old_decoded_options_count); > + unsigned int i; > const struct cl_option *option; > - size_t opt_index; > > - /* Scan all arguments. */ > - for (i = 1; i < argc; i++) > + /* Remove arguments which are negated by others after them. */ > + new_decoded_options_count = 0; > + for (i = 0; i < old_decoded_options_count; i++) > { > - int value = 1; > - const char *opt = (*argvp) [i]; > + unsigned int j, opt_idx, next_opt_idx; > > - opt_index = find_opt (opt + 1, -1); > - if (opt_index == OPT_SPECIAL_unknown > - && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm') > - && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-') > - { > - char *dup; > - > - /* Drop the "no-" from negative switches. */ > - size_t len = strlen (opt) - 3; > - > - dup = XNEWVEC (char, len + 1); > - dup[0] = '-'; > - dup[1] = opt[1]; > - memcpy (dup + 2, opt + 5, len - 2 + 1); > - opt = dup; > - value = 0; > - opt_index = find_opt (opt + 1, -1); > - free (dup); > - } > + if (old_decoded_options[i].errors & ~CL_ERR_WRONG_LANG) > + goto keep; > > - if (opt_index == OPT_SPECIAL_unknown) > + opt_idx = old_decoded_options[i].opt_index; > + switch (opt_idx) > { > -cont: > - options [i] = 0; > - continue; > - } > - > - option = &cl_options[opt_index]; > - if (option->neg_index < 0) > - goto cont; > - > - /* Skip joined switches. */ > - if ((option->flags & CL_JOINED)) > - goto cont; > - > - /* Reject negative form of switches that don't take negatives as > - unrecognized. */ > - if (!value && (option->flags & CL_REJECT_NEGATIVE)) > - goto cont; > - > - options [i] = (int) opt_index; > - need_prune |= options [i]; > - } > + case OPT_SPECIAL_unknown: > + case OPT_SPECIAL_ignore: > + case OPT_SPECIAL_program_name: > + case OPT_SPECIAL_input_file: > + goto keep; > + > + default: > + gcc_assert (opt_idx < cl_options_count); > + option = &cl_options[opt_idx]; > + if (option->neg_index < 0) > + goto keep; > + > + /* Skip joined switches. */ > + if ((option->flags & CL_JOINED)) > + goto keep; > > - if (!need_prune) > - goto done; > - > - /* Remove arguments which are negated by others after them. */ > - argv [0] = (*argvp) [0]; > - arg_count = 1; > - for (i = 1; i < argc; i++) > - { > - int j, opt_idx; > - > - opt_idx = options [i]; > - if (opt_idx) > - { > - int next_opt_idx; > - for (j = i + 1; j < argc; j++) > + for (j = i + 1; j < old_decoded_options_count; j++) > { > - next_opt_idx = options [j]; > - if (next_opt_idx > - && cancel_option (opt_idx, next_opt_idx, > - next_opt_idx)) > + if (old_decoded_options[j].errors & ~CL_ERR_WRONG_LANG) > + continue; > + next_opt_idx = old_decoded_options[j].opt_index; > + if (next_opt_idx >= cl_options_count) > + continue; > + if (cl_options[next_opt_idx].neg_index < 0) > + continue; > + if ((cl_options[next_opt_idx].flags & CL_JOINED)) > + continue; > + if (cancel_option (opt_idx, next_opt_idx, next_opt_idx)) > break; > } > - } > - else > - goto keep; > - > - if (j == argc) > - { > + if (j == old_decoded_options_count) > + { > keep: > - argv [arg_count] = (*argvp) [i]; > - arg_count++; > + new_decoded_options[new_decoded_options_count] > + = old_decoded_options[i]; > + new_decoded_options_count++; > + } > + break; > } > } > > - if (arg_count != argc) > - { > - *argcp = arg_count; > - *argvp = argv; > - /* Add NULL-termination. Guaranteed not to overflow because > - arg_count here can only be less than argc. */ > - argv[arg_count] = 0; > - } > - else > - { > -done: > - free (argv); > - } > - > - free (options); > + free (old_decoded_options); > + new_decoded_options = XRESIZEVEC (struct cl_decoded_option, > + new_decoded_options, > + new_decoded_options_count); > + *decoded_options = new_decoded_options; > + *decoded_options_count = new_decoded_options_count; > } > > /* Handle option DECODED for the language indicated by LANG_MASK, > diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/opts.h gcc-mainline/gcc/opts.h > --- gcc-mainline-0trans/gcc/opts.h 2010-09-03 08:51:25.000000000 -0700 > +++ gcc-mainline/gcc/opts.h 2010-09-10 12:56:10.000000000 -0700 > @@ -206,7 +206,6 @@ extern void decode_cmdline_options_to_ar > unsigned int lang_mask, > struct cl_decoded_option **decoded_options, > unsigned int *decoded_options_count); > -extern void prune_options (int *argcp, char ***argvp); > extern void decode_options (unsigned int argc, const char **argv, > struct cl_decoded_option **decoded_options, > unsigned int *decoded_options_count); > > -- > Joseph S. Myers > joseph@codesourcery.com >
On 11/09/2010 13:15, Joseph S. Myers wrote: > The main complication in making the driver start using decoded options > as early as it should is GCC_DRIVER_HOST_INITIALIZATION. This is a > macro with rather poorly defined semantics. Documented as a host > macro, it is in fact defined both as a host macro (for DJGPP) and as a > target macro (for Cygwin, Xtensa bare-metal and Darwin native). This > would cause conflicts if a cross compiler is built from DJGPP to > Cygwin or Xtensa bare-metal. [ ... ] This patch fixes the affected > definitions of GCC_DRIVER_HOST_INITIALIZATION, those for Cygwin and > Darwin, to work with decoded options. [ ... ] Oh. Sorry, Joseph, I hope you didn't spend too much time and sweat fixing up that Cygwin stuff; it's all deprecated and I'm planning to chop the whole lot out before 4.7.0 goes out; I wish I could have saved you the trouble. (Just to be clear, I don't in any way object to this patch; in the long run it's not going to matter from a Cygwin POV.) cheers, DaveK
diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/darwin-driver.c gcc-mainline/gcc/config/darwin-driver.c --- gcc-mainline-0trans/gcc/config/darwin-driver.c 2010-07-27 16:46:56.000000000 -0700 +++ gcc-mainline/gcc/config/darwin-driver.c 2010-09-10 17:35:03.000000000 -0700 @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. #include "coretypes.h" #include "tm.h" #include "gcc.h" +#include "opts.h" #include <sys/sysctl.h> #include "xregex.h" @@ -32,11 +33,12 @@ along with GCC; see the file COPYING3. of the system on which the compiler is running. */ void -darwin_default_min_version (int * argc_p, char *** argv_p) +darwin_default_min_version (unsigned int *decoded_options_count, + struct cl_decoded_option **decoded_options) { - const int argc = *argc_p; - char ** const argv = *argv_p; - int i; + const unsigned int argc = *decoded_options_count; + struct cl_decoded_option *const argv = *decoded_options; + unsigned int i; char osversion[32]; size_t osversion_len = sizeof (osversion) - 1; static int osversion_name[2] = { CTL_KERN, KERN_OSRELEASE }; @@ -44,34 +46,17 @@ darwin_default_min_version (int * argc_p char * version_pend; int major_vers; char minor_vers[6]; - static char new_flag[sizeof ("-mmacosx-version-min=10.0.0") + 6]; + static char new_flag[sizeof ("10.0.0") + 6]; /* If the command-line is empty, just return. */ if (argc <= 1) return; - /* Don't do this if the user has specified -b or -V at the start - of the command-line. */ - if (argv[1][0] == '-' - && (argv[1][1] == 'V' || - ((argv[1][1] == 'b') && (NULL != strchr(argv[1] + 2,'-'))))) - return; /* Don't do this if the user specified -mmacosx-version-min= or -mno-macosx-version-min. */ for (i = 1; i < argc; i++) - if (argv[i][0] == '-') - { - const char * const p = argv[i]; - if (strncmp (p, "-mno-macosx-version-min", 23) == 0 - || strncmp (p, "-mmacosx-version-min", 20) == 0) - return; - - /* It doesn't count if it's an argument to a different switch. */ - if (p[0] == '-' - && ((SWITCH_TAKES_ARG (p[1]) > (p[2] != 0)) - || WORD_SWITCH_TAKES_ARG (p + 1))) - i++; - } + if (argv[i].opt_index == OPT_mmacosx_version_min_) + return; /* Retrieve the deployment target from the environment and insert it as a flag. */ @@ -84,12 +69,14 @@ darwin_default_min_version (int * argc_p to ignore the environment variable, as if it was never set. */ && macosx_deployment_target[0]) { - ++*argc_p; - *argv_p = XNEWVEC (char *, *argc_p); - (*argv_p)[0] = argv[0]; - (*argv_p)[1] = concat ("-mmacosx-version-min=", - macosx_deployment_target, NULL); - memcpy (*argv_p + 2, argv + 1, (argc - 1) * sizeof (char *)); + ++*decoded_options_count; + *decoded_options = XNEWVEC (struct cl_decoded_option, + *decoded_options_count); + (*decoded_options)[0] = argv[0]; + generate_option (OPT_mmacosx_version_min_, macosx_deployment_target, + 1, CL_DRIVER, &(*decoded_options)[1]); + memcpy (*decoded_options + 2, argv + 1, + (argc - 1) * sizeof (struct cl_decoded_option *)); return; } } @@ -128,17 +115,20 @@ darwin_default_min_version (int * argc_p if (major_vers - 4 <= 4) /* On 10.4 and earlier, the old linker is used which does not support three-component system versions. */ - sprintf (new_flag, "-mmacosx-version-min=10.%d", major_vers - 4); + sprintf (new_flag, "10.%d", major_vers - 4); else - sprintf (new_flag, "-mmacosx-version-min=10.%d.%s", major_vers - 4, + sprintf (new_flag, "10.%d.%s", major_vers - 4, minor_vers); /* Add the new flag. */ - ++*argc_p; - *argv_p = XNEWVEC (char *, *argc_p); - (*argv_p)[0] = argv[0]; - (*argv_p)[1] = new_flag; - memcpy (*argv_p + 2, argv + 1, (argc - 1) * sizeof (char *)); + ++*decoded_options_count; + *decoded_options = XNEWVEC (struct cl_decoded_option, + *decoded_options_count); + (*decoded_options)[0] = argv[0]; + generate_option (OPT_mmacosx_version_min_, new_flag, + 1, CL_DRIVER, &(*decoded_options)[1]); + memcpy (*decoded_options + 2, argv + 1, + (argc - 1) * sizeof (struct cl_decoded_option *)); return; parse_failed: diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/darwin.h gcc-mainline/gcc/config/darwin.h --- gcc-mainline-0trans/gcc/config/darwin.h 2010-08-22 05:22:04.000000000 -0700 +++ gcc-mainline/gcc/config/darwin.h 2010-09-10 13:45:48.000000000 -0700 @@ -1059,9 +1059,10 @@ extern int flag_apple_kext; #define TARGET_HAS_TARGETCM 1 #ifndef CROSS_DIRECTORY_STRUCTURE -extern void darwin_default_min_version (int * argc, char *** argv); +extern void darwin_default_min_version (unsigned int *decoded_options_count, + struct cl_decoded_option **decoded_options); #define GCC_DRIVER_HOST_INITIALIZATION \ - darwin_default_min_version (&argc, &argv) + darwin_default_min_version (&decoded_options_count, &decoded_options) #endif /* CROSS_DIRECTORY_STRUCTURE */ /* The Apple assembler and linker do not support constructor priorities. */ diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/i386/cygwin.h gcc-mainline/gcc/config/i386/cygwin.h --- gcc-mainline-0trans/gcc/config/i386/cygwin.h 2010-09-02 04:45:25.000000000 -0700 +++ gcc-mainline/gcc/config/i386/cygwin.h 2010-09-10 17:03:22.000000000 -0700 @@ -252,12 +252,13 @@ char *cvt_to_mingw[] = #undef GEN_CVT_ARRAY #endif /*GEN_CVT_ARRAY*/ -void mingw_scan (int, const char * const *, const char **); +void mingw_scan (unsigned int, const struct cl_decoded_option *, + const char **); #if 1 #define GCC_DRIVER_HOST_INITIALIZATION \ do \ { \ - mingw_scan(argc, (const char * const *) argv, &spec_machine); \ + mingw_scan (decoded_options_count, decoded_options, &spec_machine); \ } \ while (0) #else @@ -277,7 +278,7 @@ do \ add_prefix (&startfile_prefixes,\ concat (standard_startfile_prefix, "w32api", NULL),\ "GCC", PREFIX_PRIORITY_LAST, 0, NULL);\ - mingw_scan(argc, (const char * const *) argv, &spec_machine); \ + mingw_scan (decoded_options_count, decoded_options, &spec_machine); \ } \ while (0) #endif diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/i386/cygwin1.c gcc-mainline/gcc/config/i386/cygwin1.c --- gcc-mainline-0trans/gcc/config/i386/cygwin1.c 2009-03-28 00:38:15.000000000 -0700 +++ gcc-mainline/gcc/config/i386/cygwin1.c 2010-09-10 17:03:32.000000000 -0700 @@ -22,32 +22,42 @@ along with GCC; see the file COPYING3. #include "system.h" #include "coretypes.h" #include "tm.h" +#include "opts.h" #include <string.h> void -mingw_scan (int argc ATTRIBUTE_UNUSED, - const char *const *argv, +mingw_scan (unsigned int decoded_options_count, + const struct cl_decoded_option *decoded_options, const char **spec_machine) { + unsigned int i; putenv (xstrdup ("GCC_CYGWIN_MINGW=0")); - while (*++argv) - if (strcmp (*argv, "-mno-win32") == 0) - putenv (xstrdup ("GCC_CYGWIN_WIN32=0")); - else if (strcmp (*argv, "-mwin32") == 0) - putenv (xstrdup ("GCC_CYGWIN_WIN32=1")); - else if (strcmp (*argv, "-mno-cygwin") == 0) + for (i = 1; i < decoded_options_count; i++) + switch (decoded_options[i].opt_index) { - char *p = strstr (*spec_machine, "-cygwin"); - if (p) + case OPT_mwin32: + if (decoded_options[i].value == 0) + putenv (xstrdup ("GCC_CYGWIN_WIN32=0")); + else + putenv (xstrdup ("GCC_CYGWIN_WIN32=1")); + break; + + case OPT_mcygwin: + if (decoded_options[i].value == 0) { - int len = p - *spec_machine; - char *s = XNEWVEC (char, strlen (*spec_machine) + 3); - memcpy (s, *spec_machine, len); - strcpy (s + len, "-mingw32"); - *spec_machine = s; + char *p = strstr (*spec_machine, "-cygwin"); + if (p) + { + int len = p - *spec_machine; + char *s = XNEWVEC (char, strlen (*spec_machine) + 3); + memcpy (s, *spec_machine, len); + strcpy (s + len, "-mingw32"); + *spec_machine = s; + } + putenv (xstrdup ("GCC_CYGWIN_MINGW=1")); } - putenv (xstrdup ("GCC_CYGWIN_MINGW=1")); + break; } return; } diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/i386/t-cygwin gcc-mainline/gcc/config/i386/t-cygwin --- gcc-mainline-0trans/gcc/config/i386/t-cygwin 2010-09-02 04:45:25.000000000 -0700 +++ gcc-mainline/gcc/config/i386/t-cygwin 2010-09-10 17:04:44.000000000 -0700 @@ -1,4 +1,4 @@ -# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2008, 2009 +# Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2008, 2009, 2010 # Free Software Foundation, Inc. # # This file is part of GCC. @@ -24,7 +24,7 @@ LIBGCC2_INCLUDES += -I$(srcdir)/../winsu -I$(srcdir)/../winsup/cygwin/include cygwin1.o: $(srcdir)/config/i386/cygwin1.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ - $(TM_H) $(TM_P_H) + $(TM_H) $(TM_P_H) opts.h $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/i386/cygwin1.c diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/config/t-darwin gcc-mainline/gcc/config/t-darwin --- gcc-mainline-0trans/gcc/config/t-darwin 2010-06-07 02:48:58.000000000 -0700 +++ gcc-mainline/gcc/config/t-darwin 2010-09-10 17:04:34.000000000 -0700 @@ -36,7 +36,7 @@ darwin-f.o: $(srcdir)/config/darwin-f.c $(srcdir)/config/darwin-f.c $(PREPROCESSOR_DEFINES) darwin-driver.o: $(srcdir)/config/darwin-driver.c \ - $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) + $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(GCC_H) opts.h $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ $(srcdir)/config/darwin-driver.c diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/gcc.c gcc-mainline/gcc/gcc.c --- gcc-mainline-0trans/gcc/gcc.c 2010-09-08 03:32:16.000000000 -0700 +++ gcc-mainline/gcc/gcc.c 2010-09-10 14:12:13.000000000 -0700 @@ -261,7 +261,7 @@ static void display_help (void); static void add_preprocessor_option (const char *, int); static void add_assembler_option (const char *, int); static void add_linker_option (const char *, int); -static void process_command (int, const char **); +static void process_command (unsigned int, struct cl_decoded_option *); static int execute (void); static void alloc_args (void); static void clear_args (void); @@ -3516,7 +3516,8 @@ driver_handle_option (const struct cl_de Store its length in `n_switches'. */ static void -process_command (int argc, const char **argv) +process_command (unsigned int decoded_options_count, + struct cl_decoded_option *decoded_options) { const char *temp; char *temp1; @@ -3524,8 +3525,7 @@ process_command (int argc, const char ** char *(*get_relative_prefix) (const char *, const char *, const char *) = NULL; struct cl_option_handlers handlers; - struct cl_decoded_option *decoded_options; - unsigned int decoded_options_count, j; + unsigned int j; GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX"); @@ -3546,9 +3546,6 @@ process_command (int argc, const char ** } } - decode_cmdline_options_to_array (argc, argv, CL_DRIVER, - &decoded_options, &decoded_options_count); - /* Handle any -no-canonical-prefixes flag early, to assign the function that builds relative prefixes. This function creates default search paths that are needed later in normal option handling. */ @@ -3565,17 +3562,18 @@ process_command (int argc, const char ** get_relative_prefix = make_relative_prefix; /* Set up the default search paths. If there is no GCC_EXEC_PREFIX, - see if we can create it from the pathname specified in argv[0]. */ + see if we can create it from the pathname specified in + decoded_options[0].arg. */ gcc_libexec_prefix = standard_libexec_prefix; #ifndef VMS /* FIXME: make_relative_prefix doesn't yet work for VMS. */ if (!gcc_exec_prefix) { - gcc_exec_prefix = get_relative_prefix (argv[0], + gcc_exec_prefix = get_relative_prefix (decoded_options[0].arg, standard_bindir_prefix, standard_exec_prefix); - gcc_libexec_prefix = get_relative_prefix (argv[0], + gcc_libexec_prefix = get_relative_prefix (decoded_options[0].arg, standard_bindir_prefix, standard_libexec_prefix); if (gcc_exec_prefix) @@ -3602,7 +3600,8 @@ process_command (int argc, const char ** #endif /* From this point onward, gcc_exec_prefix is non-null if the toolchain is relocated. The toolchain was either relocated using GCC_EXEC_PREFIX - or an automatically created GCC_EXEC_PREFIX from argv[0]. */ + or an automatically created GCC_EXEC_PREFIX from + decoded_options[0].arg. */ /* Do language-specific adjustment/addition of flags. */ lang_specific_driver (&decoded_options, &decoded_options_count, @@ -3898,7 +3897,7 @@ process_command (int argc, const char ** ``make_relative_prefix'' is not compiled for VMS, so don't call it. */ if (target_system_root && !target_system_root_changed && gcc_exec_prefix) { - char *tmp_prefix = get_relative_prefix (argv[0], + char *tmp_prefix = get_relative_prefix (decoded_options[0].arg, standard_bindir_prefix, target_system_root); if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0) @@ -6109,6 +6108,8 @@ main (int argc, char **argv) const char *p; struct user_specs *uptr; char **old_argv = argv; + struct cl_decoded_option *decoded_options; + unsigned int decoded_options_count; /* Initialize here, not in definition. The IRIX 6 O32 cc sometimes chokes on ?: in file-scope variable initializations. */ @@ -6127,7 +6128,10 @@ main (int argc, char **argv) if (argv != old_argv) at_file_supplied = true; - prune_options (&argc, &argv); + decode_cmdline_options_to_array (argc, CONST_CAST2 (const char **, char **, + argv), + CL_DRIVER, + &decoded_options, &decoded_options_count); #ifdef GCC_DRIVER_HOST_INITIALIZATION /* Perform host dependent initialization when needed. */ @@ -6217,7 +6221,7 @@ main (int argc, char **argv) Make a table of specified input files (infiles, n_infiles). Decode switches that are handled locally. */ - process_command (argc, CONST_CAST2 (const char **, char **, argv)); + process_command (decoded_options_count, decoded_options); /* Initialize the vector of specs to just the default. This means one element containing 0s, as a terminator. */ diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/opts-common.c gcc-mainline/gcc/opts-common.c --- gcc-mainline-0trans/gcc/opts-common.c 2010-09-08 06:56:29.000000000 -0700 +++ gcc-mainline/gcc/opts-common.c 2010-09-10 14:47:56.000000000 -0700 @@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. #include "tm.h" /* For SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG and TARGET_OPTION_TRANSLATE_TABLE. */ +static void prune_options (struct cl_decoded_option **, unsigned int *); + /* Perform a binary search to find which option the command-line INPUT matches. Returns its index in the option array, and OPT_SPECIAL_unknown on failure. @@ -698,10 +700,9 @@ decode_cmdline_options_to_array (unsigne if (argv_copied) free (argv); - opt_array = XRESIZEVEC (struct cl_decoded_option, opt_array, - num_decoded_options); *decoded_options = opt_array; *decoded_options_count = num_decoded_options; + prune_options (decoded_options, decoded_options_count); } /* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the @@ -724,119 +725,77 @@ cancel_option (int opt_idx, int next_opt /* Filter out options canceled by the ones after them. */ -void -prune_options (int *argcp, char ***argvp) +static void +prune_options (struct cl_decoded_option **decoded_options, + unsigned int *decoded_options_count) { - int argc = *argcp; - int *options = XNEWVEC (int, argc); - /* We will only return this replacement argv if we remove at least - one argument, so it does not need to be size (argc + 1) to - make room for the terminating NULL because we will always have - freed up at least one slot when we end up using it at all. */ - char **argv = XNEWVEC (char *, argc); - int i, arg_count, need_prune = 0; + unsigned int old_decoded_options_count = *decoded_options_count; + struct cl_decoded_option *old_decoded_options = *decoded_options; + unsigned int new_decoded_options_count; + struct cl_decoded_option *new_decoded_options + = XNEWVEC (struct cl_decoded_option, old_decoded_options_count); + unsigned int i; const struct cl_option *option; - size_t opt_index; - /* Scan all arguments. */ - for (i = 1; i < argc; i++) + /* Remove arguments which are negated by others after them. */ + new_decoded_options_count = 0; + for (i = 0; i < old_decoded_options_count; i++) { - int value = 1; - const char *opt = (*argvp) [i]; + unsigned int j, opt_idx, next_opt_idx; - opt_index = find_opt (opt + 1, -1); - if (opt_index == OPT_SPECIAL_unknown - && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm') - && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-') - { - char *dup; - - /* Drop the "no-" from negative switches. */ - size_t len = strlen (opt) - 3; - - dup = XNEWVEC (char, len + 1); - dup[0] = '-'; - dup[1] = opt[1]; - memcpy (dup + 2, opt + 5, len - 2 + 1); - opt = dup; - value = 0; - opt_index = find_opt (opt + 1, -1); - free (dup); - } + if (old_decoded_options[i].errors & ~CL_ERR_WRONG_LANG) + goto keep; - if (opt_index == OPT_SPECIAL_unknown) + opt_idx = old_decoded_options[i].opt_index; + switch (opt_idx) { -cont: - options [i] = 0; - continue; - } - - option = &cl_options[opt_index]; - if (option->neg_index < 0) - goto cont; - - /* Skip joined switches. */ - if ((option->flags & CL_JOINED)) - goto cont; - - /* Reject negative form of switches that don't take negatives as - unrecognized. */ - if (!value && (option->flags & CL_REJECT_NEGATIVE)) - goto cont; - - options [i] = (int) opt_index; - need_prune |= options [i]; - } + case OPT_SPECIAL_unknown: + case OPT_SPECIAL_ignore: + case OPT_SPECIAL_program_name: + case OPT_SPECIAL_input_file: + goto keep; + + default: + gcc_assert (opt_idx < cl_options_count); + option = &cl_options[opt_idx]; + if (option->neg_index < 0) + goto keep; + + /* Skip joined switches. */ + if ((option->flags & CL_JOINED)) + goto keep; - if (!need_prune) - goto done; - - /* Remove arguments which are negated by others after them. */ - argv [0] = (*argvp) [0]; - arg_count = 1; - for (i = 1; i < argc; i++) - { - int j, opt_idx; - - opt_idx = options [i]; - if (opt_idx) - { - int next_opt_idx; - for (j = i + 1; j < argc; j++) + for (j = i + 1; j < old_decoded_options_count; j++) { - next_opt_idx = options [j]; - if (next_opt_idx - && cancel_option (opt_idx, next_opt_idx, - next_opt_idx)) + if (old_decoded_options[j].errors & ~CL_ERR_WRONG_LANG) + continue; + next_opt_idx = old_decoded_options[j].opt_index; + if (next_opt_idx >= cl_options_count) + continue; + if (cl_options[next_opt_idx].neg_index < 0) + continue; + if ((cl_options[next_opt_idx].flags & CL_JOINED)) + continue; + if (cancel_option (opt_idx, next_opt_idx, next_opt_idx)) break; } - } - else - goto keep; - - if (j == argc) - { + if (j == old_decoded_options_count) + { keep: - argv [arg_count] = (*argvp) [i]; - arg_count++; + new_decoded_options[new_decoded_options_count] + = old_decoded_options[i]; + new_decoded_options_count++; + } + break; } } - if (arg_count != argc) - { - *argcp = arg_count; - *argvp = argv; - /* Add NULL-termination. Guaranteed not to overflow because - arg_count here can only be less than argc. */ - argv[arg_count] = 0; - } - else - { -done: - free (argv); - } - - free (options); + free (old_decoded_options); + new_decoded_options = XRESIZEVEC (struct cl_decoded_option, + new_decoded_options, + new_decoded_options_count); + *decoded_options = new_decoded_options; + *decoded_options_count = new_decoded_options_count; } /* Handle option DECODED for the language indicated by LANG_MASK, diff -rupN --exclude=.svn gcc-mainline-0trans/gcc/opts.h gcc-mainline/gcc/opts.h --- gcc-mainline-0trans/gcc/opts.h 2010-09-03 08:51:25.000000000 -0700 +++ gcc-mainline/gcc/opts.h 2010-09-10 12:56:10.000000000 -0700 @@ -206,7 +206,6 @@ extern void decode_cmdline_options_to_ar unsigned int lang_mask, struct cl_decoded_option **decoded_options, unsigned int *decoded_options_count); -extern void prune_options (int *argcp, char ***argvp); extern void decode_options (unsigned int argc, const char **argv, struct cl_decoded_option **decoded_options, unsigned int *decoded_options_count);