From patchwork Sat Sep 11 12:15:36 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 64511 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id 66D7FB70A4 for ; Sat, 11 Sep 2010 22:15:53 +1000 (EST) Received: (qmail 16543 invoked by alias); 11 Sep 2010 12:15:50 -0000 Received: (qmail 16528 invoked by uid 22791); 11 Sep 2010 12:15:46 -0000 X-SWARE-Spam-Status: No, hits=-1.7 required=5.0 tests=AWL, BAYES_00, TW_CP, TW_RG, TW_XG, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sat, 11 Sep 2010 12:15:40 +0000 Received: (qmail 32151 invoked from network); 11 Sep 2010 12:15:37 -0000 Received: from unknown (HELO digraph.polyomino.org.uk) (joseph@127.0.0.2) by mail.codesourcery.com with ESMTPA; 11 Sep 2010 12:15:37 -0000 Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.69) (envelope-from ) id 1OuOzY-0002fV-59 for gcc-patches@gcc.gnu.org; Sat, 11 Sep 2010 12:15:36 +0000 Date: Sat, 11 Sep 2010 12:15:36 +0000 (UTC) From: "Joseph S. Myers" To: gcc-patches@gcc.gnu.org Subject: Make prune_options work with decoded options Message-ID: MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org This patch, based on a tree with (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? 2010-09-11 Joseph Myers * 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 #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 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);