This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Merge two passes over options in gcc.c


On Sat, Jun 26, 2010 at 3:05 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> Continuing preparation for making the driver share option processing
> machinery with the compiler proper, this patch replaces two passes
> over options in the driver with a single pass, which fits more
> naturally with the option processing model used elsewhere of a pass
> over options that calls appropriate handlers for each option in turn.
> (There are several other passes to assimilate to the model of first
> decoding options then working with decoded options, but these two
> passes are the main ones that will need converting to use decoded
> options as part of the initial integration of shared option processing
> machinery in the driver; the others can follow later.)
>
> Previously, the first pass would act on some options and work out how
> much memory to allocate for other options and input files, while the
> second pass would act on other options and store options for use of
> specs as well as storing a list of input files. ?By making the code
> increase the size of the relevant arrays as needed (size doubling like
> this is already used elsewhere in the driver), the two passes can be
> integrated.
>
> The two passes were in fact out of sync as regards -Xpreprocessor and
> -Xassembler; the second pass would skip their operands when looking
> for the next option, but the first pass would not, resulting in such
> operands being wrongly interpreted as driver options.
>
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu. ?OK to
> commit?

Ok.

Thanks,
Richard.

> 2010-06-26 ?Joseph Myers ?<joseph@codesourcery.com>
>
> ? ? ? ?* gcc.c (n_switches_alloc, n_infiles_alloc, alloc_infile,
> ? ? ? ?add_infile, alloc_switch): New.
> ? ? ? ?(process_command): Remove variable lang_n_infiles. ?Process
> ? ? ? ?options in a single pass. ?Use new functions for allocating
> ? ? ? ?infiles and switches arrays. ?Properly skip operands of
> ? ? ? ?-Xpreprocessor and -Xassembler.
>
> testsuite:
> 2010-06-26 ?Joseph Myers ?<joseph@codesourcery.com>
>
> ? ? ? ?* gcc.dg/opts-3.c: New test.
>
> diff -rupN --exclude=.svn gcc-mainline-opt4-takes-arg/gcc/gcc.c gcc-mainline/gcc/gcc.c
> --- gcc-mainline-opt4-takes-arg/gcc/gcc.c ? ? ? 2010-06-25 08:11:25.000000000 -0700
> +++ gcc-mainline/gcc/gcc.c ? ? ?2010-06-26 03:36:56.000000000 -0700
> @@ -3244,6 +3244,8 @@ static struct switchstr *switches;
>
> ?static int n_switches;
>
> +static int n_switches_alloc;
> +
> ?/* Set to zero if -fcompare-debug is disabled, positive if it's
> ? ?enabled and we're running the first compilation, negative if it's
> ? ?enabled and we're running the second compilation. ?For most of the
> @@ -3289,6 +3291,8 @@ static struct infile *infiles;
>
> ?int n_infiles;
>
> +static int n_infiles_alloc;
> +
> ?/* True if multiple input files are being compiled to a single
> ? ?assembly file. ?*/
>
> @@ -3473,6 +3477,51 @@ add_linker_option (const char *option, i
> ? linker_options [n_linker_options - 1] = save_string (option, len);
> ?}
>
> +/* Allocate space for an input file in infiles. ?*/
> +
> +static void
> +alloc_infile (void)
> +{
> + ?if (n_infiles_alloc == 0)
> + ? ?{
> + ? ? ?n_infiles_alloc = 16;
> + ? ? ?infiles = XNEWVEC (struct infile, n_infiles_alloc);
> + ? ?}
> + ?else if (n_infiles_alloc == n_infiles)
> + ? ?{
> + ? ? ?n_infiles_alloc *= 2;
> + ? ? ?infiles = XRESIZEVEC (struct infile, infiles, n_infiles_alloc);
> + ? ?}
> +}
> +
> +/* Store an input file with the given NAME and LANGUAGE in
> + ? infiles. ?*/
> +
> +static void
> +add_infile (const char *name, const char *language)
> +{
> + ?alloc_infile ();
> + ?infiles[n_infiles].name = name;
> + ?infiles[n_infiles++].language = language;
> +}
> +
> +/* Allocate space for a switch in switches. ?*/
> +
> +static void
> +alloc_switch (void)
> +{
> + ?if (n_switches_alloc == 0)
> + ? ?{
> + ? ? ?n_switches_alloc = 16;
> + ? ? ?switches = XNEWVEC (struct switchstr, n_switches_alloc);
> + ? ?}
> + ?else if (n_switches_alloc == n_switches)
> + ? ?{
> + ? ? ?n_switches_alloc *= 2;
> + ? ? ?switches = XRESIZEVEC (struct switchstr, switches, n_switches_alloc);
> + ? ?}
> +}
> +
> ?/* Create the vector `switches' and its contents.
> ? ?Store its length in `n_switches'. ?*/
>
> @@ -3484,7 +3533,6 @@ process_command (int argc, const char **
> ? char *temp1;
> ? const char *spec_lang = 0;
> ? int last_language_n_infiles;
> - ?int lang_n_infiles = 0;
> ? const char *tooldir_prefix;
> ? char *(*get_relative_prefix) (const char *, const char *,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const char *) = NULL;
> @@ -3698,12 +3746,22 @@ process_command (int argc, const char **
> ? ? ? ?}
> ? ? }
>
> - ?/* Scan argv twice. ?Here, the first time, just count how many switches
> - ? ? there will be in their vector, and how many input files in theirs.
> - ? ? Here we also parse the switches that cc itself uses (e.g. -v). ?*/
> + ?/* Process the options and store input files and switches in their
> + ? ? vectors. ?*/
> +
> + ?last_language_n_infiles = -1;
>
> ? for (i = 1; i < argc; i++)
> ? ? {
> + ? ? ?const char *p = NULL;
> + ? ? ?int c = 0;
> +
> + ? ? ?if (argv[i][0] == '-' && argv[i][1] != 0)
> + ? ? ? {
> + ? ? ? ? p = &argv[i][1];
> + ? ? ? ? c = *p;
> + ? ? ? }
> +
> ? ? ? if (! strcmp (argv[i], "-dumpspecs"))
> ? ? ? ?{
> ? ? ? ? ?struct spec_list *sl;
> @@ -3729,59 +3787,50 @@ process_command (int argc, const char **
> ? ? ? ? ?/* translate_options () has turned --version into -fversion. ?*/
> ? ? ? ? ?print_version = 1;
>
> - ? ? ? ? /* We will be passing a dummy file on to the sub-processes. ?*/
> - ? ? ? ? n_infiles++;
> - ? ? ? ? n_switches++;
> -
> ? ? ? ? ?/* CPP driver cannot obtain switch from cc1_options. ?*/
> ? ? ? ? ?if (is_cpp_driver)
> ? ? ? ? ? ?add_preprocessor_option ("--version", strlen ("--version"));
> ? ? ? ? ?add_assembler_option ("--version", strlen ("--version"));
> ? ? ? ? ?add_linker_option ("--version", strlen ("--version"));
> +
> + ? ? ? ? goto normal_switch;
> ? ? ? ?}
> ? ? ? else if (strcmp (argv[i], "-fhelp") == 0)
> ? ? ? ?{
> ? ? ? ? ?/* translate_options () has turned --help into -fhelp. ?*/
> ? ? ? ? ?print_help_list = 1;
>
> - ? ? ? ? /* We will be passing a dummy file on to the sub-processes. ?*/
> - ? ? ? ? n_infiles++;
> - ? ? ? ? n_switches++;
> -
> ? ? ? ? ?/* CPP driver cannot obtain switch from cc1_options. ?*/
> ? ? ? ? ?if (is_cpp_driver)
> ? ? ? ? ? ?add_preprocessor_option ("--help", 6);
> ? ? ? ? ?add_assembler_option ("--help", 6);
> ? ? ? ? ?add_linker_option ("--help", 6);
> +
> + ? ? ? ? goto normal_switch;
> ? ? ? ?}
> ? ? ? else if (strncmp (argv[i], "-fhelp=", 7) == 0)
> ? ? ? ?{
> ? ? ? ? ?/* translate_options () has turned --help into -fhelp. ?*/
> ? ? ? ? ?print_subprocess_help = 2;
>
> - ? ? ? ? /* We will be passing a dummy file on to the sub-processes. ?*/
> - ? ? ? ? n_infiles++;
> - ? ? ? ? n_switches++;
> + ? ? ? ? goto normal_switch;
> ? ? ? ?}
> ? ? ? else if (strcmp (argv[i], "-ftarget-help") == 0)
> ? ? ? ?{
> ? ? ? ? ?/* translate_options() has turned --target-help into -ftarget-help. ?*/
> ? ? ? ? ?print_subprocess_help = 1;
>
> - ? ? ? ? /* We will be passing a dummy file on to the sub-processes. ?*/
> - ? ? ? ? n_infiles++;
> - ? ? ? ? n_switches++;
> -
> ? ? ? ? ?/* CPP driver cannot obtain switch from cc1_options. ?*/
> ? ? ? ? ?if (is_cpp_driver)
> ? ? ? ? ? ?add_preprocessor_option ("--target-help", 13);
> ? ? ? ? ?add_assembler_option ("--target-help", 13);
> ? ? ? ? ?add_linker_option ("--target-help", 13);
> +
> + ? ? ? ? goto normal_switch;
> ? ? ? ?}
> ? ? ? else if (! strcmp (argv[i], "-pass-exit-codes"))
> ? ? ? ?{
> ? ? ? ? ?pass_exit_codes = 1;
> - ? ? ? ? n_switches++;
> ? ? ? ?}
> ? ? ? else if (! strcmp (argv[i], "-print-search-dirs"))
> ? ? ? ?print_search_dirs = 1;
> @@ -3804,16 +3853,18 @@ process_command (int argc, const char **
> ? ? ? else if (! strcmp (argv[i], "-fcompare-debug-second"))
> ? ? ? ?{
> ? ? ? ? ?compare_debug_second = 1;
> - ? ? ? ? n_switches++;
> + ? ? ? ? goto normal_switch;
> ? ? ? ?}
> ? ? ? else if (! strcmp (argv[i], "-fno-compare-debug"))
> ? ? ? ?{
> ? ? ? ? ?argv[i] = "-fcompare-debug=";
> + ? ? ? ? p = &argv[i][1];
> ? ? ? ? ?goto compare_debug_with_arg;
> ? ? ? ?}
> ? ? ? else if (! strcmp (argv[i], "-fcompare-debug"))
> ? ? ? ?{
> ? ? ? ? ?argv[i] = "-fcompare-debug=-gtoggle";
> + ? ? ? ? p = &argv[i][1];
> ? ? ? ? ?goto compare_debug_with_arg;
> ? ? ? ?}
> ?#define OPT "-fcompare-debug="
> @@ -3831,7 +3882,7 @@ process_command (int argc, const char **
> ? ? ? ? ? ?compare_debug_opt = NULL;
> ? ? ? ? ?else
> ? ? ? ? ? ?compare_debug_opt = opt;
> - ? ? ? ? n_switches++;
> + ? ? ? ? goto normal_switch;
> ? ? ? ?}
> ? ? ? else if (! strncmp (argv[i], "-Wa,", 4))
> ? ? ? ?{
> @@ -3869,17 +3920,24 @@ process_command (int argc, const char **
> ? ? ? ?}
> ? ? ? else if (strncmp (argv[i], "-Wl,", 4) == 0)
> ? ? ? ?{
> - ? ? ? ? int j;
> + ? ? ? ? int prev, j;
> ? ? ? ? ?/* Split the argument at commas. ?*/
> - ? ? ? ? for (j = 3; argv[i][j]; j++)
> - ? ? ? ? ? n_infiles += (argv[i][j] == ',');
> + ? ? ? ? prev = 4;
> + ? ? ? ? for (j = 4; argv[i][j]; j++)
> + ? ? ? ? ? if (argv[i][j] == ',')
> + ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? add_infile (save_string (argv[i] + prev, j - prev), "*");
> + ? ? ? ? ? ? ? prev = j + 1;
> + ? ? ? ? ? ? }
> + ? ? ? ? /* Record the part after the last comma. ?*/
> + ? ? ? ? add_infile (argv[i] + prev, "*");
> ? ? ? ?}
> ? ? ? else if (strcmp (argv[i], "-Xlinker") == 0)
> ? ? ? ?{
> ? ? ? ? ?if (i + 1 == argc)
> ? ? ? ? ? ?fatal_error ("argument to %<-Xlinker%> is missing");
>
> - ? ? ? ? n_infiles++;
> + ? ? ? ? add_infile (argv[i+1], "*");
> ? ? ? ? ?i++;
> ? ? ? ?}
> ? ? ? else if (strcmp (argv[i], "-Xpreprocessor") == 0)
> @@ -3888,6 +3946,7 @@ process_command (int argc, const char **
> ? ? ? ? ? ?fatal_error ("argument to %<-Xpreprocessor%> is missing");
>
> ? ? ? ? ?add_preprocessor_option (argv[i+1], strlen (argv[i+1]));
> + ? ? ? ? i++;
> ? ? ? ?}
> ? ? ? else if (strcmp (argv[i], "-Xassembler") == 0)
> ? ? ? ?{
> @@ -3895,25 +3954,29 @@ process_command (int argc, const char **
> ? ? ? ? ? ?fatal_error ("argument to %<-Xassembler%> is missing");
>
> ? ? ? ? ?add_assembler_option (argv[i+1], strlen (argv[i+1]));
> + ? ? ? ? i++;
> ? ? ? ?}
> ? ? ? else if (strcmp (argv[i], "-l") == 0)
> ? ? ? ?{
> ? ? ? ? ?if (i + 1 == argc)
> ? ? ? ? ? ?fatal_error ("argument to %<-l%> is missing");
>
> - ? ? ? ? n_infiles++;
> + ? ? ? ? /* POSIX allows separation of -l and the lib arg;
> + ? ? ? ? ? ?canonicalize by concatenating -l with its arg */
> + ? ? ? ? add_infile (concat ("-l", argv[i + 1], NULL), "*");
> ? ? ? ? ?i++;
> ? ? ? ?}
> ? ? ? else if (strncmp (argv[i], "-l", 2) == 0)
> - ? ? ? n_infiles++;
> + ? ? ? {
> + ? ? ? ? add_infile (argv[i], "*");
> + ? ? ? }
> ? ? ? else if (strcmp (argv[i], "-save-temps") == 0)
> ? ? ? ?{
> ? ? ? ? ?save_temps_flag = SAVE_TEMPS_CWD;
> - ? ? ? ? n_switches++;
> + ? ? ? ? goto normal_switch;
> ? ? ? ?}
> ? ? ? else if (strncmp (argv[i], "-save-temps=", 12) == 0)
> ? ? ? ?{
> - ? ? ? ? n_switches++;
> ? ? ? ? ?if (strcmp (argv[i]+12, "cwd") == 0)
> ? ? ? ? ? ?save_temps_flag = SAVE_TEMPS_CWD;
> ? ? ? ? ?else if (strcmp (argv[i]+12, "obj") == 0
> @@ -3921,6 +3984,7 @@ process_command (int argc, const char **
> ? ? ? ? ? ?save_temps_flag = SAVE_TEMPS_OBJ;
> ? ? ? ? ?else
> ? ? ? ? ? ?fatal_error ("%qs is an unknown -save-temps option", argv[i]);
> + ? ? ? ? goto normal_switch;
> ? ? ? ?}
> ? ? ? else if (strcmp (argv[i], "-no-canonical-prefixes") == 0)
> ? ? ? ?/* Already handled as a special case, so ignored here. ?*/
> @@ -3928,7 +3992,7 @@ process_command (int argc, const char **
> ? ? ? else if (strcmp (argv[i], "-combine") == 0)
> ? ? ? ?{
> ? ? ? ? ?combine_flag = 1;
> - ? ? ? ? n_switches++;
> + ? ? ? ? goto normal_switch;
> ? ? ? ?}
> ? ? ? else if (strcmp (argv[i], "-specs") == 0)
> ? ? ? ?{
> @@ -3958,6 +4022,11 @@ process_command (int argc, const char **
> ? ? ? ? ? ?user_specs_head = user;
> ? ? ? ? ?user_specs_tail = user;
> ? ? ? ?}
> + ? ? ?else if (! strncmp (argv[i], "--sysroot=", strlen ("--sysroot=")))
> + ? ? ? {
> + ? ? ? ? target_system_root = argv[i] + strlen ("--sysroot=");
> + ? ? ? ? target_system_root_changed = 1;
> + ? ? ? }
> ? ? ? else if (strcmp (argv[i], "-time") == 0)
> ? ? ? ?report_times = 1;
> ? ? ? else if (strncmp (argv[i], "-time=", sizeof ("-time=") - 1) == 0)
> @@ -3971,7 +4040,7 @@ process_command (int argc, const char **
> ? ? ? ? ?/* -pipe has to go into the switches array as well as
> ? ? ? ? ? ? setting a flag. ?*/
> ? ? ? ? ?use_pipes = 1;
> - ? ? ? ? n_switches++;
> + ? ? ? ? goto normal_switch;
> ? ? ? ?}
> ? ? ? else if (strcmp (argv[i], "-wrapper") == 0)
> ? ? ? ? {
> @@ -3979,8 +4048,6 @@ process_command (int argc, const char **
> ? ? ? ? ? ?fatal_error ("argument to %<-wrapper%> is missing");
>
> ? ? ? ? ? wrapper_string = argv[i];
> - ? ? ? ? n_switches++;
> - ? ? ? ? n_switches++;
> ? ? ? ? }
> ? ? ? else if (strcmp (argv[i], "-###") == 0)
> ? ? ? ?{
> @@ -3993,9 +4060,6 @@ process_command (int argc, const char **
> ? ? ? ?}
> ? ? ? else if (argv[i][0] == '-' && argv[i][1] != 0)
> ? ? ? ?{
> - ? ? ? ? const char *p = &argv[i][1];
> - ? ? ? ? int c = *p;
> -
> ? ? ? ? ?switch (c)
> ? ? ? ? ? ?{
> ? ? ? ? ? ?case 'B':
> @@ -4006,7 +4070,7 @@ process_command (int argc, const char **
> ? ? ? ? ? ? ? ?if (p[1] == 0 && i + 1 == argc)
> ? ? ? ? ? ? ? ? ?fatal_error ("argument to %<-B%> is missing");
> ? ? ? ? ? ? ? ?if (p[1] == 0)
> - ? ? ? ? ? ? ? ? value = argv[++i];
> + ? ? ? ? ? ? ? ? value = argv[i + 1];
> ? ? ? ? ? ? ? ?else
> ? ? ? ? ? ? ? ? ?value = p + 1;
>
> @@ -4035,28 +4099,38 @@ process_command (int argc, const char **
> ? ? ? ? ? ? ? ? ? ? ? ? ? ?PREFIX_PRIORITY_B_OPT, 0, 0);
> ? ? ? ? ? ? ? ?add_prefix (&include_prefixes, value, NULL,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ?PREFIX_PRIORITY_B_OPT, 0, 0);
> - ? ? ? ? ? ? ? n_switches++;
> ? ? ? ? ? ? ?}
> - ? ? ? ? ? ? break;
> + ? ? ? ? ? ? goto normal_switch;
>
> ? ? ? ? ? ?case 'v': ? /* Print our subcommands and print versions. ?*/
> - ? ? ? ? ? ? n_switches++;
> ? ? ? ? ? ? ?/* If they do anything other than exactly `-v', don't set
> ? ? ? ? ? ? ? ? verbose_flag; rather, continue on to give the error. ?*/
> ? ? ? ? ? ? ?if (p[1] != 0)
> ? ? ? ? ? ? ? ?break;
> ? ? ? ? ? ? ?verbose_flag++;
> + ? ? ? ? ? ? goto normal_switch;
> +
> + ? ? ? ? ? case 'x':
> + ? ? ? ? ? ? if (p[1] == 0 && i + 1 == argc)
> + ? ? ? ? ? ? ? fatal_error ("argument to %<-x%> is missing");
> + ? ? ? ? ? ? if (p[1] == 0)
> + ? ? ? ? ? ? ? spec_lang = argv[++i];
> + ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? spec_lang = p + 1;
> + ? ? ? ? ? ? if (! strcmp (spec_lang, "none"))
> + ? ? ? ? ? ? ? /* Suppress the warning if -xnone comes after the last input
> + ? ? ? ? ? ? ? ? ?file, because alternate command interfaces like g++ might
> + ? ? ? ? ? ? ? ? ?find it useful to place -xnone after each input file. ?*/
> + ? ? ? ? ? ? ? spec_lang = 0;
> + ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? last_language_n_infiles = n_infiles;
> ? ? ? ? ? ? ?break;
>
> ? ? ? ? ? ?case 'S':
> ? ? ? ? ? ?case 'c':
> ? ? ? ? ? ?case 'E':
> ? ? ? ? ? ? ?if (p[1] == 0)
> - ? ? ? ? ? ? ? {
> - ? ? ? ? ? ? ? ? have_c = 1;
> - ? ? ? ? ? ? ? ? n_switches++;
> - ? ? ? ? ? ? ? ? break;
> - ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? have_c = 1;
> ? ? ? ? ? ? ?goto normal_switch;
>
> ? ? ? ? ? ?case 'o':
> @@ -4094,7 +4168,10 @@ process_command (int argc, const char **
> ? ? ? ? ? ? ?if (p[1] == 0)
> ? ? ? ? ? ? ? ?argv[i + 1] = convert_filename (argv[i + 1], ! have_c, 0);
> ? ? ? ? ? ? ?else
> - ? ? ? ? ? ? ? argv[i] = convert_filename (argv[i], ! have_c, 0);
> + ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? argv[i] = convert_filename (argv[i], ! have_c, 0);
> + ? ? ? ? ? ? ? ? p = &argv[i][1];
> + ? ? ? ? ? ? ? }
> ?#endif
> ? ? ? ? ? ? ?/* Save the output name in case -save-temps=obj was used. ?*/
> ? ? ? ? ? ? ?if ((p[1] == 0) && argv[i + 1])
> @@ -4106,18 +4183,105 @@ process_command (int argc, const char **
> ? ? ? ? ? ?default:
> ? ? ? ? ? ?normal_switch:
>
> - ? ? ? ? ? ? n_switches++;
> + ? ? ? ? ? ? alloc_switch ();
> + ? ? ? ? ? ? switches[n_switches].part1 = p;
> + ? ? ? ? ? ? /* Deal with option arguments in separate argv elements. ?*/
> + ? ? ? ? ? ? if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
> + ? ? ? ? ? ? ? ? || WORD_SWITCH_TAKES_ARG (p))
> + ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? int j = 0;
> + ? ? ? ? ? ? ? ? int n_args = WORD_SWITCH_TAKES_ARG (p);
>
> - ? ? ? ? ? ? if (SWITCH_TAKES_ARG (c) > (p[1] != 0))
> - ? ? ? ? ? ? ? i += SWITCH_TAKES_ARG (c) - (p[1] != 0);
> - ? ? ? ? ? ? else if (WORD_SWITCH_TAKES_ARG (p))
> - ? ? ? ? ? ? ? i += WORD_SWITCH_TAKES_ARG (p);
> + ? ? ? ? ? ? ? ? if (n_args == 0)
> + ? ? ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? ? ? /* Count only the option arguments in separate
> + ? ? ? ? ? ? ? ? ? ? ? ?argv elements. ?*/
> + ? ? ? ? ? ? ? ? ? ? n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
> + ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? ? if (i + n_args >= argc)
> + ? ? ? ? ? ? ? ? ? fatal_error ("argument to %<-%s%> is missing", p);
> + ? ? ? ? ? ? ? ? switches[n_switches].args
> + ? ? ? ? ? ? ? ? ? = XNEWVEC (const char *, n_args + 1);
> + ? ? ? ? ? ? ? ? while (j < n_args)
> + ? ? ? ? ? ? ? ? ? switches[n_switches].args[j++] = argv[++i];
> + ? ? ? ? ? ? ? ? /* Null-terminate the vector. ?*/
> + ? ? ? ? ? ? ? ? switches[n_switches].args[j] = 0;
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? else if (strchr (switches_need_spaces, c))
> + ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? /* On some systems, ld cannot handle some options without
> + ? ? ? ? ? ? ? ? ? ?a space. ?So split the option from its argument. ?*/
> + ? ? ? ? ? ? ? ? char *part1 = XNEWVEC (char, 2);
> + ? ? ? ? ? ? ? ? part1[0] = c;
> + ? ? ? ? ? ? ? ? part1[1] = '\0';
> +
> + ? ? ? ? ? ? ? ? switches[n_switches].part1 = part1;
> + ? ? ? ? ? ? ? ? switches[n_switches].args = XNEWVEC (const char *, 2);
> + ? ? ? ? ? ? ? ? switches[n_switches].args[0] = xstrdup (p+1);
> + ? ? ? ? ? ? ? ? switches[n_switches].args[1] = 0;
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? switches[n_switches].args = 0;
> +
> + ? ? ? ? ? ? switches[n_switches].live_cond = 0;
> + ? ? ? ? ? ? switches[n_switches].validated = 0;
> + ? ? ? ? ? ? switches[n_switches].ordering = 0;
> + ? ? ? ? ? ? /* These are always valid, since gcc.c itself understands the
> + ? ? ? ? ? ? ? ?first four, gfortranspec.c understands -static-libgfortran
> + ? ? ? ? ? ? ? ?and g++spec.c understands -static-libstdc++ */
> + ? ? ? ? ? ? if (!strcmp (p, "save-temps")
> + ? ? ? ? ? ? ? ? || !strcmp (p, "static-libgcc")
> + ? ? ? ? ? ? ? ? || !strcmp (p, "shared-libgcc")
> + ? ? ? ? ? ? ? ? || !strcmp (p, "pipe")
> + ? ? ? ? ? ? ? ? || !strcmp (p, "static-libgfortran")
> + ? ? ? ? ? ? ? ? || !strcmp (p, "static-libstdc++"))
> + ? ? ? ? ? ? ? switches[n_switches].validated = 1;
> + ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? char ch = switches[n_switches].part1[0];
> + ? ? ? ? ? ? ? ? if (ch == 'B')
> + ? ? ? ? ? ? ? ? ? switches[n_switches].validated = 1;
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? n_switches++;
> ? ? ? ? ? ?}
> ? ? ? ?}
> ? ? ? else
> ? ? ? ?{
> - ? ? ? ? n_infiles++;
> - ? ? ? ? lang_n_infiles++;
> + ? ? ? ? ?const char *p = strrchr (argv[i], '@');
> + ? ? ? ? ?char *fname;
> + ? ? ? ? long offset;
> + ? ? ? ? int consumed;
> +#ifdef HAVE_TARGET_OBJECT_SUFFIX
> + ? ? ? ? argv[i] = convert_filename (argv[i], 0, access (argv[i], F_OK));
> +#endif
> + ? ? ? ? /* For LTO static archive support we handle input file
> + ? ? ? ? ? ?specifications that are composed of a filename and
> + ? ? ? ? ? ?an offset like FNAME@OFFSET. ?*/
> + ? ? ? ? if (p
> + ? ? ? ? ? ? && p != argv[i]
> + ? ? ? ? ? ? && sscanf (p, "@%li%n", &offset, &consumed) >= 1
> + ? ? ? ? ? ? && strlen (p) == (unsigned int)consumed)
> + ? ? ? ? ? {
> + ? ? ? ? ? ? ?fname = (char *)xmalloc (p - argv[i] + 1);
> + ? ? ? ? ? ? ?memcpy (fname, argv[i], p - argv[i]);
> + ? ? ? ? ? ? ?fname[p - argv[i]] = '\0';
> + ? ? ? ? ? ? /* Only accept non-stdin and existing FNAME parts, otherwise
> + ? ? ? ? ? ? ? ?try with the full name. ?*/
> + ? ? ? ? ? ? if (strcmp (fname, "-") == 0 || access (fname, F_OK) < 0)
> + ? ? ? ? ? ? ? {
> + ? ? ? ? ? ? ? ? free (fname);
> + ? ? ? ? ? ? ? ? fname = xstrdup (argv[i]);
> + ? ? ? ? ? ? ? }
> + ? ? ? ? ? }
> + ? ? ? ? else
> + ? ? ? ? ? fname = xstrdup (argv[i]);
> +
> + ? ? ? ? ?if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
> + ? ? ? ? ? perror_with_name (fname);
> + ? ? ? ? ?else
> + ? ? ? ? ? add_infile (argv[i], spec_lang);
> +
> + ? ? ? ? ?free (fname);
> ? ? ? ?}
> ? ? }
>
> @@ -4156,13 +4320,11 @@ process_command (int argc, const char **
> ? ? ? ?{
> ? ? ? ? ?compare_debug = 2;
> ? ? ? ? ?compare_debug_opt = gcd;
> - ? ? ? ? n_switches++;
> ? ? ? ?}
> ? ? ? else if (gcd && *gcd && strcmp (gcd, "0"))
> ? ? ? ?{
> ? ? ? ? ?compare_debug = 3;
> ? ? ? ? ?compare_debug_opt = "-gtoggle";
> - ? ? ? ? n_switches++;
> ? ? ? ?}
> ? ? }
> ? else if (compare_debug < 0)
> @@ -4215,7 +4377,7 @@ process_command (int argc, const char **
> ? ? ?then consider it to relocate with the rest of the GCC installation
> ? ? ?if GCC_EXEC_PREFIX is set.
> ? ? ?``make_relative_prefix'' is not compiled for VMS, so don't call it. ?*/
> - ?if (target_system_root && gcc_exec_prefix)
> + ?if (target_system_root && !target_system_root_changed && gcc_exec_prefix)
> ? ? {
> ? ? ? char *tmp_prefix = get_relative_prefix (argv[0],
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?standard_bindir_prefix,
> @@ -4231,232 +4393,12 @@ process_command (int argc, const char **
> ? /* More prefixes are enabled in main, after we read the specs file
> ? ? ?and determine whether this is cross-compilation or not. ?*/
>
> - ?/* Then create the space for the vectors and scan again. ?*/
> -
> - ?switches = XNEWVEC (struct switchstr, n_switches + 1);
> - ?infiles = XNEWVEC (struct infile, n_infiles + 1);
> - ?n_switches = 0;
> - ?n_infiles = 0;
> - ?last_language_n_infiles = -1;
> -
> - ?/* This, time, copy the text of each switch and store a pointer
> - ? ? to the copy in the vector of switches.
> - ? ? Store all the infiles in their vector. ?*/
> -
> - ?for (i = 1; i < argc; i++)
> - ? ?{
> - ? ? ?/* Just skip the switches that were handled by the preceding loop. ?*/
> - ? ? ?if (! strncmp (argv[i], "-Wa,", 4))
> - ? ? ? ;
> - ? ? ?else if (! strncmp (argv[i], "-Wp,", 4))
> - ? ? ? ;
> - ? ? ?else if (! strcmp (argv[i], "-no-canonical-prefixes"))
> - ? ? ? ;
> - ? ? ?else if (! strcmp (argv[i], "-pass-exit-codes"))
> - ? ? ? ;
> - ? ? ?else if (! strcmp (argv[i], "-print-search-dirs"))
> - ? ? ? ;
> - ? ? ?else if (! strcmp (argv[i], "-print-libgcc-file-name"))
> - ? ? ? ;
> - ? ? ?else if (! strncmp (argv[i], "-print-file-name=", 17))
> - ? ? ? ;
> - ? ? ?else if (! strncmp (argv[i], "-print-prog-name=", 17))
> - ? ? ? ;
> - ? ? ?else if (! strcmp (argv[i], "-print-multi-lib"))
> - ? ? ? ;
> - ? ? ?else if (! strcmp (argv[i], "-print-multi-directory"))
> - ? ? ? ;
> - ? ? ?else if (! strcmp (argv[i], "-print-sysroot"))
> - ? ? ? ;
> - ? ? ?else if (! strcmp (argv[i], "-print-multi-os-directory"))
> - ? ? ? ;
> - ? ? ?else if (! strcmp (argv[i], "-print-sysroot-headers-suffix"))
> - ? ? ? ;
> - ? ? ?else if (! strncmp (argv[i], "--sysroot=", strlen ("--sysroot=")))
> - ? ? ? {
> - ? ? ? ? target_system_root = argv[i] + strlen ("--sysroot=");
> - ? ? ? ? target_system_root_changed = 1;
> - ? ? ? }
> - ? ? ?else if (strncmp (argv[i], "-Wl,", 4) == 0)
> - ? ? ? {
> - ? ? ? ? int prev, j;
> - ? ? ? ? /* Split the argument at commas. ?*/
> - ? ? ? ? prev = 4;
> - ? ? ? ? for (j = 4; argv[i][j]; j++)
> - ? ? ? ? ? if (argv[i][j] == ',')
> - ? ? ? ? ? ? {
> - ? ? ? ? ? ? ? infiles[n_infiles].language = "*";
> - ? ? ? ? ? ? ? infiles[n_infiles++].name
> - ? ? ? ? ? ? ? ? = save_string (argv[i] + prev, j - prev);
> - ? ? ? ? ? ? ? prev = j + 1;
> - ? ? ? ? ? ? }
> - ? ? ? ? /* Record the part after the last comma. ?*/
> - ? ? ? ? infiles[n_infiles].language = "*";
> - ? ? ? ? infiles[n_infiles++].name = argv[i] + prev;
> - ? ? ? }
> - ? ? ?else if (strcmp (argv[i], "-Xlinker") == 0)
> - ? ? ? {
> - ? ? ? ? infiles[n_infiles].language = "*";
> - ? ? ? ? infiles[n_infiles++].name = argv[++i];
> - ? ? ? }
> - ? ? ?/* Xassembler and Xpreprocessor were already handled in the first argv
> - ? ? ? ?scan, so all we need to do here is ignore them and their argument. ?*/
> - ? ? ?else if (strcmp (argv[i], "-Xassembler") == 0)
> - ? ? ? i++;
> - ? ? ?else if (strcmp (argv[i], "-Xpreprocessor") == 0)
> - ? ? ? i++;
> - ? ? ?else if (strcmp (argv[i], "-l") == 0)
> - ? ? ? { /* POSIX allows separation of -l and the lib arg;
> - ? ? ? ? ? ?canonicalize by concatenating -l with its arg */
> - ? ? ? ? infiles[n_infiles].language = "*";
> - ? ? ? ? infiles[n_infiles++].name = concat ("-l", argv[++i], NULL);
> - ? ? ? }
> - ? ? ?else if (strncmp (argv[i], "-l", 2) == 0)
> - ? ? ? {
> - ? ? ? ? infiles[n_infiles].language = "*";
> - ? ? ? ? infiles[n_infiles++].name = argv[i];
> - ? ? ? }
> - ? ? ?else if (strcmp (argv[i], "-wrapper") == 0)
> - ? ? ? ?i++;
> - ? ? ?else if (strcmp (argv[i], "-specs") == 0)
> - ? ? ? i++;
> - ? ? ?else if (strncmp (argv[i], "-specs=", 7) == 0)
> - ? ? ? ;
> - ? ? ?else if (strcmp (argv[i], "-time") == 0)
> - ? ? ? ;
> - ? ? ?else if (strncmp (argv[i], "-time=", sizeof ("-time=") - 1) == 0)
> - ? ? ? ;
> - ? ? ?else if (strcmp (argv[i], "-###") == 0)
> - ? ? ? ;
> - ? ? ?else if (argv[i][0] == '-' && argv[i][1] != 0)
> - ? ? ? {
> - ? ? ? ? const char *p = &argv[i][1];
> - ? ? ? ? int c = *p;
> -
> - ? ? ? ? if (c == 'x')
> - ? ? ? ? ? {
> - ? ? ? ? ? ? if (p[1] == 0 && i + 1 == argc)
> - ? ? ? ? ? ? ? fatal_error ("argument to %<-x%> is missing");
> - ? ? ? ? ? ? if (p[1] == 0)
> - ? ? ? ? ? ? ? spec_lang = argv[++i];
> - ? ? ? ? ? ? else
> - ? ? ? ? ? ? ? spec_lang = p + 1;
> - ? ? ? ? ? ? if (! strcmp (spec_lang, "none"))
> - ? ? ? ? ? ? ? /* Suppress the warning if -xnone comes after the last input
> - ? ? ? ? ? ? ? ? ?file, because alternate command interfaces like g++ might
> - ? ? ? ? ? ? ? ? ?find it useful to place -xnone after each input file. ?*/
> - ? ? ? ? ? ? ? spec_lang = 0;
> - ? ? ? ? ? ? else
> - ? ? ? ? ? ? ? last_language_n_infiles = n_infiles;
> - ? ? ? ? ? ? continue;
> - ? ? ? ? ? }
> - ? ? ? ? switches[n_switches].part1 = p;
> - ? ? ? ? /* Deal with option arguments in separate argv elements. ?*/
> - ? ? ? ? if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
> - ? ? ? ? ? ? || WORD_SWITCH_TAKES_ARG (p))
> - ? ? ? ? ? {
> - ? ? ? ? ? ? int j = 0;
> - ? ? ? ? ? ? int n_args = WORD_SWITCH_TAKES_ARG (p);
> -
> - ? ? ? ? ? ? if (n_args == 0)
> - ? ? ? ? ? ? ? {
> - ? ? ? ? ? ? ? ? /* Count only the option arguments in separate argv elements. ?*/
> - ? ? ? ? ? ? ? ? n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
> - ? ? ? ? ? ? ? }
> - ? ? ? ? ? ? if (i + n_args >= argc)
> - ? ? ? ? ? ? ? fatal_error ("argument to %<-%s%> is missing", p);
> - ? ? ? ? ? ? switches[n_switches].args
> - ? ? ? ? ? ? ? = XNEWVEC (const char *, n_args + 1);
> - ? ? ? ? ? ? while (j < n_args)
> - ? ? ? ? ? ? ? switches[n_switches].args[j++] = argv[++i];
> - ? ? ? ? ? ? /* Null-terminate the vector. ?*/
> - ? ? ? ? ? ? switches[n_switches].args[j] = 0;
> - ? ? ? ? ? }
> - ? ? ? ? else if (strchr (switches_need_spaces, c))
> - ? ? ? ? ? {
> - ? ? ? ? ? ? /* On some systems, ld cannot handle some options without
> - ? ? ? ? ? ? ? ?a space. ?So split the option from its argument. ?*/
> - ? ? ? ? ? ? char *part1 = XNEWVEC (char, 2);
> - ? ? ? ? ? ? part1[0] = c;
> - ? ? ? ? ? ? part1[1] = '\0';
> -
> - ? ? ? ? ? ? switches[n_switches].part1 = part1;
> - ? ? ? ? ? ? switches[n_switches].args = XNEWVEC (const char *, 2);
> - ? ? ? ? ? ? switches[n_switches].args[0] = xstrdup (p+1);
> - ? ? ? ? ? ? switches[n_switches].args[1] = 0;
> - ? ? ? ? ? }
> - ? ? ? ? else
> - ? ? ? ? ? switches[n_switches].args = 0;
> -
> - ? ? ? ? switches[n_switches].live_cond = 0;
> - ? ? ? ? switches[n_switches].validated = 0;
> - ? ? ? ? switches[n_switches].ordering = 0;
> - ? ? ? ? /* These are always valid, since gcc.c itself understands the
> - ? ? ? ? ? ?first four, gfortranspec.c understands -static-libgfortran
> - ? ? ? ? ? ?and g++spec.c understands -static-libstdc++ */
> - ? ? ? ? if (!strcmp (p, "save-temps")
> - ? ? ? ? ? ? || !strcmp (p, "static-libgcc")
> - ? ? ? ? ? ? || !strcmp (p, "shared-libgcc")
> - ? ? ? ? ? ? || !strcmp (p, "pipe")
> - ? ? ? ? ? ? || !strcmp (p, "static-libgfortran")
> - ? ? ? ? ? ? || !strcmp (p, "static-libstdc++"))
> - ? ? ? ? ? switches[n_switches].validated = 1;
> - ? ? ? ? else
> - ? ? ? ? ? {
> - ? ? ? ? ? ? char ch = switches[n_switches].part1[0];
> - ? ? ? ? ? ? if (ch == 'B')
> - ? ? ? ? ? ? ? switches[n_switches].validated = 1;
> - ? ? ? ? ? }
> - ? ? ? ? n_switches++;
> - ? ? ? }
> - ? ? ?else
> - ? ? ? {
> - ? ? ? ? ?const char *p = strrchr (argv[i], '@');
> - ? ? ? ? ?char *fname;
> - ? ? ? ? long offset;
> - ? ? ? ? int consumed;
> -#ifdef HAVE_TARGET_OBJECT_SUFFIX
> - ? ? ? ? argv[i] = convert_filename (argv[i], 0, access (argv[i], F_OK));
> -#endif
> - ? ? ? ? /* For LTO static archive support we handle input file
> - ? ? ? ? ? ?specifications that are composed of a filename and
> - ? ? ? ? ? ?an offset like FNAME@OFFSET. ?*/
> - ? ? ? ? if (p
> - ? ? ? ? ? ? && p != argv[i]
> - ? ? ? ? ? ? && sscanf (p, "@%li%n", &offset, &consumed) >= 1
> - ? ? ? ? ? ? && strlen (p) == (unsigned int)consumed)
> - ? ? ? ? ? {
> - ? ? ? ? ? ? ?fname = (char *)xmalloc (p - argv[i] + 1);
> - ? ? ? ? ? ? ?memcpy (fname, argv[i], p - argv[i]);
> - ? ? ? ? ? ? ?fname[p - argv[i]] = '\0';
> - ? ? ? ? ? ? /* Only accept non-stdin and existing FNAME parts, otherwise
> - ? ? ? ? ? ? ? ?try with the full name. ?*/
> - ? ? ? ? ? ? if (strcmp (fname, "-") == 0 || access (fname, F_OK) < 0)
> - ? ? ? ? ? ? ? {
> - ? ? ? ? ? ? ? ? free (fname);
> - ? ? ? ? ? ? ? ? fname = xstrdup (argv[i]);
> - ? ? ? ? ? ? ? }
> - ? ? ? ? ? }
> - ? ? ? ? else
> - ? ? ? ? ? fname = xstrdup (argv[i]);
> -
> - ? ? ? ? ?if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
> - ? ? ? ? ? perror_with_name (fname);
> - ? ? ? ? ?else
> - ? ? ? ? ? ?{
> - ? ? ? ? ? ? ?infiles[n_infiles].language = spec_lang;
> - ? ? ? ? ? ? ?infiles[n_infiles++].name = argv[i];
> - ? ? ? ? ? ?}
> -
> - ? ? ? ? ?free (fname);
> - ? ? ? }
> - ? ?}
> -
> ? if (n_infiles == last_language_n_infiles && spec_lang != 0)
> ? ? warning (0, "%<-x %s%> after last input file has no effect", spec_lang);
>
> ? if (compare_debug == 2 || compare_debug == 3)
> ? ? {
> + ? ? ?alloc_switch ();
> ? ? ? switches[n_switches].part1 = concat ("fcompare-debug=",
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? compare_debug_opt,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? NULL);
> @@ -4471,15 +4413,16 @@ process_command (int argc, const char **
> ? /* Ensure we only invoke each subprocess once. ?*/
> ? if (print_subprocess_help || print_help_list || print_version)
> ? ? {
> - ? ? ?n_infiles = 1;
> + ? ? ?n_infiles = 0;
>
> ? ? ? /* Create a dummy input file, so that we can pass
> ? ? ? ? the help option on to the various sub-processes. ?*/
> - ? ? ?infiles[0].language = "c";
> - ? ? ?infiles[0].name ? = "help-dummy";
> + ? ? ?add_infile ("help-dummy", "c");
> ? ? }
>
> + ?alloc_switch ();
> ? switches[n_switches].part1 = 0;
> + ?alloc_infile ();
> ? infiles[n_infiles].name = 0;
> ?}
>
> diff -rupN --exclude=.svn gcc-mainline-opt4-takes-arg/gcc/testsuite/gcc.dg/opts-3.c gcc-mainline/gcc/testsuite/gcc.dg/opts-3.c
> --- gcc-mainline-opt4-takes-arg/gcc/testsuite/gcc.dg/opts-3.c ? 1969-12-31 16:00:00.000000000 -0800
> +++ gcc-mainline/gcc/testsuite/gcc.dg/opts-3.c ?2010-06-25 17:37:27.000000000 -0700
> @@ -0,0 +1,7 @@
> +/* Parameters of -Xassembler should not be interpreted as driver
> + ? options (and so cause the driver to exit prematurely, as in this
> + ? testcase, or have other unintended effects). ?*/
> +/* { dg-do compile } */
> +/* { dg-options "-Xassembler -dumpmachine" } */
> +
> +int int x; /* { dg-error "two or more data types" } */
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
>


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]