diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5983420620c..83ca51b6fcf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,28 @@ +2010-09-22 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. + 2010-09-22 Joseph Myers * common.opt (-assemble, -compile, -coverage, -debug, -dump, diff --git a/gcc/config/darwin-driver.c b/gcc/config/darwin-driver.c index b23efc50c0a..099226c25d3 100644 --- a/gcc/config/darwin-driver.c +++ b/gcc/config/darwin-driver.c @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #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. If not see 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 *** argv_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, char *** argv_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, char *** argv_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 --git a/gcc/config/darwin.h b/gcc/config/darwin.h index 3314acb1912..f0ff9010b93 100644 --- a/gcc/config/darwin.h +++ b/gcc/config/darwin.h @@ -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 --git a/gcc/config/i386/cygwin.h b/gcc/config/i386/cygwin.h index a8d26e9558d..67308fc7dff 100644 --- a/gcc/config/i386/cygwin.h +++ b/gcc/config/i386/cygwin.h @@ -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 --git a/gcc/config/i386/cygwin1.c b/gcc/config/i386/cygwin1.c index 7de34d24b7a..99d9d8f8243 100644 --- a/gcc/config/i386/cygwin1.c +++ b/gcc/config/i386/cygwin1.c @@ -22,32 +22,42 @@ along with GCC; see the file COPYING3. If not see #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 --git a/gcc/config/i386/t-cygwin b/gcc/config/i386/t-cygwin index af91aa5cdb6..a01219cfb9d 100644 --- a/gcc/config/i386/t-cygwin +++ b/gcc/config/i386/t-cygwin @@ -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)/../winsup/include \ -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 --git a/gcc/config/t-darwin b/gcc/config/t-darwin index b538ccfa405..70c0da54bbc 100644 --- a/gcc/config/t-darwin +++ b/gcc/config/t-darwin @@ -36,7 +36,7 @@ darwin-f.o: $(srcdir)/config/darwin-f.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(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 --git a/gcc/gcc.c b/gcc/gcc.c index 83bfbb9ee6b..2614faf5b7b 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -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); @@ -3506,7 +3506,8 @@ driver_handle_option (const struct cl_decoded_option *decoded, 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; @@ -3514,8 +3515,7 @@ process_command (int argc, const char **argv) 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"); @@ -3536,9 +3536,6 @@ process_command (int argc, const char **argv) } } - 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. */ @@ -3555,17 +3552,18 @@ process_command (int argc, const char **argv) 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) @@ -3592,7 +3590,8 @@ process_command (int argc, const char **argv) #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, @@ -3888,7 +3887,7 @@ process_command (int argc, const char **argv) ``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) @@ -6099,6 +6098,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. */ @@ -6117,7 +6118,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. */ @@ -6207,7 +6211,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 --git a/gcc/opts-common.c b/gcc/opts-common.c index 678b60e891b..078610fdb57 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -27,6 +27,8 @@ along with GCC; see the file COPYING3. If not see #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 (unsigned int argc, const char **argv, 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_idx, int orig_next_opt_idx) /* 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++) - { - int value = 1; - const char *opt = (*argvp) [i]; - - 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 (opt_index == OPT_SPECIAL_unknown) - { -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]; - } - - 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++) + new_decoded_options_count = 0; + for (i = 0; i < old_decoded_options_count; i++) { - int j, opt_idx; + unsigned int j, opt_idx, next_opt_idx; - opt_idx = options [i]; - if (opt_idx) - { - int next_opt_idx; - for (j = i + 1; j < argc; j++) - { - next_opt_idx = options [j]; - if (next_opt_idx - && cancel_option (opt_idx, next_opt_idx, - next_opt_idx)) - break; - } - } - else + if (old_decoded_options[i].errors & ~CL_ERR_WRONG_LANG) goto keep; - if (j == argc) + opt_idx = old_decoded_options[i].opt_index; + switch (opt_idx) { + 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; + + for (j = i + 1; j < old_decoded_options_count; j++) + { + 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; + } + 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 --git a/gcc/opts.h b/gcc/opts.h index ed175e5de4a..c4d253ff04a 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -206,7 +206,6 @@ extern void decode_cmdline_options_to_array (unsigned int argc, 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);