Message ID | Pine.LNX.4.64.1006232024410.22427@digraph.polyomino.org.uk |
---|---|
State | New |
Headers | show |
On Wed, Jun 23, 2010 at 10:26 PM, Joseph S. Myers <joseph@codesourcery.com> wrote: > This patch is relative to a tree with > <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg01968.html>, > <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg02150.html> and > <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg02260.html> applied. > The first of these patches needs C++ and Ada pieces approved; the > second needs C++ pieces approved; the third needs approval for > everything except c-family, Fortran and Java pieces. > > The driver handles some options solely on the basis of specs and the > target macros SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG with no more > structured information about these options. Although I plan to move > to .opt files having structured information about all options for all > targets (since some such unstructured specs-only options are used in > multilib selection, so such changes are required when multilib > selection ceases to be textually based), an intermediate stage > involved in reaching that point incrementally will have the driver > using shared option processing code for some purposes but still > passing through specs-only options for use in existing > specs-processing code. > > Thus the shared option processing code should be able to handle > unknown options using SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG, > until more structured information eliminates those macros, and this > patch implements this. (Right now it should only have any effect when > cc1 etc. are called directly, since it does nothing for options known > to the core compiler and the other options should not get passed > through to the core compiler.) > > One complication is that SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG > can specify options taking more than one argument, a concept not yet > known to the .opt machinery. Thus, some common options code is > adjusted to handle such options to the extent of storing multiple argv > elements appropriately in the decoded option structure. > > Bootstrapped with no regressions on x86_64-unknown-linux-gnu. OK to > commit? Ok for the non-frontend specific changes. Thanks, Richard. > 2010-06-23 Joseph Myers <joseph@codesourcery.com> > > * config/darwin-driver.c (SWITCH_TAKES_ARG, > WORD_SWITCH_TAKES_ARG): Remove. > * cppspec.c (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): Remove. > * defaults.h (DEFAULT_SWITCH_TAKES_ARG, > DEFAULT_WORD_SWITCH_TAKES_ARG): Move from gcc.h. > (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): Move default > definitions from gcc.c. > * gcc.c (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): Move to > defaults.h. > * gcc.h (DEFAULT_SWITCH_TAKES_ARG, DEFAULT_WORD_SWITCH_TAKES_ARG): > Move to defaults.h. > * opts-common.c: Include tm.h. > (decode_cmdline_option): Use SWITCH_TAKES_ARG and > WORD_SWITCH_TAKES_ARG to count arguments to unknown options. > Handle more than one argument. Set canonical_option_num_elements. > (decode_cmdline_options_to_array): Set > canonical_option_num_elements and trailing elements of > canonical_option. > * opts.h (struct cl_decoded_option): Allow four elements in > canonical_option. Add field canonical_option_num_elements. > * Makefile.in (opts-common.o): Update dependencies. > > ada: > 2010-06-23 Joseph Myers <joseph@codesourcery.com> > > * gcc-interface/misc.c (gnat_init_options): Ignore erroneous > options. Check canonical_option_num_elements on options copied. > > fortran: > 2010-06-23 Joseph Myers <joseph@codesourcery.com> > > * gfortranspec.c (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): > Remove. > > diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/Makefile.in gcc-mainline/gcc/Makefile.in > --- gcc-mainline-opt3/gcc/Makefile.in 2010-06-22 15:24:00.000000000 -0700 > +++ gcc-mainline/gcc/Makefile.in 2010-06-23 08:44:22.000000000 -0700 > @@ -2796,7 +2796,7 @@ opts.o : opts.c opts.h options.h $(TOPLE > $(FLAGS_H) $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H) debug.h \ > $(PLUGIN_H) $(EXCEPT_H) $(LTO_STREAMER_H) opts-diagnostic.h > opts-common.o : opts-common.c opts.h $(CONFIG_H) $(SYSTEM_H) \ > - coretypes.h intl.h $(DIAGNOSTIC_H) > + coretypes.h intl.h $(DIAGNOSTIC_H) $(TM_H) > targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ > $(EXPR_H) $(TM_H) $(RTL_H) $(TM_P_H) $(FUNCTION_H) output.h $(TOPLEV_H) \ > $(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) gt-targhooks.h \ > diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/ada/gcc-interface/misc.c gcc-mainline/gcc/ada/gcc-interface/misc.c > --- gcc-mainline-opt3/gcc/ada/gcc-interface/misc.c 2010-06-22 16:02:04.000000000 -0700 > +++ gcc-mainline/gcc/ada/gcc-interface/misc.c 2010-06-23 07:46:46.000000000 -0700 > @@ -303,8 +303,13 @@ gnat_init_options (unsigned int decoded_ > save_argc = 0; > for (i = 0; i < decoded_options_count; i++) > { > + if (decoded_options[i].errors > + || decoded_options[i].opt_index == OPT_SPECIAL_unknown) > + continue; > + gcc_assert (decoded_options[i].canonical_option_num_elements >= 1 > + && decoded_options[i].canonical_option_num_elements <= 2); > save_argv[save_argc++] = decoded_options[i].canonical_option[0]; > - if (decoded_options[i].canonical_option[1] != NULL) > + if (decoded_options[i].canonical_option_num_elements >= 2) > save_argv[save_argc++] = decoded_options[i].canonical_option[1]; > } > save_argv[save_argc] = NULL; > diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/config/darwin-driver.c gcc-mainline/gcc/config/darwin-driver.c > --- gcc-mainline-opt3/gcc/config/darwin-driver.c 2010-06-04 06:35:13.000000000 -0700 > +++ gcc-mainline/gcc/config/darwin-driver.c 2010-06-23 08:24:32.000000000 -0700 > @@ -27,14 +27,6 @@ along with GCC; see the file COPYING3. > #include <sys/sysctl.h> > #include "xregex.h" > > -#ifndef SWITCH_TAKES_ARG > -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) > -#endif > - > -#ifndef WORD_SWITCH_TAKES_ARG > -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) > -#endif > - > /* When running on a Darwin system and using that system's headers and > libraries, default the -mmacosx-version-min flag to be the version > of the system on which the compiler is running. */ > diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/cppspec.c gcc-mainline/gcc/cppspec.c > --- gcc-mainline-opt3/gcc/cppspec.c 2010-06-04 06:40:58.000000000 -0700 > +++ gcc-mainline/gcc/cppspec.c 2010-06-23 08:24:05.000000000 -0700 > @@ -30,14 +30,6 @@ along with GCC; see the file COPYING3. > assume the user knows what they're doing. If no explicit input is > mentioned, it will read stdin. */ > > -#ifndef SWITCH_TAKES_ARG > -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) > -#endif > - > -#ifndef WORD_SWITCH_TAKES_ARG > -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) > -#endif > - > /* Suffixes for known sorts of input files. Note that we do not list > files which are normally considered to have been preprocessed already, > since the user's expectation is that `cpp' always preprocesses. */ > diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/defaults.h gcc-mainline/gcc/defaults.h > --- gcc-mainline-opt3/gcc/defaults.h 2010-06-11 02:16:45.000000000 -0700 > +++ gcc-mainline/gcc/defaults.h 2010-06-23 08:24:12.000000000 -0700 > @@ -32,6 +32,38 @@ see the files COPYING3 and COPYING.RUNTI > #define GET_ENVIRONMENT(VALUE, NAME) do { (VALUE) = getenv (NAME); } while (0) > #endif > > +/* This defines which switch letters take arguments. */ > + > +#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \ > + ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \ > + || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \ > + || (CHAR) == 'I' || (CHAR) == 'J' || (CHAR) == 'm' \ > + || (CHAR) == 'x' || (CHAR) == 'L' || (CHAR) == 'A' \ > + || (CHAR) == 'B' ) > + > +/* This defines which multi-letter switches take arguments. */ > + > +#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \ > + (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \ > + || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \ > + || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \ > + || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \ > + || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \ > + || !strcmp (STR, "iquote") || !strcmp (STR, "isystem") \ > + || !strcmp (STR, "isysroot") \ > + || !strcmp (STR, "-param") || !strcmp (STR, "specs") \ > + || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ") \ > + || !strcmp (STR, "fintrinsic-modules-path") \ > + || !strcmp (STR, "dumpbase") || !strcmp (STR, "dumpdir")) > + > +#ifndef SWITCH_TAKES_ARG > +#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG (CHAR) > +#endif > + > +#ifndef WORD_SWITCH_TAKES_ARG > +#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) > +#endif > + > /* Store in OUTPUT a string (made with alloca) containing an > assembler-name for a local static variable or function named NAME. > LABELNO is an integer which is different for each call. */ > diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/fortran/gfortranspec.c gcc-mainline/gcc/fortran/gfortranspec.c > --- gcc-mainline-opt3/gcc/fortran/gfortranspec.c 2010-06-16 09:07:30.000000000 -0700 > +++ gcc-mainline/gcc/fortran/gfortranspec.c 2010-06-23 08:25:11.000000000 -0700 > @@ -113,22 +113,6 @@ static void append_arg (const char *); > static int g77_newargc; > static const char **g77_newargv; > > -/* --- This comes from gcc.c (2.8.1) verbatim: */ > - > -/* This defines which switch letters take arguments. */ > - > -#ifndef SWITCH_TAKES_ARG > -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) > -#endif > - > -/* This defines which multi-letter switches take arguments. */ > - > -#ifndef WORD_SWITCH_TAKES_ARG > -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) > -#endif > - > -/* --- End of verbatim. */ > - > /* Assumes text[0] == '-'. Returns number of argv items that belong to > (and follow) this one, an option id for options important to the > caller, and a pointer to the first char of the arg, if embedded (else > diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/gcc.c gcc-mainline/gcc/gcc.c > --- gcc-mainline-opt3/gcc/gcc.c 2010-06-07 02:48:58.000000000 -0700 > +++ gcc-mainline/gcc/gcc.c 2010-06-23 08:22:19.000000000 -0700 > @@ -975,13 +975,6 @@ struct user_specs > > static struct user_specs *user_specs_head, *user_specs_tail; > > -#ifndef SWITCH_TAKES_ARG > -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) > -#endif > - > -#ifndef WORD_SWITCH_TAKES_ARG > -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) > -#endif > > #ifdef HAVE_TARGET_EXECUTABLE_SUFFIX > /* This defines which switches stop a full compilation. */ > diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/gcc.h gcc-mainline/gcc/gcc.h > --- gcc-mainline-opt3/gcc/gcc.h 2010-05-28 12:31:35.000000000 -0700 > +++ gcc-mainline/gcc/gcc.h 2010-06-23 08:21:07.000000000 -0700 > @@ -32,31 +32,6 @@ struct spec_function > const char *(*func) (int, const char **); > }; > > -/* This defines which switch letters take arguments. */ > - > -#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \ > - ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \ > - || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \ > - || (CHAR) == 'I' || (CHAR) == 'J' || (CHAR) == 'm' \ > - || (CHAR) == 'x' || (CHAR) == 'L' || (CHAR) == 'A' \ > - || (CHAR) == 'B' ) > - > -/* This defines which multi-letter switches take arguments. */ > - > -#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \ > - (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \ > - || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \ > - || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \ > - || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \ > - || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \ > - || !strcmp (STR, "iquote") || !strcmp (STR, "isystem") \ > - || !strcmp (STR, "isysroot") \ > - || !strcmp (STR, "-param") || !strcmp (STR, "specs") \ > - || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ") \ > - || !strcmp (STR, "fintrinsic-modules-path") \ > - || !strcmp (STR, "dumpbase") || !strcmp (STR, "dumpdir")) > - > - > /* These are exported by gcc.c. */ > extern int do_spec (const char *); > extern void record_temp_file (const char *, int, int); > diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/opts-common.c gcc-mainline/gcc/opts-common.c > --- gcc-mainline-opt3/gcc/opts-common.c 2010-06-22 15:23:48.000000000 -0700 > +++ gcc-mainline/gcc/opts-common.c 2010-06-23 11:44:40.000000000 -0700 > @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. > #include "opts.h" > #include "options.h" > #include "diagnostic.h" > +#include "tm.h" /* For SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG. */ > > /* Perform a binary search to find which option the command-line INPUT > matches. Returns its index in the option array, and > @@ -138,7 +139,9 @@ decode_cmdline_option (const char **argv > const char *opt, *arg = 0; > char *dup = 0; > int value = 1; > - unsigned int result = 1; > + unsigned int result = 1, i; > + size_t total_len; > + char *p; > const struct cl_option *option; > int errors = 0; > > @@ -242,22 +245,54 @@ decode_cmdline_option (const char **argv > decoded->arg = arg; > decoded->value = value; > decoded->errors = errors; > - switch (result) > + > + if (opt_index == OPT_SPECIAL_unknown) > { > - case 1: > - decoded->orig_option_with_args_text = argv[0]; > - decoded->canonical_option[0] = argv[0]; > - decoded->canonical_option[1] = NULL; > - break; > - case 2: > - decoded->orig_option_with_args_text = concat (argv[0], " ", > - argv[1], NULL); > - decoded->canonical_option[0] = argv[0]; > - decoded->canonical_option[1] = argv[1]; > - break; > - default: > - gcc_unreachable (); > + /* Skip the correct number of arguments for options handled > + through specs. */ > + const char *popt = argv[0] + 1; > + int c = *popt; > + > + gcc_assert (result == 1); > + if (SWITCH_TAKES_ARG (c) > (popt[1] != 0)) > + result += SWITCH_TAKES_ARG (c) - (popt[1] != 0); > + else if (WORD_SWITCH_TAKES_ARG (popt)) > + result += WORD_SWITCH_TAKES_ARG (popt); > + if (result > 1) > + for (i = 1; i < result; i++) > + if (argv[i] == NULL) > + { > + result = i; > + break; > + } > } > + > + gcc_assert (result >= 1 && result <= ARRAY_SIZE (decoded->canonical_option)); > + decoded->canonical_option_num_elements = result; > + total_len = 0; > + for (i = 0; i < ARRAY_SIZE (decoded->canonical_option); i++) > + { > + if (i < result) > + { > + decoded->canonical_option[i] = argv[i]; > + total_len += strlen (argv[i]) + 1; > + } > + else > + decoded->canonical_option[i] = NULL; > + } > + decoded->orig_option_with_args_text = p = XNEWVEC (char, total_len); > + for (i = 0; i < result; i++) > + { > + size_t len = strlen (argv[i]); > + > + memcpy (p, argv[i], len); > + p += len; > + if (i == result - 1) > + *p++ = 0; > + else > + *p++ = ' '; > + } > + > return result; > } > > @@ -284,8 +319,11 @@ decode_cmdline_options_to_array (unsigne > opt_array[0].opt_index = OPT_SPECIAL_program_name; > opt_array[0].arg = argv[0]; > opt_array[0].orig_option_with_args_text = argv[0]; > + opt_array[0].canonical_option_num_elements = 1; > opt_array[0].canonical_option[0] = argv[0]; > opt_array[0].canonical_option[1] = NULL; > + opt_array[0].canonical_option[2] = NULL; > + opt_array[0].canonical_option[3] = NULL; > opt_array[0].value = 1; > opt_array[0].errors = 0; > num_decoded_options = 1; > @@ -300,8 +338,11 @@ decode_cmdline_options_to_array (unsigne > opt_array[num_decoded_options].opt_index = OPT_SPECIAL_input_file; > opt_array[num_decoded_options].arg = opt; > opt_array[num_decoded_options].orig_option_with_args_text = opt; > + opt_array[num_decoded_options].canonical_option_num_elements = 1; > opt_array[num_decoded_options].canonical_option[0] = opt; > opt_array[num_decoded_options].canonical_option[1] = NULL; > + opt_array[num_decoded_options].canonical_option[2] = NULL; > + opt_array[num_decoded_options].canonical_option[3] = NULL; > opt_array[num_decoded_options].value = 1; > opt_array[num_decoded_options].errors = 0; > num_decoded_options++; > diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/opts.h gcc-mainline/gcc/opts.h > --- gcc-mainline-opt3/gcc/opts.h 2010-06-22 15:15:44.000000000 -0700 > +++ gcc-mainline/gcc/opts.h 2010-06-23 07:30:21.000000000 -0700 > @@ -121,10 +121,12 @@ struct cl_decoded_option > /* The canonical form of the option and its argument, for when it is > necessary to reconstruct argv elements (in particular, for > processing specs and passing options to subprocesses from the > - driver). The first element of this array is non-NULL; the second > - is NULL if the canonical form uses only one argv element, > - non-NULL otherwise. */ > - const char *canonical_option[2]; > + driver). */ > + const char *canonical_option[4]; > + > + /* The number of elements in the canonical form of the option and > + arguments; always at least 1. */ > + size_t canonical_option_num_elements; > > /* For a boolean option, 1 for the true case and 0 for the "no-" > case. For an unsigned integer option, the value of the > > -- > Joseph S. Myers > joseph@codesourcery.com >
On 06/23/2010 10:26 PM, Joseph S. Myers wrote: > Bootstrapped with no regressions on x86_64-unknown-linux-gnu. OK to > commit? > I regard the Fortran changes as trivial/obvious. But for completeness: The Fortran part is OK. Tobias > fortran: > 2010-06-23 Joseph Myers <joseph@codesourcery.com> > > * gfortranspec.c (SWITCH_TAKES_ARG, WORD_SWITCH_TAKES_ARG): > Remove
diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/Makefile.in gcc-mainline/gcc/Makefile.in --- gcc-mainline-opt3/gcc/Makefile.in 2010-06-22 15:24:00.000000000 -0700 +++ gcc-mainline/gcc/Makefile.in 2010-06-23 08:44:22.000000000 -0700 @@ -2796,7 +2796,7 @@ opts.o : opts.c opts.h options.h $(TOPLE $(FLAGS_H) $(PARAMS_H) $(TREE_PASS_H) $(DBGCNT_H) debug.h \ $(PLUGIN_H) $(EXCEPT_H) $(LTO_STREAMER_H) opts-diagnostic.h opts-common.o : opts-common.c opts.h $(CONFIG_H) $(SYSTEM_H) \ - coretypes.h intl.h $(DIAGNOSTIC_H) + coretypes.h intl.h $(DIAGNOSTIC_H) $(TM_H) targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \ $(EXPR_H) $(TM_H) $(RTL_H) $(TM_P_H) $(FUNCTION_H) output.h $(TOPLEV_H) \ $(MACHMODE_H) $(TARGET_DEF_H) $(TARGET_H) $(GGC_H) gt-targhooks.h \ diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/ada/gcc-interface/misc.c gcc-mainline/gcc/ada/gcc-interface/misc.c --- gcc-mainline-opt3/gcc/ada/gcc-interface/misc.c 2010-06-22 16:02:04.000000000 -0700 +++ gcc-mainline/gcc/ada/gcc-interface/misc.c 2010-06-23 07:46:46.000000000 -0700 @@ -303,8 +303,13 @@ gnat_init_options (unsigned int decoded_ save_argc = 0; for (i = 0; i < decoded_options_count; i++) { + if (decoded_options[i].errors + || decoded_options[i].opt_index == OPT_SPECIAL_unknown) + continue; + gcc_assert (decoded_options[i].canonical_option_num_elements >= 1 + && decoded_options[i].canonical_option_num_elements <= 2); save_argv[save_argc++] = decoded_options[i].canonical_option[0]; - if (decoded_options[i].canonical_option[1] != NULL) + if (decoded_options[i].canonical_option_num_elements >= 2) save_argv[save_argc++] = decoded_options[i].canonical_option[1]; } save_argv[save_argc] = NULL; diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/config/darwin-driver.c gcc-mainline/gcc/config/darwin-driver.c --- gcc-mainline-opt3/gcc/config/darwin-driver.c 2010-06-04 06:35:13.000000000 -0700 +++ gcc-mainline/gcc/config/darwin-driver.c 2010-06-23 08:24:32.000000000 -0700 @@ -27,14 +27,6 @@ along with GCC; see the file COPYING3. #include <sys/sysctl.h> #include "xregex.h" -#ifndef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) -#endif - -#ifndef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) -#endif - /* When running on a Darwin system and using that system's headers and libraries, default the -mmacosx-version-min flag to be the version of the system on which the compiler is running. */ diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/cppspec.c gcc-mainline/gcc/cppspec.c --- gcc-mainline-opt3/gcc/cppspec.c 2010-06-04 06:40:58.000000000 -0700 +++ gcc-mainline/gcc/cppspec.c 2010-06-23 08:24:05.000000000 -0700 @@ -30,14 +30,6 @@ along with GCC; see the file COPYING3. assume the user knows what they're doing. If no explicit input is mentioned, it will read stdin. */ -#ifndef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) -#endif - -#ifndef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) -#endif - /* Suffixes for known sorts of input files. Note that we do not list files which are normally considered to have been preprocessed already, since the user's expectation is that `cpp' always preprocesses. */ diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/defaults.h gcc-mainline/gcc/defaults.h --- gcc-mainline-opt3/gcc/defaults.h 2010-06-11 02:16:45.000000000 -0700 +++ gcc-mainline/gcc/defaults.h 2010-06-23 08:24:12.000000000 -0700 @@ -32,6 +32,38 @@ see the files COPYING3 and COPYING.RUNTI #define GET_ENVIRONMENT(VALUE, NAME) do { (VALUE) = getenv (NAME); } while (0) #endif +/* This defines which switch letters take arguments. */ + +#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \ + ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \ + || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \ + || (CHAR) == 'I' || (CHAR) == 'J' || (CHAR) == 'm' \ + || (CHAR) == 'x' || (CHAR) == 'L' || (CHAR) == 'A' \ + || (CHAR) == 'B' ) + +/* This defines which multi-letter switches take arguments. */ + +#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \ + (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \ + || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \ + || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \ + || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \ + || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \ + || !strcmp (STR, "iquote") || !strcmp (STR, "isystem") \ + || !strcmp (STR, "isysroot") \ + || !strcmp (STR, "-param") || !strcmp (STR, "specs") \ + || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ") \ + || !strcmp (STR, "fintrinsic-modules-path") \ + || !strcmp (STR, "dumpbase") || !strcmp (STR, "dumpdir")) + +#ifndef SWITCH_TAKES_ARG +#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG (CHAR) +#endif + +#ifndef WORD_SWITCH_TAKES_ARG +#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) +#endif + /* Store in OUTPUT a string (made with alloca) containing an assembler-name for a local static variable or function named NAME. LABELNO is an integer which is different for each call. */ diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/fortran/gfortranspec.c gcc-mainline/gcc/fortran/gfortranspec.c --- gcc-mainline-opt3/gcc/fortran/gfortranspec.c 2010-06-16 09:07:30.000000000 -0700 +++ gcc-mainline/gcc/fortran/gfortranspec.c 2010-06-23 08:25:11.000000000 -0700 @@ -113,22 +113,6 @@ static void append_arg (const char *); static int g77_newargc; static const char **g77_newargv; -/* --- This comes from gcc.c (2.8.1) verbatim: */ - -/* This defines which switch letters take arguments. */ - -#ifndef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) -#endif - -/* This defines which multi-letter switches take arguments. */ - -#ifndef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) -#endif - -/* --- End of verbatim. */ - /* Assumes text[0] == '-'. Returns number of argv items that belong to (and follow) this one, an option id for options important to the caller, and a pointer to the first char of the arg, if embedded (else diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/gcc.c gcc-mainline/gcc/gcc.c --- gcc-mainline-opt3/gcc/gcc.c 2010-06-07 02:48:58.000000000 -0700 +++ gcc-mainline/gcc/gcc.c 2010-06-23 08:22:19.000000000 -0700 @@ -975,13 +975,6 @@ struct user_specs static struct user_specs *user_specs_head, *user_specs_tail; -#ifndef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) -#endif - -#ifndef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) -#endif #ifdef HAVE_TARGET_EXECUTABLE_SUFFIX /* This defines which switches stop a full compilation. */ diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/gcc.h gcc-mainline/gcc/gcc.h --- gcc-mainline-opt3/gcc/gcc.h 2010-05-28 12:31:35.000000000 -0700 +++ gcc-mainline/gcc/gcc.h 2010-06-23 08:21:07.000000000 -0700 @@ -32,31 +32,6 @@ struct spec_function const char *(*func) (int, const char **); }; -/* This defines which switch letters take arguments. */ - -#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \ - ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \ - || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \ - || (CHAR) == 'I' || (CHAR) == 'J' || (CHAR) == 'm' \ - || (CHAR) == 'x' || (CHAR) == 'L' || (CHAR) == 'A' \ - || (CHAR) == 'B' ) - -/* This defines which multi-letter switches take arguments. */ - -#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \ - (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \ - || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \ - || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \ - || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \ - || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \ - || !strcmp (STR, "iquote") || !strcmp (STR, "isystem") \ - || !strcmp (STR, "isysroot") \ - || !strcmp (STR, "-param") || !strcmp (STR, "specs") \ - || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ") \ - || !strcmp (STR, "fintrinsic-modules-path") \ - || !strcmp (STR, "dumpbase") || !strcmp (STR, "dumpdir")) - - /* These are exported by gcc.c. */ extern int do_spec (const char *); extern void record_temp_file (const char *, int, int); diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/opts-common.c gcc-mainline/gcc/opts-common.c --- gcc-mainline-opt3/gcc/opts-common.c 2010-06-22 15:23:48.000000000 -0700 +++ gcc-mainline/gcc/opts-common.c 2010-06-23 11:44:40.000000000 -0700 @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. #include "opts.h" #include "options.h" #include "diagnostic.h" +#include "tm.h" /* For SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG. */ /* Perform a binary search to find which option the command-line INPUT matches. Returns its index in the option array, and @@ -138,7 +139,9 @@ decode_cmdline_option (const char **argv const char *opt, *arg = 0; char *dup = 0; int value = 1; - unsigned int result = 1; + unsigned int result = 1, i; + size_t total_len; + char *p; const struct cl_option *option; int errors = 0; @@ -242,22 +245,54 @@ decode_cmdline_option (const char **argv decoded->arg = arg; decoded->value = value; decoded->errors = errors; - switch (result) + + if (opt_index == OPT_SPECIAL_unknown) { - case 1: - decoded->orig_option_with_args_text = argv[0]; - decoded->canonical_option[0] = argv[0]; - decoded->canonical_option[1] = NULL; - break; - case 2: - decoded->orig_option_with_args_text = concat (argv[0], " ", - argv[1], NULL); - decoded->canonical_option[0] = argv[0]; - decoded->canonical_option[1] = argv[1]; - break; - default: - gcc_unreachable (); + /* Skip the correct number of arguments for options handled + through specs. */ + const char *popt = argv[0] + 1; + int c = *popt; + + gcc_assert (result == 1); + if (SWITCH_TAKES_ARG (c) > (popt[1] != 0)) + result += SWITCH_TAKES_ARG (c) - (popt[1] != 0); + else if (WORD_SWITCH_TAKES_ARG (popt)) + result += WORD_SWITCH_TAKES_ARG (popt); + if (result > 1) + for (i = 1; i < result; i++) + if (argv[i] == NULL) + { + result = i; + break; + } } + + gcc_assert (result >= 1 && result <= ARRAY_SIZE (decoded->canonical_option)); + decoded->canonical_option_num_elements = result; + total_len = 0; + for (i = 0; i < ARRAY_SIZE (decoded->canonical_option); i++) + { + if (i < result) + { + decoded->canonical_option[i] = argv[i]; + total_len += strlen (argv[i]) + 1; + } + else + decoded->canonical_option[i] = NULL; + } + decoded->orig_option_with_args_text = p = XNEWVEC (char, total_len); + for (i = 0; i < result; i++) + { + size_t len = strlen (argv[i]); + + memcpy (p, argv[i], len); + p += len; + if (i == result - 1) + *p++ = 0; + else + *p++ = ' '; + } + return result; } @@ -284,8 +319,11 @@ decode_cmdline_options_to_array (unsigne opt_array[0].opt_index = OPT_SPECIAL_program_name; opt_array[0].arg = argv[0]; opt_array[0].orig_option_with_args_text = argv[0]; + opt_array[0].canonical_option_num_elements = 1; opt_array[0].canonical_option[0] = argv[0]; opt_array[0].canonical_option[1] = NULL; + opt_array[0].canonical_option[2] = NULL; + opt_array[0].canonical_option[3] = NULL; opt_array[0].value = 1; opt_array[0].errors = 0; num_decoded_options = 1; @@ -300,8 +338,11 @@ decode_cmdline_options_to_array (unsigne opt_array[num_decoded_options].opt_index = OPT_SPECIAL_input_file; opt_array[num_decoded_options].arg = opt; opt_array[num_decoded_options].orig_option_with_args_text = opt; + opt_array[num_decoded_options].canonical_option_num_elements = 1; opt_array[num_decoded_options].canonical_option[0] = opt; opt_array[num_decoded_options].canonical_option[1] = NULL; + opt_array[num_decoded_options].canonical_option[2] = NULL; + opt_array[num_decoded_options].canonical_option[3] = NULL; opt_array[num_decoded_options].value = 1; opt_array[num_decoded_options].errors = 0; num_decoded_options++; diff -rupN --exclude=.svn gcc-mainline-opt3/gcc/opts.h gcc-mainline/gcc/opts.h --- gcc-mainline-opt3/gcc/opts.h 2010-06-22 15:15:44.000000000 -0700 +++ gcc-mainline/gcc/opts.h 2010-06-23 07:30:21.000000000 -0700 @@ -121,10 +121,12 @@ struct cl_decoded_option /* The canonical form of the option and its argument, for when it is necessary to reconstruct argv elements (in particular, for processing specs and passing options to subprocesses from the - driver). The first element of this array is non-NULL; the second - is NULL if the canonical form uses only one argv element, - non-NULL otherwise. */ - const char *canonical_option[2]; + driver). */ + const char *canonical_option[4]; + + /* The number of elements in the canonical form of the option and + arguments; always at least 1. */ + size_t canonical_option_num_elements; /* For a boolean option, 1 for the true case and 0 for the "no-" case. For an unsigned integer option, the value of the