diff options
author | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-01 22:22:57 +0000 |
---|---|---|
committer | hjl <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-07-01 22:22:57 +0000 |
commit | 9e169c4bf36a38689550c059570c57efbf00a6fb (patch) | |
tree | 95e6800f7ac2a49ff7f799d96f04172320e70ac0 /gcc/gcc.c | |
parent | 6170dfb6edfb7b19f8ae5209b8f948fe0076a4ad (diff) | |
download | gcc-vect256.tar.gz |
Merged trunk at revision 161680 into branch.vect256
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/vect256@161681 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r-- | gcc/gcc.c | 722 |
1 files changed, 292 insertions, 430 deletions
diff --git a/gcc/gcc.c b/gcc/gcc.c index a199f02b46d..6a0dae5c5a0 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -280,23 +280,6 @@ static const char *cross_compile = "1"; static const char *cross_compile = "0"; #endif -#ifdef MODIFY_TARGET_NAME - -/* Information on how to alter the target name based on a command-line - switch. The only case we support now is simply appending or deleting a - string to or from the end of the first part of the configuration name. */ - -enum add_del {ADD, DELETE}; - -static const struct modify_target -{ - const char *const sw; - const enum add_del add_del; - const char *const str; -} -modify_target[] = MODIFY_TARGET_NAME; -#endif - /* Greatest exit code of sub-processes that has been encountered up to now. */ static int greatest_status = 1; @@ -399,6 +382,7 @@ static const char *replace_outfile_spec_function (int, const char **); static const char *version_compare_spec_function (int, const char **); static const char *include_spec_function (int, const char **); static const char *find_file_spec_function (int, const char **); +static const char *find_plugindir_spec_function (int, const char **); static const char *print_asm_header_spec_function (int, const char **); static const char *compare_debug_dump_opt_spec_function (int, const char **); static const char *compare_debug_self_opt_spec_function (int, const char **); @@ -680,18 +664,6 @@ proper position among the other output files. */ "%{!shared:%{pg:gcrt0%O%s}%{!pg:%{p:mcrt0%O%s}%{!p:crt0%O%s}}}" #endif -/* config.h can define SWITCHES_NEED_SPACES to control which options - require spaces between the option and the argument. - - We define SWITCHES_NEED_SPACES to include "o" by default. This - causes "-ofoo.o" to be split into "-o foo.o" during the initial - processing of the command-line, before being seen by the specs - machinery. This makes sure we record "foo.o" as the temporary file - to be deleted in the case of error, rather than "-ofoo.o". */ -#ifndef SWITCHES_NEED_SPACES -#define SWITCHES_NEED_SPACES "o" -#endif - /* config.h can define ENDFILE_SPEC to override the default crtn files. */ #ifndef ENDFILE_SPEC #define ENDFILE_SPEC "" @@ -827,7 +799,6 @@ static const char *link_gomp_spec = ""; static const char *libgcc_spec = LIBGCC_SPEC; static const char *endfile_spec = ENDFILE_SPEC; static const char *startfile_spec = STARTFILE_SPEC; -static const char *switches_need_spaces = SWITCHES_NEED_SPACES; static const char *linker_name_spec = LINKER_NAME; static const char *linker_plugin_file_spec = ""; static const char *lto_wrapper_spec = ""; @@ -862,7 +833,7 @@ static const char *cpp_unique_options = %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\ %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}}\ %{remap} %{g3|ggdb3|gstabs3|gcoff3|gxcoff3|gvms3:-dD}\ - %{!iplugindir*:%{fplugin*:-iplugindir=%:find-file(plugin)}}\ + %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\ %{H} %C %{D*&U*&A*} %{i*} %Z %i\ %{fmudflap:-D_MUDFLAP -include mf-runtime.h}\ %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h}\ @@ -885,7 +856,7 @@ static const char *cpp_debug_options = "%{d*}"; /* NB: This is shared amongst all front-ends, except for Ada. */ static const char *cc1_options = "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{!iplugindir*:%{fplugin*:-iplugindir=%:find-file(plugin)}}\ + %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\ %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{a*}\ %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)} \ %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}} \ @@ -1392,7 +1363,7 @@ translate_options (int *argcp, const char *const **argvp) else if (strchr (arginfo, '*') != 0) { - error ("incomplete '%s' option", option_map[j].name); + error ("incomplete %qs option", option_map[j].name); break; } @@ -1403,7 +1374,7 @@ translate_options (int *argcp, const char *const **argvp) { if (i + 1 == argc) { - error ("missing argument to '%s' option", + error ("missing argument to %qs option", option_map[j].name); break; } @@ -1416,7 +1387,7 @@ translate_options (int *argcp, const char *const **argvp) else if (strchr (arginfo, 'o') == 0) { if (arg != 0) - error ("extraneous argument to '%s' option", + error ("extraneous argument to %qs option", option_map[j].name); arg = 0; } @@ -1474,7 +1445,7 @@ translate_options (int *argcp, const char *const **argvp) } } else - /* Ordinary operands, or +e options. */ + /* Ordinary operands. */ newv[newindex++] = argv[i++]; } @@ -1667,7 +1638,6 @@ static struct spec_list static_specs[] = INIT_STATIC_SPEC ("link_gomp", &link_gomp_spec), INIT_STATIC_SPEC ("libgcc", &libgcc_spec), INIT_STATIC_SPEC ("startfile", &startfile_spec), - INIT_STATIC_SPEC ("switches_need_spaces", &switches_need_spaces), INIT_STATIC_SPEC ("cross_compile", &cross_compile), INIT_STATIC_SPEC ("version", &compiler_version), INIT_STATIC_SPEC ("multilib", &multilib_select), @@ -1719,6 +1689,7 @@ static const struct spec_function static_spec_functions[] = { "version-compare", version_compare_spec_function }, { "include", include_spec_function }, { "find-file", find_file_spec_function }, + { "find-plugindir", find_plugindir_spec_function }, { "print-asm-header", print_asm_header_spec_function }, { "compare-debug-dump-opt", compare_debug_dump_opt_spec_function }, { "compare-debug-self-opt", compare_debug_self_opt_spec_function }, @@ -2281,8 +2252,8 @@ read_specs (const char *filename, int main_p) for (newsl = specs; newsl; newsl = newsl->next) if (strcmp (newsl->name, p2) == 0) - fatal_error ("%s: attempt to rename spec '%s' to " - "already defined spec '%s'", + fatal_error ("%s: attempt to rename spec %qs to " + "already defined spec %qs", filename, p1, p2); if (verbose_flag) @@ -2907,7 +2878,7 @@ add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix, int require_machine_suffix, int os_multilib) { if (!IS_ABSOLUTE_PATH (prefix)) - fatal_error ("system path '%s' is not absolute", prefix); + fatal_error ("system path %qs is not absolute", prefix); if (target_system_root) { @@ -3095,7 +3066,7 @@ execute (void) ? PEX_RECORD_TIMES : 0), progname, temp_filename); if (pex == NULL) - pfatal_with_name (_("pex_init failed")); + fatal_error ("pex_init failed: %m"); for (i = 0; i < n_commands; i++) { @@ -3134,13 +3105,13 @@ execute (void) statuses = (int *) alloca (n_commands * sizeof (int)); if (!pex_get_status (pex, n_commands, statuses)) - pfatal_with_name (_("failed to get exit status")); + fatal_error ("failed to get exit status: %m"); if (report_times || report_times_to_file) { times = (struct pex_time *) alloca (n_commands * sizeof (struct pex_time)); if (!pex_get_times (pex, n_commands, times)) - pfatal_with_name (_("failed to get process times")); + fatal_error ("failed to get process times: %m"); } pex_free (pex); @@ -3266,6 +3237,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 @@ -3311,6 +3284,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. */ @@ -3495,6 +3470,51 @@ add_linker_option (const char *option, int len) 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'. */ @@ -3506,11 +3526,6 @@ process_command (int argc, const char **argv) char *temp1; const char *spec_lang = 0; int last_language_n_infiles; - int lang_n_infiles = 0; -#ifdef MODIFY_TARGET_NAME - int is_modify_target_name; - unsigned int j; -#endif const char *tooldir_prefix; char *(*get_relative_prefix) (const char *, const char *, const char *) = NULL; @@ -3724,12 +3739,22 @@ process_command (int argc, const char **argv) } } - /* 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; @@ -3755,59 +3780,50 @@ process_command (int argc, const char **argv) /* 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; @@ -3830,16 +3846,18 @@ process_command (int argc, const char **argv) 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=" @@ -3857,7 +3875,7 @@ process_command (int argc, const char **argv) compare_debug_opt = NULL; else compare_debug_opt = opt; - n_switches++; + goto normal_switch; } else if (! strncmp (argv[i], "-Wa,", 4)) { @@ -3893,63 +3911,73 @@ process_command (int argc, const char **argv) /* Record the part after the last comma. */ add_preprocessor_option (argv[i] + prev, j - prev); } - else if (argv[i][0] == '+' && argv[i][1] == 'e') - /* The +e options to the C++ front-end. */ - n_switches++; 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"); + fatal_error ("argument to %<-Xlinker%> is missing"); - n_infiles++; + add_infile (argv[i+1], "*"); i++; } else if (strcmp (argv[i], "-Xpreprocessor") == 0) { if (i + 1 == argc) - fatal_error ("argument to '-Xpreprocessor' is missing"); + 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) { if (i + 1 == argc) - fatal_error ("argument to '-Xassembler' is missing"); + 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"); + 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 || strcmp (argv[i]+12, "object") == 0) save_temps_flag = SAVE_TEMPS_OBJ; else - fatal_error ("'%s' is an unknown -save-temps option", argv[i]); + 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. */ @@ -3957,13 +3985,13 @@ process_command (int argc, const char **argv) else if (strcmp (argv[i], "-combine") == 0) { combine_flag = 1; - n_switches++; + goto normal_switch; } else if (strcmp (argv[i], "-specs") == 0) { struct user_specs *user = XNEW (struct user_specs); if (++i >= argc) - fatal_error ("argument to '-specs' is missing"); + fatal_error ("argument to %<-specs%> is missing"); user->next = (struct user_specs *) 0; user->filename = argv[i]; @@ -3977,7 +4005,7 @@ process_command (int argc, const char **argv) { struct user_specs *user = XNEW (struct user_specs); if (strlen (argv[i]) == 7) - fatal_error ("argument to '-specs=' is missing"); + fatal_error ("argument to %<-specs=%> is missing"); user->next = (struct user_specs *) 0; user->filename = argv[i] + 7; @@ -3987,6 +4015,11 @@ process_command (int argc, const char **argv) 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) @@ -4000,16 +4033,14 @@ process_command (int argc, const char **argv) /* -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) { if (++i >= argc) - fatal_error ("argument to '-wrapper' is missing"); + fatal_error ("argument to %<-wrapper%> is missing"); wrapper_string = argv[i]; - n_switches++; - n_switches++; } else if (strcmp (argv[i], "-###") == 0) { @@ -4022,9 +4053,6 @@ process_command (int argc, const char **argv) } else if (argv[i][0] == '-' && argv[i][1] != 0) { - const char *p = &argv[i][1]; - int c = *p; - switch (c) { case 'B': @@ -4033,9 +4061,9 @@ process_command (int argc, const char **argv) int len; if (p[1] == 0 && i + 1 == argc) - fatal_error ("argument to '-B' is missing"); + fatal_error ("argument to %<-B%> is missing"); if (p[1] == 0) - value = argv[++i]; + value = argv[i + 1]; else value = p + 1; @@ -4064,28 +4092,38 @@ process_command (int argc, const char **argv) 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': @@ -4123,7 +4161,10 @@ process_command (int argc, const char **argv) 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]) @@ -4135,55 +4176,105 @@ process_command (int argc, const char **argv) default: normal_switch: -#ifdef MODIFY_TARGET_NAME - is_modify_target_name = 0; - - for (j = 0; j < ARRAY_SIZE (modify_target); j++) - if (! strcmp (argv[i], modify_target[j].sw)) - { - char *new_name = XNEWVEC (char, strlen (modify_target[j].str) - + strlen (spec_machine)); - const char *p, *r; - char *q; - int made_addition = 0; - - is_modify_target_name = 1; - for (p = spec_machine, q = new_name; *p != 0; ) - { - if (modify_target[j].add_del == DELETE - && (! strncmp (q, modify_target[j].str, - strlen (modify_target[j].str)))) - p += strlen (modify_target[j].str); - else if (modify_target[j].add_del == ADD - && ! made_addition && *p == '-') - { - for (r = modify_target[j].str; *r != 0; ) - *q++ = *r++; - made_addition = 1; - } - - *q++ = *p++; - } - - spec_machine = new_name; - } - - if (is_modify_target_name) - break; -#endif + 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 (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 (c == 'o') + { + /* On some systems, ld cannot handle "-o" 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++; - - 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); } } 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); } } @@ -4222,13 +4313,11 @@ process_command (int argc, const char **argv) { 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) @@ -4281,7 +4370,7 @@ process_command (int argc, const char **argv) 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, @@ -4297,256 +4386,12 @@ process_command (int argc, const char **argv) /* 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. */ -#ifdef MODIFY_TARGET_NAME - is_modify_target_name = 0; - - for (j = 0; j < ARRAY_SIZE (modify_target); j++) - if (! strcmp (argv[i], modify_target[j].sw)) - is_modify_target_name = 1; - - if (is_modify_target_name) - ; - else -#endif - 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 (argv[i][0] == '+' && argv[i][1] == 'e') - { - /* Compensate for the +e options to the C++ front-end; - they're there simply for cfront call-compatibility. We do - some magic in default_compilers to pass them down properly. - Note we deliberately start at the `+' here, to avoid passing - -e0 or -e1 down into the linker. */ - switches[n_switches].part1 = &argv[i][0]; - switches[n_switches].args = 0; - switches[n_switches].live_cond = 0; - switches[n_switches].validated = 0; - n_switches++; - } - 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); + 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); @@ -4561,15 +4406,16 @@ process_command (int argc, const char **argv) /* 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; } @@ -4706,7 +4552,7 @@ end_going_arg (void) if (full_script_path == NULL) { - error ("unable to locate default linker script '%s' in the library search paths", string); + error ("unable to locate default linker script %qs in the library search paths", string); /* Script was not found on search path. */ return; } @@ -4894,7 +4740,7 @@ do_self_spec (const char *spec) /* Each switch should start with '-'. */ if (c != '-') - fatal_error ("switch '%s' does not start with '-'", argbuf[i]); + fatal_error ("switch %qs does not start with %<-%>", argbuf[i]); p++; c = *p; @@ -4918,7 +4764,7 @@ do_self_spec (const char *spec) n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0); } if (i + n_args >= argbuf_index) - fatal_error ("argument to '-%s' is missing", p); + fatal_error ("argument to %<-%s%> is missing", p); sw->args = XNEWVEC (const char *, n_args + 1); while (j < n_args) @@ -4926,9 +4772,9 @@ do_self_spec (const char *spec) /* Null-terminate the vector. */ sw->args[j] = 0; } - else if (strchr (switches_need_spaces, c)) + else if (c == 'o') { - /* On some systems, ld cannot handle some options without + /* On some systems, ld cannot handle "-o" without a space. So split the option from its argument. */ char *part1 = XNEWVEC (char, 2); part1[0] = c; @@ -5124,7 +4970,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) switch (c = *p++) { case 0: - fatal_error ("spec '%s' invalid", spec); + fatal_error ("spec %qs invalid", spec); case 'b': if (save_temps_length) @@ -5273,7 +5119,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) p += 2; /* We don't support extra suffix characters after %O. */ if (*p == '.' || ISALNUM ((unsigned char) *p)) - fatal_error ("spec '%s' has invalid '%%0%c'", spec, *p); + fatal_error ("spec %qs has invalid %<%%0%c%>", spec, *p); if (suffix_length == 0) suffix = TARGET_OBJECT_SUFFIX; else @@ -5584,7 +5430,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) int cur_index = argbuf_index; /* Handle the {...} following the %W. */ if (*p != '{') - fatal_error ("spec '%s' has invalid '%%W%c", spec, *p); + fatal_error ("spec %qs has invalid %<%%W%c%>", spec, *p); p = handle_braces (p + 1); if (p == 0) return -1; @@ -5604,7 +5450,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) /* Skip past the option value and make a copy. */ if (*p != '{') - fatal_error ("spec '%s' has invalid '%%x%c'", spec, *p); + fatal_error ("spec %qs has invalid %<%%x%c%>", spec, *p); while (*p++ != '}') ; string = save_string (p1 + 1, p - p1 - 2); @@ -5799,7 +5645,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) /* Catch the case where a spec string contains something like '%{foo:%*}'. i.e. there is no * in the pattern on the left hand side of the :. */ - error ("spec failure: '%%*' has not been initialized by pattern match"); + error ("spec failure: %<%%*%> has not been initialized by pattern match"); break; /* Process a string found as the value of a spec given by name. @@ -5889,7 +5735,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) break; default: - error ("spec failure: unrecognized spec option '%c'", c); + error ("spec failure: unrecognized spec option %qc", c); break; } break; @@ -5951,7 +5797,7 @@ eval_spec_function (const char *func, const char *args) sf = lookup_spec_function (func); if (sf == NULL) - fatal_error ("unknown spec function '%s'", func); + fatal_error ("unknown spec function %qs", func); /* Push the spec processing context. */ save_argbuf_index = argbuf_index; @@ -5971,7 +5817,7 @@ eval_spec_function (const char *func, const char *args) alloc_args (); if (do_spec_2 (args) < 0) - fatal_error ("error in args to spec function '%s'", func); + fatal_error ("error in args to spec function %qs", func); /* argbuf_index is an index for the next argument to be inserted, and so contains the count of the args already inserted. */ @@ -6288,7 +6134,7 @@ handle_braces (const char *p) return p; invalid: - fatal_error ("braced spec '%s' is invalid at '%c'", orig, *p); + fatal_error ("braced spec %qs is invalid at %qc", orig, *p); #undef SKIP_WHITE } @@ -6376,7 +6222,7 @@ process_brace_body (const char *p, const char *atom, const char *end_atom, return p; invalid: - fatal_error ("braced spec body '%s' is invalid", body); + fatal_error ("braced spec body %qs is invalid", body); } /* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch @@ -7074,7 +6920,7 @@ main (int argc, char **argv) for (i = 0; (int) i < n_switches; i++) if (! switches[i].validated) - error ("unrecognized option '-%s'", switches[i].part1); + error ("unrecognized option %<-%s%>", switches[i].part1); /* Obey some of the options. */ @@ -7317,7 +7163,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" value = do_spec (input_file_compiler->spec); infiles[i].preprocessed = true; if (!have_o_argbuf_index) - fatal_error ("spec '%s' is invalid", + fatal_error ("spec %qs is invalid", input_file_compiler->spec); infiles[i].name = argbuf[have_o_argbuf_index]; infiles[i].incompiler @@ -7654,7 +7500,7 @@ pfatal_with_name (const char *name) static void perror_with_name (const char *name) { - error ("%s: %s", name, xstrerror (errno)); + error ("%s: %m", name); } static inline void @@ -7809,7 +7655,7 @@ used_arg (const char *p, int len) if (*q == '\0') { invalid_matches: - fatal_error ("multilib spec '%s' is invalid", + fatal_error ("multilib spec %qs is invalid", multilib_matches); } q++; @@ -8001,7 +7847,7 @@ set_multilib_dir (void) if (*p == '\0') { invalid_exclusions: - fatal_error ("multilib exclusions '%s' is invalid", + fatal_error ("multilib exclusions %qs is invalid", multilib_exclusions); } @@ -8059,7 +7905,7 @@ set_multilib_dir (void) if (*p == '\0') { invalid_select: - fatal_error ("multilib select '%s' is invalid", + fatal_error ("multilib select %qs is invalid", multilib_select); } ++p; @@ -8200,7 +8046,7 @@ print_multilib_info (void) if (*p == '\0') { invalid_select: - fatal_error ("multilib select '%s' is invalid", multilib_select); + fatal_error ("multilib select %qs is invalid", multilib_select); } ++p; @@ -8238,7 +8084,7 @@ print_multilib_info (void) if (*e == '\0') { invalid_exclusion: - fatal_error ("multilib exclusion '%s' is invalid", + fatal_error ("multilib exclusion %qs is invalid", multilib_exclusions); } @@ -8444,7 +8290,7 @@ getenv_spec_function (int argc, const char **argv) value = getenv (argv[0]); if (!value) - fatal_error ("environment variable \"%s\" not defined", argv[0]); + fatal_error ("environment variable %qs not defined", argv[0]); /* We have to escape every character of the environment variable so they are not interpreted as active spec characters. A @@ -8535,12 +8381,12 @@ compare_version_strings (const char *v1, const char *v2) abort (); rresult = regexec (&r, v1, 0, NULL, 0); if (rresult == REG_NOMATCH) - fatal_error ("invalid version number `%s'", v1); + fatal_error ("invalid version number %qs", v1); else if (rresult != 0) abort (); rresult = regexec (&r, v2, 0, NULL, 0); if (rresult == REG_NOMATCH) - fatal_error ("invalid version number `%s'", v2); + fatal_error ("invalid version number %qs", v2); else if (rresult != 0) abort (); @@ -8630,7 +8476,7 @@ version_compare_spec_function (int argc, const char **argv) break; default: - fatal_error ("unknown operator '%s' in %%:version-compare", argv[0]); + fatal_error ("unknown operator %qs in %%:version-compare", argv[0]); } if (! result) return NULL; @@ -8657,11 +8503,11 @@ include_spec_function (int argc, const char **argv) return NULL; } -/* %:find-file spec function. This function replace its argument by +/* %:find-file spec function. This function replaces its argument by the file found thru find_file, that is the -print-file-name gcc program option. */ static const char * -find_file_spec_function (int argc, const char**argv) +find_file_spec_function (int argc, const char **argv) { const char *file; @@ -8673,6 +8519,22 @@ find_file_spec_function (int argc, const char**argv) } +/* %:find-plugindir spec function. This function replaces its argument + by the -iplugindir=<dir> option. `dir' is found thru find_file, that + is the -print-file-name gcc program option. */ +static const char * +find_plugindir_spec_function (int argc, const char **argv ATTRIBUTE_UNUSED) +{ + const char *option; + + if (argc != 0) + abort (); + + option = concat ("-iplugindir=", find_file ("plugin"), NULL); + return option; +} + + /* %:print-asm-header spec function. Print a banner to say that the following output is from the assembler. */ |