diff options
author | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-19 18:19:39 +0000 |
---|---|---|
committer | bstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-09-19 18:19:39 +0000 |
commit | e56043cd2c207982e812ce6fcecb7353dea58363 (patch) | |
tree | 01a6f37ad5a9ae6b18bdc20f052b04e19b4255c0 /gcc/gcc.c | |
parent | 2e02a1a4548f2ee1ea519c88e68b20621ad16fcc (diff) | |
download | gcc-e56043cd2c207982e812ce6fcecb7353dea58363.tar.gz |
2010-09-19 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 164348, with some improvements
in gcc/melt-runtime.[ch]
2010-09-19 Basile Starynkevitch <basile@starynkevitch.net>
[[merged with trunk rev.164348, so improved MELT runtime!]]
* gcc/melt-runtime.h: improved comments.
(melt_debug_garbcoll, melt_debuggc_eprintf): Moved from melt-runtime.c.
(melt_obmag_string): New declaration.
(struct meltobject_st, struct meltclosure_st, struct
meltroutine_st, struct meltmixbigint_st, struct meltstring_st):
using GTY variable_size and @@MELTGTY@@ comment.
(melt_mark_special): added debug print.
* gcc/melt-runtime.c: Improved comments.
Include bversion.h, realmpfr.h, gimple-pretty-print.h.
(ggc_force_collect) Declared external.
(melt_forward_counter): Added.
(melt_obmag_string): New function.
(melt_alptr_1, melt_alptr_2, melt_break_alptr_1_at)
(melt_break_alptr_2_at, melt_break_alptr_1,melt_break_alptr_1)
(melt_allocate_young_gc_zone, melt_free_young_gc_zone): New.
(delete_special, meltgc_make_special): Improved debug printf and
use melt_break_alptr_1...
(ggc_alloc_*) macros defined for backport to GCC 4.5
(melt_forwarded_copy): Don't clear the new destination zone in old
GGC heap.
(meltgc_add_out_raw_len): Use ggc_alloc_atomic.
(meltgc_raw_new_mappointers, meltgc_raw_put_mappointers)
(meltgc_raw_remove_mappointers): Corrected length argument to
ggc_alloc_cleared_vec_entrypointermelt_st.
(melt_really_initialize): Call melt_allocate_young_gc_zone.
(melt_initialize): Set flag_plugin_added.
(melt_val2passflag): TODO_verify_loops only in GCC 4.5
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@164424 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r-- | gcc/gcc.c | 1987 |
1 files changed, 830 insertions, 1157 deletions
diff --git a/gcc/gcc.c b/gcc/gcc.c index 31e4ab37513..479d7daf2ff 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -82,6 +82,7 @@ compilation is specified by a string called a "spec". */ #include "intl.h" #include "prefix.h" #include "gcc.h" +#include "diagnostic.h" #include "flags.h" #include "opts.h" @@ -139,44 +140,9 @@ int is_cpp_driver; /* Flag set to nonzero if an @file argument has been supplied to gcc. */ static bool at_file_supplied; -/* Flag saying to pass the greatest exit code returned by a sub-process - to the calling program. */ -static int pass_exit_codes; - /* Definition of string containing the arguments given to configure. */ #include "configargs.h" -/* Flag saying to print the directories gcc will search through looking for - programs, libraries, etc. */ - -static int print_search_dirs; - -/* Flag saying to print the full filename of this file - as found through our usual search mechanism. */ - -static const char *print_file_name = NULL; - -/* As print_file_name, but search for executable file. */ - -static const char *print_prog_name = NULL; - -/* Flag saying to print the relative path we'd use to - find libgcc.a given the current compiler flags. */ - -static int print_multi_directory; - -static int print_sysroot; - -/* Flag saying to print the relative path we'd use to - find OS libraries given the current compiler flags. */ - -static int print_multi_os_directory; - -/* Flag saying to print the list of subdirectories and - compiler flags used to select them in a standard form. */ - -static int print_multi_lib; - /* Flag saying to print the command line options understood by gcc and its sub-processes. */ @@ -186,11 +152,6 @@ static int print_help_list; static int print_version; -/* Flag saying to print the sysroot suffix used for searching for - headers. */ - -static int print_sysroot_headers_suffix; - /* Flag indicating whether we should print the command and arguments */ static int verbose_flag; @@ -206,11 +167,6 @@ static int verbose_only_flag; static int print_subprocess_help; -/* Flag indicating whether we should report subprocess execution times - (if this is supported by the system - see pexecute.c). */ - -static int report_times; - /* Whether we should report subprocess execution times to a file. */ FILE *report_times_to_file = NULL; @@ -249,24 +205,15 @@ static enum save_temps { static char *save_temps_prefix = 0; static size_t save_temps_length = 0; -/* Nonzero means pass multiple source files to the compiler at one time. */ - -static int combine_flag = 0; - -/* Nonzero means use pipes to communicate between subprocesses. - Overridden by either of the above two flags. */ - -static int use_pipes; - /* The compiler version. */ static const char *compiler_version; -/* The target version specified with -V */ +/* The target version. */ static const char *const spec_version = DEFAULT_TARGET_VERSION; -/* The target machine specified with -b. */ +/* The target machine. */ static const char *spec_machine = DEFAULT_TARGET_MACHINE; @@ -279,27 +226,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 - -/* The number of errors that have occurred; the link phase will not be - run if this is nonzero. */ -static int error_count = 0; - /* Greatest exit code of sub-processes that has been encountered up to now. */ static int greatest_status = 1; @@ -315,14 +241,6 @@ static struct obstack obstack; static struct obstack collect_obstack; -/* This is a list of a wrapper program and its arguments. - e.g. wrapper_string of "strace,-c" - will cause all programs to run as - strace -c program arguments - instead of just - program arguments */ -static const char *wrapper_string; - /* Forward declaration for prototypes. */ struct path_prefix; struct prefix_list; @@ -378,8 +296,6 @@ static int default_arg (const char *, int); static void set_multilib_dir (void); static void print_multilib_info (void); static void perror_with_name (const char *); -static void fatal_ice (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -static void notice (const char *, ...) ATTRIBUTE_PRINTF_1; static void display_help (void); static void add_preprocessor_option (const char *, int); static void add_assembler_option (const char *, int); @@ -388,7 +304,7 @@ static void process_command (int, const char **); static int execute (void); static void alloc_args (void); static void clear_args (void); -static void fatal_error (int); +static void fatal_signal (int); #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC) static void init_gcc_specs (struct obstack *, const char *, const char *, const char *); @@ -401,8 +317,11 @@ static const char *getenv_spec_function (int, const char **); static const char *if_exists_spec_function (int, const char **); static const char *if_exists_else_spec_function (int, const char **); static const char *replace_outfile_spec_function (int, const char **); +static const char *remove_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 **); @@ -684,18 +603,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 "" @@ -780,16 +687,12 @@ proper position among the other output files. */ %{fuse-linker-plugin: \ -plugin %(linker_plugin_file) \ -plugin-opt=%(lto_wrapper) \ - -plugin-opt=%(lto_gcc) \ + -plugin-opt=-fresolution=%u.res \ %{static|static-libgcc:-plugin-opt=-pass-through=%(lto_libgcc)} \ %{static:-plugin-opt=-pass-through=-lc} \ - %{O*:-plugin-opt=-O%*} \ - %{w:-plugin-opt=-w} \ - %{f*:-plugin-opt=-f%*} \ - %{m*:-plugin-opt=-m%*} \ - %{v:-plugin-opt=-v} \ } \ - %{flto} %{fwhopr} %l " LINK_PIE_SPEC \ + %{flto:%<fcompare-debug*} %{fwhopr*:%<fcompare-debug*} \ + %{flto} %{fwhopr*} %l " LINK_PIE_SPEC \ "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\ %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\ %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\ @@ -836,7 +739,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 = ""; @@ -865,13 +767,13 @@ static const char *trad_capable_cpp = therefore no dependency entry, confuses make into thinking a .o file that happens to exist is up-to-date. */ static const char *cpp_unique_options = -"%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}}\ - %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I\ +"%{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I\ %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\ %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\ %{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*:%: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}\ @@ -894,7 +796,8 @@ 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}}\ - %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{a*}\ + %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\ + %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{aux-info*}\ %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)} \ %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}} \ %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\ @@ -982,13 +885,6 @@ struct user_specs static struct user_specs *user_specs_head, *user_specs_tail; -#ifndef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) -#endif - -#ifndef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) -#endif #ifdef HAVE_TARGET_EXECUTABLE_SUFFIX /* This defines which switches stop a full compilation. */ @@ -1098,12 +994,12 @@ static const struct compiler default_compilers[] = %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i} \n\ cc1 -fpreprocessed %{save-temps*:%b.i} %{!save-temps*:%g.i} \ %(cc1_options)\ - -o %g.s %{!o*:--output-pch=%i.gch}\ - %W{o*:--output-pch=%*}%V}\ + %{!fdump-ada-spec*:-o %g.s %{!o*:--output-pch=%i.gch}\ + %W{o*:--output-pch=%*}}%V}\ %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\ cc1 %(cpp_unique_options) %(cc1_options)\ - -o %g.s %{!o*:--output-pch=%i.gch}\ - %W{o*:--output-pch=%*}%V}}}}}}", 0, 0, 0}, + %{!fdump-ada-spec*:-o %g.s %{!o*:--output-pch=%i.gch}\ + %W{o*:--output-pch=%*}}%V}}}}}}", 0, 0, 0}, {".i", "@cpp-output", 0, 1, 0}, {"@cpp-output", "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 1, 0}, @@ -1189,7 +1085,7 @@ static const struct option_map option_map[] = {"--debug", "-g", "oj"}, {"--define-macro", "-D", "aj"}, {"--dependencies", "-M", 0}, - {"--dump", "-d", "a"}, + {"--dump", "-d", "aj"}, {"--dumpbase", "-dumpbase", "a"}, {"--dumpdir", "-dumpdir", "a"}, {"--encoding", "-fencoding=", "aj"}, @@ -1242,12 +1138,9 @@ static const struct option_map option_map[] = {"--print-sysroot", "-print-sysroot", 0}, {"--print-sysroot-headers-suffix", "-print-sysroot-headers-suffix", 0}, {"--profile", "-p", 0}, - {"--profile-blocks", "-a", 0}, - {"--quiet", "-q", 0}, {"--resource", "-fcompile-resource=", "aj"}, {"--save-temps", "-save-temps", 0}, {"--shared", "-shared", 0}, - {"--silent", "-q", 0}, {"--specs", "-specs=", "aj"}, {"--static", "-static", 0}, {"--std", "-std=", "aj"}, @@ -1400,7 +1293,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; } @@ -1411,7 +1304,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; } @@ -1424,7 +1317,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; } @@ -1482,7 +1375,7 @@ translate_options (int *argcp, const char *const **argvp) } } else - /* Ordinary operands, or +e options. */ + /* Ordinary operands. */ newv[newindex++] = argv[i++]; } @@ -1675,7 +1568,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), @@ -1724,8 +1616,11 @@ static const struct spec_function static_spec_functions[] = { "if-exists", if_exists_spec_function }, { "if-exists-else", if_exists_else_spec_function }, { "replace-outfile", replace_outfile_spec_function }, + { "remove-outfile", remove_outfile_spec_function }, { "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 }, @@ -1796,7 +1691,7 @@ init_spec (void) return; /* Already initialized. */ if (verbose_flag) - notice ("Using built-in specs.\n"); + fnotice (stderr, "Using built-in specs.\n"); #ifdef EXTRA_SPECS extra_specs = XCNEWVEC (struct spec_list, ARRAY_SIZE (extra_specs_1)); @@ -1981,7 +1876,7 @@ set_spec (const char *name, const char *spec) #ifdef DEBUG_SPECS if (verbose_flag) - notice ("Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec)); + fnotice (stderr, "Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec)); #endif /* Free the old spec. */ @@ -2036,10 +1931,6 @@ static int execution_count; /* Number of commands that exited with a signal. */ static int signal_count; - -/* Name with which this program was invoked. */ - -static const char *programname; /* Allocate the argument vector. */ @@ -2077,7 +1968,15 @@ store_arg (const char *arg, int delete_always, int delete_failure) if (strcmp (arg, "-o") == 0) have_o_argbuf_index = argbuf_index; if (delete_always || delete_failure) - record_temp_file (arg, delete_always, delete_failure); + { + const char *p; + /* If the temporary file we should delete is specified as + part of a joined argument extract the filename. */ + if (arg[0] == '-' + && (p = strrchr (arg, '='))) + arg = p + 1; + record_temp_file (arg, delete_always, delete_failure); + } } /* Load specs from a file name named FILENAME, replacing occurrences of @@ -2096,7 +1995,7 @@ load_specs (const char *filename) char *specs_p; if (verbose_flag) - notice ("Reading specs from %s\n", filename); + fnotice (stderr, "Reading specs from %s\n", filename); /* Open and stat the file. */ desc = open (filename, O_RDONLY, 0); @@ -2192,8 +2091,9 @@ read_specs (const char *filename, int main_p) p1++; if (*p1++ != '<' || p[-2] != '>') - fatal ("specs %%include syntax malformed after %ld characters", - (long) (p1 - buffer + 1)); + fatal_error ("specs %%include syntax malformed after " + "%ld characters", + (long) (p1 - buffer + 1)); p[-2] = '\0'; new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true); @@ -2211,15 +2111,16 @@ read_specs (const char *filename, int main_p) p1++; if (*p1++ != '<' || p[-2] != '>') - fatal ("specs %%include syntax malformed after %ld characters", - (long) (p1 - buffer + 1)); + fatal_error ("specs %%include syntax malformed after " + "%ld characters", + (long) (p1 - buffer + 1)); p[-2] = '\0'; new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true); if (new_filename) read_specs (new_filename, FALSE); else if (verbose_flag) - notice ("could not find specs file %s\n", p1); + fnotice (stderr, "could not find specs file %s\n", p1); continue; } else if (!strncmp (p1, "%rename", sizeof "%rename" - 1) @@ -2236,16 +2137,18 @@ read_specs (const char *filename, int main_p) p1++; if (! ISALPHA ((unsigned char) *p1)) - fatal ("specs %%rename syntax malformed after %ld characters", - (long) (p1 - buffer)); + fatal_error ("specs %%rename syntax malformed after " + "%ld characters", + (long) (p1 - buffer)); p2 = p1; while (*p2 && !ISSPACE ((unsigned char) *p2)) p2++; if (*p2 != ' ' && *p2 != '\t') - fatal ("specs %%rename syntax malformed after %ld characters", - (long) (p2 - buffer)); + fatal_error ("specs %%rename syntax malformed after " + "%ld characters", + (long) (p2 - buffer)); name_len = p2 - p1; *p2++ = '\0'; @@ -2253,8 +2156,9 @@ read_specs (const char *filename, int main_p) p2++; if (! ISALPHA ((unsigned char) *p2)) - fatal ("specs %%rename syntax malformed after %ld characters", - (long) (p2 - buffer)); + fatal_error ("specs %%rename syntax malformed after " + "%ld characters", + (long) (p2 - buffer)); /* Get new spec name. */ p3 = p2; @@ -2262,8 +2166,9 @@ read_specs (const char *filename, int main_p) p3++; if (p3 != p - 1) - fatal ("specs %%rename syntax malformed after %ld characters", - (long) (p3 - buffer)); + fatal_error ("specs %%rename syntax malformed after " + "%ld characters", + (long) (p3 - buffer)); *p3 = '\0'; for (sl = specs; sl; sl = sl->next) @@ -2271,21 +2176,22 @@ read_specs (const char *filename, int main_p) break; if (!sl) - fatal ("specs %s spec was not found to be renamed", p1); + fatal_error ("specs %s spec was not found to be renamed", p1); if (strcmp (p1, p2) == 0) continue; for (newsl = specs; newsl; newsl = newsl->next) if (strcmp (newsl->name, p2) == 0) - fatal ("%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) { - notice ("rename spec %s to %s\n", p1, p2); + fnotice (stderr, "rename spec %s to %s\n", p1, p2); #ifdef DEBUG_SPECS - notice ("spec is '%s'\n\n", *(sl->ptr_spec)); + fnotice (stderr, "spec is '%s'\n\n", *(sl->ptr_spec)); #endif } @@ -2298,8 +2204,8 @@ read_specs (const char *filename, int main_p) continue; } else - fatal ("specs unknown %% command after %ld characters", - (long) (p1 - buffer)); + fatal_error ("specs unknown %% command after %ld characters", + (long) (p1 - buffer)); } /* Find the colon that should end the suffix. */ @@ -2309,8 +2215,8 @@ read_specs (const char *filename, int main_p) /* The colon shouldn't be missing. */ if (*p1 != ':') - fatal ("specs file malformed after %ld characters", - (long) (p1 - buffer)); + fatal_error ("specs file malformed after %ld characters", + (long) (p1 - buffer)); /* Skip back over trailing whitespace. */ p2 = p1; @@ -2322,8 +2228,8 @@ read_specs (const char *filename, int main_p) /* Find the next line. */ p = skip_whitespace (p1 + 1); if (p[1] == 0) - fatal ("specs file malformed after %ld characters", - (long) (p - buffer)); + fatal_error ("specs file malformed after %ld characters", + (long) (p - buffer)); p1 = p; /* Find next blank line or end of string. */ @@ -2374,7 +2280,7 @@ read_specs (const char *filename, int main_p) } if (link_command_spec == 0) - fatal ("spec file has no spec for linking"); + fatal_error ("spec file has no spec for linking"); } /* Record the names of temporary files we tell compilers to write, @@ -2702,7 +2608,7 @@ static void xputenv (const char *string) { if (verbose_flag) - notice ("%s\n", string); + fnotice (stderr, "%s\n", string); putenv (CONST_CAST (char *, string)); } @@ -2903,7 +2809,7 @@ add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix, int require_machine_suffix, int os_multilib) { if (!IS_ABSOLUTE_PATH (prefix)) - fatal ("system path '%s' is not absolute", prefix); + fatal_error ("system path %qs is not absolute", prefix); if (target_system_root) { @@ -2975,7 +2881,7 @@ execute (void) if (strcmp (argbuf[i], "|") == 0) { /* each command. */ #if defined (__MSDOS__) || defined (OS2) || defined (VMS) - fatal ("-pipe not supported"); + fatal_error ("-pipe not supported"); #endif argbuf[i] = 0; /* termination of command args. */ commands[n_commands].prog = argbuf[i + 1]; @@ -3007,14 +2913,23 @@ execute (void) for (j = commands[i].argv; *j; j++) { const char *p; - fprintf (stderr, " \""); for (p = *j; *p; ++p) + if (!ISALNUM ((unsigned char) *p) + && *p != '_' && *p != '/' && *p != '-' && *p != '.') + break; + if (*p || !*j) { - if (*p == '"' || *p == '\\' || *p == '$') - fputc ('\\', stderr); - fputc (*p, stderr); + fprintf (stderr, " \""); + for (p = *j; *p; ++p) + { + if (*p == '"' || *p == '\\' || *p == '$') + fputc ('\\', stderr); + fputc (*p, stderr); + } + fputc ('"', stderr); } - fputc ('"', stderr); + else + fprintf (stderr, " %s", *j); } } else @@ -3037,7 +2952,7 @@ execute (void) return 0; } #ifdef DEBUG - notice ("\nGo ahead? (y or n) "); + fnotice (stderr, "\nGo ahead? (y or n) "); fflush (stderr); i = getchar (); if (i != '\n') @@ -3080,9 +2995,9 @@ execute (void) pex = pex_init (PEX_USE_PIPES | ((report_times || report_times_to_file) ? PEX_RECORD_TIMES : 0), - programname, temp_filename); + 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++) { @@ -3098,7 +3013,7 @@ execute (void) if (errmsg != NULL) { if (err == 0) - fatal (errmsg); + fatal_error (errmsg); else { errno = err; @@ -3121,13 +3036,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); @@ -3153,12 +3068,8 @@ execute (void) } else #endif - fatal_ice ("\ -Internal error: %s (program %s)\n\ -Please submit a full bug report.\n\ -See %s for instructions.", - strsignal (WTERMSIG (status)), commands[i].prog, - bug_report_url); + internal_error ("%s (program %s)", + strsignal (WTERMSIG (status)), commands[i].prog); } else if (WIFEXITED (status) && WEXITSTATUS (status) >= MIN_FATAL_STATUS) @@ -3181,7 +3092,8 @@ See %s for instructions.", if (ut + st != 0) { if (report_times) - notice ("# %s %.2f %.2f\n", commands[i].prog, ut, st); + fnotice (stderr, "# %s %.2f %.2f\n", + commands[i].prog, ut, st); if (report_times_to_file) { @@ -3256,6 +3168,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 @@ -3301,6 +3215,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. */ @@ -3375,7 +3291,7 @@ convert_filename (const char *name, int do_exe ATTRIBUTE_UNUSED, static void display_help (void) { - printf (_("Usage: %s [options] file...\n"), programname); + printf (_("Usage: %s [options] file...\n"), progname); fputs (_("Options:\n"), stdout); fputs (_(" -pass-exit-codes Exit with highest error code from a phase\n"), stdout); @@ -3420,8 +3336,6 @@ display_help (void) --sysroot=<directory> Use <directory> as the root directory for headers\n\ and libraries\n"), stdout); fputs (_(" -B <directory> Add <directory> to the compiler's search paths\n"), stdout); - fputs (_(" -b <machine> Run gcc for target <machine>, if installed\n"), stdout); - fputs (_(" -V <version> Run gcc version number <version>, if installed\n"), stdout); fputs (_(" -v Display the programs invoked by the compiler\n"), stdout); fputs (_(" -### Like -v but options quoted and commands not executed\n"), stdout); fputs (_(" -E Preprocess only; do not compile, assemble or link\n"), stdout); @@ -3439,7 +3353,7 @@ display_help (void) \nOptions starting with -g, -f, -m, -O, -W, or --param are automatically\n\ passed on to the various sub-processes invoked by %s. In order to pass\n\ other options on to these processes the -W<letter> options must be used.\n\ -"), programname); +"), progname); /* The rest of the options are displayed by invocations of the various sub-processes. */ @@ -3487,6 +3401,495 @@ 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); + } +} + +/* Save an option OPT with N_ARGS arguments in array ARGS, marking it + as validated if VALIDATED. */ + +static void +save_switch (const char *opt, size_t n_args, const char *const *args, + bool validated) +{ + alloc_switch (); + switches[n_switches].part1 = opt + 1; + if (n_args == 0) + switches[n_switches].args = 0; + else + { + switches[n_switches].args = XNEWVEC (const char *, n_args + 1); + memcpy (switches[n_switches].args, args, n_args * sizeof (const char *)); + switches[n_switches].args[n_args] = NULL; + } + + switches[n_switches].live_cond = 0; + switches[n_switches].validated = validated; + switches[n_switches].ordering = 0; + n_switches++; +} + +/* Handle an option DECODED that is unknown to the option-processing + machinery, but may be known to specs. */ + +static bool +driver_unknown_option_callback (const struct cl_decoded_option *decoded) +{ + save_switch (decoded->canonical_option[0], + decoded->canonical_option_num_elements - 1, + &decoded->canonical_option[1], false); + + return false; +} + +/* Handle an option DECODED that is not marked as CL_DRIVER. + LANG_MASK will always be CL_DRIVER. */ + +static void +driver_wrong_lang_callback (const struct cl_decoded_option *decoded, + unsigned int lang_mask ATTRIBUTE_UNUSED) +{ + /* At this point, non-driver options are accepted (and expected to + be passed down by specs) unless marked to be rejected by the + driver. Options to be rejected by the driver but accepted by the + compilers proper are treated just like completely unknown + options. */ + const struct cl_option *option = &cl_options[decoded->opt_index]; + + if (option->flags & CL_REJECT_DRIVER) + error ("unrecognized command line option %qs", + decoded->orig_option_with_args_text); + else + driver_unknown_option_callback (decoded); +} + +/* Note that an option (index OPT_INDEX, argument ARG, value VALUE) + has been successfully handled with a handler for mask MASK. */ + +static void +driver_post_handling_callback (const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED, + unsigned int mask ATTRIBUTE_UNUSED) +{ + /* Nothing to do here. */ +} + +static const char *spec_lang = 0; +static int last_language_n_infiles; + +/* Handle a driver option; arguments and return value as for + handle_option. */ + +static bool +driver_handle_option (const struct cl_decoded_option *decoded, + unsigned int lang_mask ATTRIBUTE_UNUSED, int kind, + const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) +{ + size_t opt_index = decoded->opt_index; + const char *arg = decoded->arg; + const char *compare_debug_replacement_opt; + int value = decoded->value; + bool validated = false; + bool do_save = true; + + gcc_assert (kind == DK_UNSPECIFIED); + + switch (opt_index) + { + case OPT_dumpspecs: + { + struct spec_list *sl; + init_spec (); + for (sl = specs; sl; sl = sl->next) + printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec)); + if (link_command_spec) + printf ("*link_command:\n%s\n\n", link_command_spec); + exit (0); + } + + case OPT_dumpversion: + printf ("%s\n", spec_version); + exit (0); + + case OPT_dumpmachine: + printf ("%s\n", spec_machine); + exit (0); + + case OPT_fversion: + /* translate_options () has turned --version into -fversion. */ + print_version = 1; + + /* 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")); + break; + + case OPT_fhelp: + /* translate_options () has turned --help into -fhelp. */ + print_help_list = 1; + + /* 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); + break; + + case OPT_fhelp_: + /* translate_options () has turned --help into -fhelp. */ + print_subprocess_help = 2; + break; + + case OPT_ftarget_help: + /* translate_options() has turned --target-help into -ftarget-help. */ + print_subprocess_help = 1; + + /* 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); + break; + + case OPT_pass_exit_codes: + case OPT_print_search_dirs: + case OPT_print_file_name_: + case OPT_print_prog_name_: + case OPT_print_multi_lib: + case OPT_print_multi_directory: + case OPT_print_sysroot: + case OPT_print_multi_os_directory: + case OPT_print_sysroot_headers_suffix: + case OPT_time: + case OPT_wrapper: + /* These options set the variables specified in common.opt + automatically, and do not need to be saved for spec + processing. */ + do_save = false; + break; + + case OPT_print_libgcc_file_name: + print_file_name = "libgcc.a"; + do_save = false; + break; + + case OPT_fcompare_debug_second: + compare_debug_second = 1; + break; + + case OPT_fcompare_debug: + switch (value) + { + case 0: + compare_debug_replacement_opt = "-fcompare-debug="; + arg = ""; + goto compare_debug_with_arg; + + case 1: + compare_debug_replacement_opt = "-fcompare-debug=-gtoggle"; + arg = "-gtoggle"; + goto compare_debug_with_arg; + + default: + gcc_unreachable (); + } + break; + + case OPT_fcompare_debug_: + compare_debug_replacement_opt = decoded->canonical_option[0]; + compare_debug_with_arg: + gcc_assert (decoded->canonical_option_num_elements == 1); + gcc_assert (arg != NULL); + if (arg) + compare_debug = 1; + else + compare_debug = -1; + if (compare_debug < 0) + compare_debug_opt = NULL; + else + compare_debug_opt = arg; + save_switch (compare_debug_replacement_opt, 0, NULL, validated); + return true; + + case OPT_Wa_: + { + int prev, j; + /* Pass the rest of this option to the assembler. */ + + /* Split the argument at commas. */ + prev = 0; + for (j = 0; arg[j]; j++) + if (arg[j] == ',') + { + add_assembler_option (arg + prev, j - prev); + prev = j + 1; + } + + /* Record the part after the last comma. */ + add_assembler_option (arg + prev, j - prev); + } + do_save = false; + break; + + case OPT_Wp_: + { + int prev, j; + /* Pass the rest of this option to the preprocessor. */ + + /* Split the argument at commas. */ + prev = 0; + for (j = 0; arg[j]; j++) + if (arg[j] == ',') + { + add_preprocessor_option (arg + prev, j - prev); + prev = j + 1; + } + + /* Record the part after the last comma. */ + add_preprocessor_option (arg + prev, j - prev); + } + do_save = false; + break; + + case OPT_Wl_: + { + int prev, j; + /* Split the argument at commas. */ + prev = 0; + for (j = 0; arg[j]; j++) + if (arg[j] == ',') + { + add_infile (save_string (arg + prev, j - prev), "*"); + prev = j + 1; + } + /* Record the part after the last comma. */ + add_infile (arg + prev, "*"); + } + do_save = false; + break; + + case OPT_Xlinker: + add_infile (arg, "*"); + do_save = false; + break; + + case OPT_Xpreprocessor: + add_preprocessor_option (arg, strlen (arg)); + do_save = false; + break; + + case OPT_Xassembler: + add_assembler_option (arg, strlen (arg)); + do_save = false; + break; + + case OPT_l: + /* POSIX allows separation of -l and the lib arg; canonicalize + by concatenating -l with its arg */ + add_infile (concat ("-l", arg, NULL), "*"); + do_save = false; + break; + + case OPT_L: + /* Similarly, canonicalize -L for linkers that may not accept + separate arguments. */ + save_switch (concat ("-L", arg, NULL), 0, NULL, validated); + return true; + + case OPT_save_temps: + save_temps_flag = SAVE_TEMPS_CWD; + validated = true; + break; + + case OPT_save_temps_: + if (strcmp (arg, "cwd") == 0) + save_temps_flag = SAVE_TEMPS_CWD; + else if (strcmp (arg, "obj") == 0 + || strcmp (arg, "object") == 0) + save_temps_flag = SAVE_TEMPS_OBJ; + else + fatal_error ("%qs is an unknown -save-temps option", + decoded->orig_option_with_args_text); + break; + + case OPT_no_canonical_prefixes: + /* Already handled as a special case, so ignored here. */ + do_save = false; + break; + + case OPT_pipe: + validated = true; + /* Fall through. */ + case OPT_combine: + /* These options set the variables specified in common.opt + automatically, but do need to be saved for spec + processing. */ + break; + + case OPT_specs_: + { + struct user_specs *user = XNEW (struct user_specs); + + user->next = (struct user_specs *) 0; + user->filename = arg; + if (user_specs_tail) + user_specs_tail->next = user; + else + user_specs_head = user; + user_specs_tail = user; + } + do_save = false; + break; + + case OPT__sysroot_: + target_system_root = arg; + target_system_root_changed = 1; + do_save = false; + break; + + case OPT_time_: + if (report_times_to_file) + fclose (report_times_to_file); + report_times_to_file = fopen (arg, "a"); + do_save = false; + break; + + case OPT____: + /* "-###" + This is similar to -v except that there is no execution + of the commands and the echoed arguments are quoted. It + is intended for use in shell scripts to capture the + driver-generated command line. */ + verbose_only_flag++; + verbose_flag++; + do_save = false; + break; + + case OPT_B: + { + size_t len = strlen (arg); + + /* Catch the case where the user has forgotten to append a + directory separator to the path. Note, they may be using + -B to add an executable name prefix, eg "i386-elf-", in + order to distinguish between multiple installations of + GCC in the same directory. Hence we must check to see + if appending a directory separator actually makes a + valid directory name. */ + if (!IS_DIR_SEPARATOR (arg[len - 1]) + && is_directory (arg, false)) + { + char *tmp = XNEWVEC (char, len + 2); + strcpy (tmp, arg); + tmp[len] = DIR_SEPARATOR; + tmp[++len] = 0; + arg = tmp; + } + + add_prefix (&exec_prefixes, arg, NULL, + PREFIX_PRIORITY_B_OPT, 0, 0); + add_prefix (&startfile_prefixes, arg, NULL, + PREFIX_PRIORITY_B_OPT, 0, 0); + add_prefix (&include_prefixes, arg, NULL, + PREFIX_PRIORITY_B_OPT, 0, 0); + } + validated = true; + break; + + case OPT_v: /* Print our subcommands and print versions. */ + verbose_flag++; + break; + + case OPT_x: + spec_lang = arg; + 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; + do_save = false; + break; + + case OPT_o: + have_o = 1; +#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX) + arg = convert_filename (arg, ! have_c, 0); +#endif + /* Save the output name in case -save-temps=obj was used. */ + save_temps_prefix = xstrdup (arg); + /* On some systems, ld cannot handle "-o" without a space. So + split the option from its argument. */ + save_switch ("-o", 1, &arg, validated); + return true; + + case OPT_static_libgcc: + case OPT_shared_libgcc: + case OPT_static_libgfortran: + case OPT_static_libstdc__: + /* These are always valid, since gcc.c itself understands the + first two, gfortranspec.c understands -static-libgfortran and + g++spec.c understands -static-libstdc++ */ + validated = true; + break; + + default: + /* Various driver options need no special processing at this + point, having been handled in a prescan above or being + handled by specs. */ + break; + } + + if (do_save) + save_switch (decoded->canonical_option[0], + decoded->canonical_option_num_elements - 1, + &decoded->canonical_option[1], validated); + return true; +} + /* Create the vector `switches' and its contents. Store its length in `n_switches'. */ @@ -3496,16 +3899,12 @@ process_command (int argc, const char **argv) int i; const char *temp; 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; + struct cl_option_handlers handlers; + struct cl_decoded_option *decoded_options; + unsigned int decoded_options_count, j; GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX"); @@ -3526,81 +3925,6 @@ process_command (int argc, const char **argv) } } - /* If there is a -V or -b option (or both), process it now, before - trying to interpret the rest of the command line. - Use heuristic that all configuration names must have at least - one dash '-'. This allows us to pass options starting with -b. */ - if (argc > 1 && argv[1][0] == '-' - && (argv[1][1] == 'V' - || (argv[1][1] == 'b' - && (argv[1][2] == '\0' - || NULL != strchr (argv[1] + 2, '-'))))) - { - const char *new_version = DEFAULT_TARGET_VERSION; - const char *new_machine = DEFAULT_TARGET_MACHINE; - const char *progname = argv[0]; - char **new_argv; - char *new_argv0; - int baselen; - int status = 0; - int err = 0; - const char *errmsg; - - while (argc > 1 && argv[1][0] == '-' - && (argv[1][1] == 'V' - || (argv[1][1] == 'b' - && (argv[1][2] == '\0' - || NULL != strchr (argv[1] + 2, '-'))))) - { - char opt = argv[1][1]; - const char *arg; - if (argv[1][2] != '\0') - { - arg = argv[1] + 2; - argc -= 1; - argv += 1; - } - else if (argc > 2) - { - arg = argv[2]; - argc -= 2; - argv += 2; - } - else - fatal ("'-%c' option must have argument", opt); - if (opt == 'V') - new_version = arg; - else - new_machine = arg; - } - - for (baselen = strlen (progname); baselen > 0; baselen--) - if (IS_DIR_SEPARATOR (progname[baselen-1])) - break; - new_argv0 = XDUPVAR (char, progname, baselen, - baselen + concat_length (new_version, new_machine, - "-gcc-", NULL) + 1); - strcpy (new_argv0 + baselen, new_machine); - strcat (new_argv0, "-gcc-"); - strcat (new_argv0, new_version); - - new_argv = XDUPVEC (char *, argv, argc + 1); - new_argv[0] = new_argv0; - - errmsg = pex_one (PEX_SEARCH, new_argv0, new_argv, progname, NULL, - NULL, &status, &err); - - if (errmsg) - { - if (err == 0) - fatal ("couldn't run '%s': %s", new_argv0, errmsg); - else - fatal ("couldn't run '%s': %s: %s", new_argv0, errmsg, - xstrerror (err)); - } - exit (status); - } - /* Convert new-style -- options to old-style. */ translate_options (&argc, CONST_CAST2 (const char *const **, const char ***, @@ -3661,10 +3985,11 @@ process_command (int argc, const char **argv) is relocated. The toolchain was either relocated using GCC_EXEC_PREFIX or an automatically created GCC_EXEC_PREFIX from argv[0]. */ + decode_cmdline_options_to_array (argc, argv, CL_DRIVER, + &decoded_options, &decoded_options_count); + /* Do language-specific adjustment/addition of flags. */ - lang_specific_driver (&argc, - CONST_CAST2 (const char *const **, const char ***, - &argv), + lang_specific_driver (&decoded_options, &decoded_options_count, &added_libraries); if (gcc_exec_prefix) @@ -3791,476 +4116,76 @@ 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). */ - - for (i = 1; i < argc; i++) - { - if (! strcmp (argv[i], "-dumpspecs")) - { - struct spec_list *sl; - init_spec (); - for (sl = specs; sl; sl = sl->next) - printf ("*%s:\n%s\n\n", sl->name, *(sl->ptr_spec)); - if (link_command_spec) - printf ("*link_command:\n%s\n\n", link_command_spec); - exit (0); - } - else if (! strcmp (argv[i], "-dumpversion")) - { - printf ("%s\n", spec_version); - exit (0); - } - else if (! strcmp (argv[i], "-dumpmachine")) - { - printf ("%s\n", spec_machine); - exit (0); - } - else if (strcmp (argv[i], "-fversion") == 0) - { - /* 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")); - } - 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); - } - 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++; - } - 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); - } - 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; - else if (! strcmp (argv[i], "-print-libgcc-file-name")) - print_file_name = "libgcc.a"; - else if (! strncmp (argv[i], "-print-file-name=", 17)) - print_file_name = argv[i] + 17; - else if (! strncmp (argv[i], "-print-prog-name=", 17)) - print_prog_name = argv[i] + 17; - else if (! strcmp (argv[i], "-print-multi-lib")) - print_multi_lib = 1; - else if (! strcmp (argv[i], "-print-multi-directory")) - print_multi_directory = 1; - else if (! strcmp (argv[i], "-print-sysroot")) - print_sysroot = 1; - else if (! strcmp (argv[i], "-print-multi-os-directory")) - print_multi_os_directory = 1; - else if (! strcmp (argv[i], "-print-sysroot-headers-suffix")) - print_sysroot_headers_suffix = 1; - else if (! strcmp (argv[i], "-fcompare-debug-second")) - { - compare_debug_second = 1; - n_switches++; - } - else if (! strcmp (argv[i], "-fno-compare-debug")) - { - argv[i] = "-fcompare-debug="; - goto compare_debug_with_arg; - } - else if (! strcmp (argv[i], "-fcompare-debug")) - { - argv[i] = "-fcompare-debug=-gtoggle"; - goto compare_debug_with_arg; - } -#define OPT "-fcompare-debug=" - else if (! strncmp (argv[i], OPT, sizeof (OPT) - 1)) - { - const char *opt; - compare_debug_with_arg: - opt = argv[i] + sizeof (OPT) - 1; -#undef OPT - if (*opt) - compare_debug = 1; - else - compare_debug = -1; - if (compare_debug < 0) - compare_debug_opt = NULL; - else - compare_debug_opt = opt; - n_switches++; - } - else if (! strncmp (argv[i], "-Wa,", 4)) - { - int prev, j; - /* Pass the rest of this option to the assembler. */ - - /* Split the argument at commas. */ - prev = 4; - for (j = 4; argv[i][j]; j++) - if (argv[i][j] == ',') - { - add_assembler_option (argv[i] + prev, j - prev); - prev = j + 1; - } - - /* Record the part after the last comma. */ - add_assembler_option (argv[i] + prev, j - prev); - } - else if (! strncmp (argv[i], "-Wp,", 4)) - { - int prev, j; - /* Pass the rest of this option to the preprocessor. */ - - /* Split the argument at commas. */ - prev = 4; - for (j = 4; argv[i][j]; j++) - if (argv[i][j] == ',') - { - add_preprocessor_option (argv[i] + prev, j - prev); - prev = j + 1; - } - - /* 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; - /* Split the argument at commas. */ - for (j = 3; argv[i][j]; j++) - n_infiles += (argv[i][j] == ','); - } - else if (strcmp (argv[i], "-Xlinker") == 0) - { - if (i + 1 == argc) - fatal ("argument to '-Xlinker' is missing"); - - n_infiles++; - i++; - } - else if (strcmp (argv[i], "-Xpreprocessor") == 0) - { - if (i + 1 == argc) - fatal ("argument to '-Xpreprocessor' is missing"); + /* Process the options and store input files and switches in their + vectors. */ - add_preprocessor_option (argv[i+1], strlen (argv[i+1])); - } - else if (strcmp (argv[i], "-Xassembler") == 0) - { - if (i + 1 == argc) - fatal ("argument to '-Xassembler' is missing"); + last_language_n_infiles = -1; - add_assembler_option (argv[i+1], strlen (argv[i+1])); - } - else if (strcmp (argv[i], "-l") == 0) - { - if (i + 1 == argc) - fatal ("argument to '-l' is missing"); + handlers.unknown_option_callback = driver_unknown_option_callback; + handlers.wrong_lang_callback = driver_wrong_lang_callback; + handlers.post_handling_callback = driver_post_handling_callback; + handlers.num_handlers = 1; + handlers.handlers[0].handler = driver_handle_option; + handlers.handlers[0].mask = CL_DRIVER; - n_infiles++; - i++; - } - else if (strncmp (argv[i], "-l", 2) == 0) - n_infiles++; - else if (strcmp (argv[i], "-save-temps") == 0) - { - save_temps_flag = SAVE_TEMPS_CWD; - n_switches++; - } - 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 ("'%s' is an unknown -save-temps option", argv[i]); - } - else if (strcmp (argv[i], "-no-canonical-prefixes") == 0) - /* Already handled as a special case, so ignored here. */ - ; - else if (strcmp (argv[i], "-combine") == 0) - { - combine_flag = 1; - n_switches++; - } - else if (strcmp (argv[i], "-specs") == 0) - { - struct user_specs *user = XNEW (struct user_specs); - if (++i >= argc) - fatal ("argument to '-specs' is missing"); - - user->next = (struct user_specs *) 0; - user->filename = argv[i]; - if (user_specs_tail) - user_specs_tail->next = user; - else - user_specs_head = user; - user_specs_tail = user; - } - else if (strncmp (argv[i], "-specs=", 7) == 0) - { - struct user_specs *user = XNEW (struct user_specs); - if (strlen (argv[i]) == 7) - fatal ("argument to '-specs=' is missing"); - - user->next = (struct user_specs *) 0; - user->filename = argv[i] + 7; - if (user_specs_tail) - user_specs_tail->next = user; - else - user_specs_head = user; - user_specs_tail = user; - } - else if (strcmp (argv[i], "-time") == 0) - report_times = 1; - else if (strncmp (argv[i], "-time=", sizeof ("-time=") - 1) == 0) - { - if (report_times_to_file) - fclose (report_times_to_file); - report_times_to_file = fopen (argv[i] + sizeof ("-time=") - 1, "a"); - } - else if (strcmp (argv[i], "-pipe") == 0) + for (j = 1; j < decoded_options_count; j++) + { + switch (decoded_options[j].opt_index) { - /* -pipe has to go into the switches array as well as - setting a flag. */ - use_pipes = 1; - n_switches++; + case OPT_S: + case OPT_c: + case OPT_E: + have_c = 1; + break; } - else if (strcmp (argv[i], "-wrapper") == 0) - { - if (++i >= argc) - fatal ("argument to '-wrapper' is missing"); + if (have_c) + break; + } - wrapper_string = argv[i]; - n_switches++; - n_switches++; - } - else if (strcmp (argv[i], "-###") == 0) - { - /* This is similar to -v except that there is no execution - of the commands and the echoed arguments are quoted. It - is intended for use in shell scripts to capture the - driver-generated command line. */ - verbose_only_flag++; - verbose_flag++; - } - else if (argv[i][0] == '-' && argv[i][1] != 0) + for (j = 1; j < decoded_options_count; j++) + { + if (decoded_options[j].opt_index == OPT_SPECIAL_input_file) { - const char *p = &argv[i][1]; - int c = *p; - - switch (c) + const char *arg = decoded_options[j].arg; + const char *p = strrchr (arg, '@'); + char *fname; + long offset; + int consumed; +#ifdef HAVE_TARGET_OBJECT_SUFFIX + arg = convert_filename (arg, 0, access (arg, 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 != arg + && sscanf (p, "@%li%n", &offset, &consumed) >= 1 + && strlen (p) == (unsigned int)consumed) { - case 'b': - if (p[1] && NULL == strchr (argv[i] + 2, '-')) - goto normal_switch; - - /* Fall through. */ - case 'V': - fatal ("'-%c' must come at the start of the command line", c); - break; - - case 'B': - { - const char *value; - int len; - - if (p[1] == 0 && i + 1 == argc) - fatal ("argument to '-B' is missing"); - if (p[1] == 0) - value = argv[++i]; - else - value = p + 1; - - len = strlen (value); - - /* Catch the case where the user has forgotten to append a - directory separator to the path. Note, they may be using - -B to add an executable name prefix, eg "i386-elf-", in - order to distinguish between multiple installations of - GCC in the same directory. Hence we must check to see - if appending a directory separator actually makes a - valid directory name. */ - if (! IS_DIR_SEPARATOR (value [len - 1]) - && is_directory (value, false)) - { - char *tmp = XNEWVEC (char, len + 2); - strcpy (tmp, value); - tmp[len] = DIR_SEPARATOR; - tmp[++ len] = 0; - value = tmp; - } - - add_prefix (&exec_prefixes, value, NULL, - PREFIX_PRIORITY_B_OPT, 0, 0); - add_prefix (&startfile_prefixes, value, NULL, - PREFIX_PRIORITY_B_OPT, 0, 0); - add_prefix (&include_prefixes, value, NULL, - PREFIX_PRIORITY_B_OPT, 0, 0); - n_switches++; - } - break; - - 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++; - break; - - case 'S': - case 'c': - case 'E': - if (p[1] == 0) - { - have_c = 1; - n_switches++; - break; - } - goto normal_switch; - - case 'o': - have_o = 1; -#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) - if (! have_c) + fname = (char *)xmalloc (p - arg + 1); + memcpy (fname, arg, p - arg); + fname[p - arg] = '\0'; + /* Only accept non-stdin and existing FNAME parts, otherwise + try with the full name. */ + if (strcmp (fname, "-") == 0 || access (fname, F_OK) < 0) { - int skip; - - /* Forward scan, just in case -S, -E or -c is specified - after -o. */ - int j = i + 1; - if (p[1] == 0) - ++j; - while (j < argc) - { - if (argv[j][0] == '-') - { - if (SWITCH_CURTAILS_COMPILATION (argv[j][1]) - && argv[j][2] == 0) - { - have_c = 1; - break; - } - else if ((skip = SWITCH_TAKES_ARG (argv[j][1]))) - j += skip - (argv[j][2] != 0); - else if ((skip = WORD_SWITCH_TAKES_ARG (argv[j] + 1))) - j += skip; - } - j++; - } + free (fname); + fname = xstrdup (arg); } -#endif -#if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) || defined(HAVE_TARGET_OBJECT_SUFFIX) - 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); -#endif - /* Save the output name in case -save-temps=obj was used. */ - if ((p[1] == 0) && argv[i + 1]) - save_temps_prefix = xstrdup(argv[i + 1]); - else - save_temps_prefix = xstrdup(argv[i] + 1); - goto normal_switch; - - 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 - - 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 + fname = xstrdup (arg); + + if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0) + perror_with_name (fname); + else + add_infile (arg, spec_lang); + + free (fname); + continue; } - else - { - n_infiles++; - lang_n_infiles++; - } + + read_cmdline_option (decoded_options + j, CL_DRIVER, &handlers); } /* If -save-temps=obj and -o name, create the prefix to use for %b. @@ -4286,7 +4211,7 @@ process_command (int argc, const char **argv) { /* -save-temps overrides -pipe, so that temp files are produced */ if (save_temps_flag) - error ("warning: -pipe ignored because -save-temps specified"); + warning (0, "-pipe ignored because -save-temps specified"); use_pipes = 0; } @@ -4298,13 +4223,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) @@ -4357,7 +4280,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, @@ -4373,257 +4296,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 ("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 ("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 and gfortranspec.c understands -static-libgfortran. */ - if (!strcmp (p, "save-temps") - || !strcmp (p, "static-libgcc") - || !strcmp (p, "shared-libgcc") - || !strcmp (p, "pipe") - || !strcmp (p, "static-libgfortran")) - 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); - error_count++; - } - 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) - error ("warning: '-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); @@ -4638,15 +4316,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; } @@ -4716,7 +4395,7 @@ set_collect_gcc_options (void) sans all directory names, and basename_length is the number of characters starting there excluding the suffix .c or whatever. */ -static const char *input_filename; +static const char *gcc_input_filename; static int input_file_number; size_t input_filename_length; static int basename_length; @@ -4783,7 +4462,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; } @@ -4971,7 +4650,7 @@ do_self_spec (const char *spec) /* Each switch should start with '-'. */ if (c != '-') - fatal ("switch '%s' does not start with '-'", argbuf[i]); + fatal_error ("switch %qs does not start with %<-%>", argbuf[i]); p++; c = *p; @@ -4995,7 +4674,7 @@ do_self_spec (const char *spec) n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0); } if (i + n_args >= argbuf_index) - fatal ("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) @@ -5003,9 +4682,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; @@ -5087,20 +4766,20 @@ create_at_file (char **argv) int status; if (f == NULL) - fatal ("could not open temporary response file %s", - temp_file); + fatal_error ("could not open temporary response file %s", + temp_file); status = writeargv (argv, f); if (status) - fatal ("could not write to temporary response file %s", - temp_file); + fatal_error ("could not write to temporary response file %s", + temp_file); status = fclose (f); if (EOF == status) - fatal ("could not close temporary response file %s", - temp_file); + fatal_error ("could not close temporary response file %s", + temp_file); store_arg (at_argument, 0, 0); @@ -5201,7 +4880,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) switch (c = *p++) { case 0: - fatal ("spec '%s' invalid", spec); + fatal_error ("spec %qs invalid", spec); case 'b': if (save_temps_length) @@ -5277,7 +4956,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) buf = (char *) alloca (p - q + 1); strncpy (buf, q, p - q); buf[p - q] = 0; - notice ("%s\n", _(buf)); + inform (0, "%s", _(buf)); if (*p) p++; } @@ -5350,7 +5029,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 ("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 @@ -5391,7 +5070,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) break; } - /* If the input_filename has the same suffix specified + /* If the gcc_input_filename has the same suffix specified for the %g, %u, or %U, and -save-temps is specified, we could end up using that file as an intermediate thus clobbering the user's source file (.e.g., @@ -5409,7 +5088,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) tmp[basename_length + suffix_length] = '\0'; temp_filename = tmp; - if (strcmp (temp_filename, input_filename) != 0) + if (strcmp (temp_filename, gcc_input_filename) != 0) { #ifndef HOST_LACKS_INODE_NUMBERS struct stat st_temp; @@ -5417,12 +5096,13 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) /* Note, set_input() resets input_stat_set to 0. */ if (input_stat_set == 0) { - input_stat_set = stat (input_filename, &input_stat); + input_stat_set = stat (gcc_input_filename, + &input_stat); if (input_stat_set >= 0) input_stat_set = 1; } - /* If we have the stat for the input_filename + /* If we have the stat for the gcc_input_filename and we can do the stat for the temp_filename then the they could still refer to the same file if st_dev/st_ino's are the same. */ @@ -5432,7 +5112,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) || input_stat.st_ino != st_temp.st_ino) #else /* Just compare canonical pathnames. */ - char* input_realname = lrealpath (input_filename); + char* input_realname = lrealpath (gcc_input_filename); char* temp_realname = lrealpath (temp_filename); bool files_differ = strcmp (input_realname, temp_realname); free (input_realname); @@ -5534,7 +5214,8 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) } else { - obstack_grow (&obstack, input_filename, input_filename_length); + obstack_grow (&obstack, gcc_input_filename, + input_filename_length); arg_going = 1; } break; @@ -5659,7 +5340,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 ("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; @@ -5679,7 +5360,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 ("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); @@ -5874,7 +5555,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. @@ -5883,7 +5564,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) %[...] modifies -D options the way %P does; %(...) uses the spec unmodified. */ case '[': - error ("warning: use of obsolete %%[ operator in specs"); + warning (0, "use of obsolete %%[ operator in specs"); case '(': { const char *name = p; @@ -5901,7 +5582,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) { name = *(sl->ptr_spec); #ifdef DEBUG_SPECS - notice ("Processing spec %c%s%c, which is '%s'\n", + fnotice (stderr, "Processing spec %c%s%c, which is '%s'\n", c, sl->name, (c == '(') ? ')' : ']', name); #endif break; @@ -5964,7 +5645,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; @@ -6026,7 +5707,7 @@ eval_spec_function (const char *func, const char *args) sf = lookup_spec_function (func); if (sf == NULL) - fatal ("unknown spec function '%s'", func); + fatal_error ("unknown spec function %qs", func); /* Push the spec processing context. */ save_argbuf_index = argbuf_index; @@ -6046,7 +5727,7 @@ eval_spec_function (const char *func, const char *args) alloc_args (); if (do_spec_2 (args) < 0) - fatal ("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. */ @@ -6095,10 +5776,10 @@ handle_spec_function (const char *p) break; /* Only allow [A-Za-z0-9], -, and _ in function names. */ if (!ISALNUM (*endp) && !(*endp == '-' || *endp == '_')) - fatal ("malformed spec function name"); + fatal_error ("malformed spec function name"); } if (*endp != '(') /* ) */ - fatal ("no arguments for spec function"); + fatal_error ("no arguments for spec function"); func = save_string (p, endp - p); p = ++endp; @@ -6117,7 +5798,7 @@ handle_spec_function (const char *p) } /* ( */ if (*endp != ')') - fatal ("malformed spec function arguments"); + fatal_error ("malformed spec function arguments"); args = save_string (p, endp - p); p = ++endp; @@ -6363,7 +6044,7 @@ handle_braces (const char *p) return p; invalid: - fatal ("braced spec '%s' is invalid at '%c'", orig, *p); + fatal_error ("braced spec %qs is invalid at %qc", orig, *p); #undef SKIP_WHITE } @@ -6451,7 +6132,7 @@ process_brace_body (const char *p, const char *atom, const char *end_atom, return p; invalid: - fatal ("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 @@ -6640,9 +6321,9 @@ set_input (const char *filename) { const char *p; - input_filename = filename; - input_filename_length = strlen (input_filename); - input_basename = lbasename (input_filename); + gcc_input_filename = filename; + input_filename_length = strlen (gcc_input_filename); + input_basename = lbasename (gcc_input_filename); /* Find a suffix starting with the last period, and set basename_length to exclude that suffix. */ @@ -6660,7 +6341,7 @@ set_input (const char *filename) input_suffix = ""; /* If a spec for 'g', 'u', or 'U' is seen with -save-temps then - we will need to do a stat on the input_filename. The + we will need to do a stat on the gcc_input_filename. The INPUT_STAT_SET signals that the stat is needed. */ input_stat_set = 0; } @@ -6668,7 +6349,7 @@ set_input (const char *filename) /* On fatal signals, delete all the temporary files. */ static void -fatal_error (int signum) +fatal_signal (int signum) { signal (signum, SIG_DFL); delete_failure_queue (); @@ -6701,7 +6382,7 @@ compare_files (char *cmpfile[]) if (stat (cmpfile[i], &st) < 0 || !S_ISREG (st.st_mode)) { error ("%s: could not determine length of compare-debug file %s", - input_filename, cmpfile[i]); + gcc_input_filename, cmpfile[i]); ret = 1; break; } @@ -6711,7 +6392,7 @@ compare_files (char *cmpfile[]) if (!ret && length[0] != length[1]) { - error ("%s: -fcompare-debug failure (length)", input_filename); + error ("%s: -fcompare-debug failure (length)", gcc_input_filename); ret = 1; } @@ -6722,7 +6403,7 @@ compare_files (char *cmpfile[]) if (fd < 0) { error ("%s: could not open compare-debug file %s", - input_filename, cmpfile[i]); + gcc_input_filename, cmpfile[i]); ret = 1; break; } @@ -6741,7 +6422,7 @@ compare_files (char *cmpfile[]) { if (memcmp (map[0], map[1], length[0]) != 0) { - error ("%s: -fcompare-debug failure", input_filename); + error ("%s: -fcompare-debug failure", gcc_input_filename); ret = 1; } } @@ -6763,7 +6444,7 @@ compare_files (char *cmpfile[]) if (!temp[i]) { error ("%s: could not open compare-debug file %s", - input_filename, cmpfile[i]); + gcc_input_filename, cmpfile[i]); ret = 1; break; } @@ -6779,7 +6460,7 @@ compare_files (char *cmpfile[]) if (c0 != c1) { error ("%s: -fcompare-debug failure", - input_filename); + gcc_input_filename); ret = 1; break; } @@ -6820,9 +6501,9 @@ main (int argc, char **argv) p = argv[0] + strlen (argv[0]); while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1])) --p; - programname = p; + progname = p; - xmalloc_set_program_name (programname); + xmalloc_set_program_name (progname); expandargv (&argc, &argv); @@ -6842,17 +6523,21 @@ main (int argc, char **argv) gcc_init_libintl (); + diagnostic_initialize (global_dc, 0); + if (atexit (delete_temp_files) != 0) + fatal_error ("atexit failed"); + if (signal (SIGINT, SIG_IGN) != SIG_IGN) - signal (SIGINT, fatal_error); + signal (SIGINT, fatal_signal); #ifdef SIGHUP if (signal (SIGHUP, SIG_IGN) != SIG_IGN) - signal (SIGHUP, fatal_error); + signal (SIGHUP, fatal_signal); #endif if (signal (SIGTERM, SIG_IGN) != SIG_IGN) - signal (SIGTERM, fatal_error); + signal (SIGTERM, fatal_signal); #ifdef SIGPIPE if (signal (SIGPIPE, SIG_IGN) != SIG_IGN) - signal (SIGPIPE, fatal_error); + signal (SIGPIPE, fatal_signal); #endif #ifdef SIGCHLD /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will @@ -7121,7 +6806,7 @@ main (int argc, char **argv) set_multilib_dir (); /* Set up to remember the pathname of gcc and any options - needed for collect. We use argv[0] instead of programname because + needed for collect. We use argv[0] instead of progname because we need the complete pathname. */ obstack_init (&collect_obstack); obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1); @@ -7145,7 +6830,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. */ @@ -7222,7 +6907,7 @@ main (int argc, char **argv) else /* The error status indicates that only one set of fixed headers should be built. */ - fatal ("not configured with sysroot headers suffix"); + fatal_error ("not configured with sysroot headers suffix"); } if (print_help_list) @@ -7247,7 +6932,7 @@ main (int argc, char **argv) if (print_version) { - printf (_("%s %s%s\n"), programname, pkgversion_string, + printf (_("%s %s%s\n"), progname, pkgversion_string, version_string); printf ("Copyright %s 2010 Free Software Foundation, Inc.\n", _("(C)")); @@ -7268,8 +6953,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" int n; const char *thrmod; - notice ("Target: %s\n", spec_machine); - notice ("Configured with: %s\n", configuration_arguments); + fnotice (stderr, "Target: %s\n", spec_machine); + fnotice (stderr, "Configured with: %s\n", configuration_arguments); #ifdef THREAD_MODEL_SPEC /* We could have defined THREAD_MODEL_SPEC to "%*" by default, @@ -7283,7 +6968,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" thrmod = thread_model; #endif - notice ("Thread model: %s\n", thrmod); + fnotice (stderr, "Thread model: %s\n", thrmod); /* compiler_version is truncated at the first space when initialized from version string, so truncate version_string at the first space @@ -7294,17 +6979,18 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" if (! strncmp (version_string, compiler_version, n) && compiler_version[n] == 0) - notice ("gcc version %s %s\n", version_string, pkgversion_string); + fnotice (stderr, "gcc version %s %s\n", version_string, + pkgversion_string); else - notice ("gcc driver version %s %sexecuting gcc version %s\n", - version_string, pkgversion_string, compiler_version); + fnotice (stderr, "gcc driver version %s %sexecuting gcc version %s\n", + version_string, pkgversion_string, compiler_version); if (n_infiles == 0) return (0); } if (n_infiles == added_libraries) - fatal ("no input files"); + fatal_error ("no input files"); /* Make a place to record the compiler output file names that correspond to the input files. */ @@ -7353,7 +7039,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" } if (!combine_inputs && have_c && have_o && lang_n_infiles > 1) - fatal ("cannot specify -o with -c, -S or -E with multiple files"); + fatal_error ("cannot specify -o with -c, -S or -E with multiple files"); if (combine_flag && save_temps_flag) { @@ -7379,7 +7065,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" if (input_file_compiler->spec[0] == '#') { error ("%s: %s compiler not installed on this system", - input_filename, &input_file_compiler->spec[1]); + gcc_input_filename, &input_file_compiler->spec[1]); this_file_error = 1; } else @@ -7387,7 +7073,8 @@ 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 ("spec '%s' is invalid", input_file_compiler->spec); + fatal_error ("spec %qs is invalid", + input_file_compiler->spec); infiles[i].name = argbuf[have_o_argbuf_index]; infiles[i].incompiler = lookup_compiler (infiles[i].name, @@ -7402,7 +7089,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" if (this_file_error) { delete_failure_queue (); - error_count++; + errorcount++; break; } clear_failure_queue (); @@ -7424,7 +7111,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" /* Use the same thing in %o, unless cp->spec says otherwise. */ - outfiles[i] = input_filename; + outfiles[i] = gcc_input_filename; /* Figure out which compiler from the file's suffix. */ @@ -7442,7 +7129,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" if (input_file_compiler->spec[0] == '#') { error ("%s: %s compiler not installed on this system", - input_filename, &input_file_compiler->spec[1]); + gcc_input_filename, &input_file_compiler->spec[1]); this_file_error = 1; } else @@ -7465,7 +7152,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" else if (compare_debug && debug_check_temp_file[0]) { if (verbose_flag) - error ("Recompiling with -fcompare-debug"); + inform (0, "recompiling with -fcompare-debug"); compare_debug = -compare_debug; n_switches = n_switches_debug_check[1]; @@ -7488,7 +7175,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" debug_check_temp_file[1])); if (verbose_flag) - error ("Comparing final insns dumps"); + inform (0, "comparing final insns dumps"); if (compare_files (debug_check_temp_file)) this_file_error = 1; @@ -7519,7 +7206,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" if (this_file_error) { delete_failure_queue (); - error_count++; + errorcount++; } /* If this compilation succeeded, don't delete those files later. */ clear_failure_queue (); @@ -7541,13 +7228,13 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" } } - if (error_count == 0) + if (!seen_error ()) { /* Make sure INPUT_FILE_NUMBER points to first available open slot. */ input_file_number = n_infiles; if (lang_specific_pre_link ()) - error_count++; + errorcount++; } /* Determine if there are any linker input files. */ @@ -7558,7 +7245,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" /* Run ld to link all the compiler output files. */ - if (num_linker_inputs > 0 && error_count == 0 && print_subprocess_help < 2) + if (num_linker_inputs > 0 && !seen_error () && print_subprocess_help < 2) { int tmp = execution_count; const char *fuse_linker_plugin = "fuse-linker-plugin"; @@ -7575,15 +7262,15 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" fuse_linker_plugin + strlen (fuse_linker_plugin), 0)) { linker_plugin_file_spec = find_a_file (&exec_prefixes, - "liblto_plugin.so", X_OK, + "liblto_plugin.so", R_OK, false); if (!linker_plugin_file_spec) - fatal ("-fuse-linker-plugin, but liblto_plugin.so not found"); + fatal_error ("-fuse-linker-plugin, but liblto_plugin.so not found"); lto_libgcc_spec = find_a_file (&startfile_prefixes, "libgcc.a", R_OK, true); if (!lto_libgcc_spec) - fatal ("could not find libgcc.a"); + fatal_error ("could not find libgcc.a"); } lto_gcc_spec = argv[0]; @@ -7601,23 +7288,23 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" } value = do_spec (link_command_spec); if (value < 0) - error_count = 1; + errorcount = 1; linker_was_run = (tmp != execution_count); } /* If options said don't run linker, complain about input files to be given to the linker. */ - if (! linker_was_run && error_count == 0) + if (! linker_was_run && !seen_error ()) for (i = 0; (int) i < n_infiles; i++) if (explicit_link_files[i] && !(infiles[i].language && infiles[i].language[0] == '*')) - error ("%s: linker input file unused because linking not done", - outfiles[i]); + warning (0, "%s: linker input file unused because linking not done", + outfiles[i]); /* Delete some or all of the temporary files we made. */ - if (error_count) + if (seen_error ()) delete_failure_queue (); delete_temp_files (); @@ -7628,7 +7315,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" } return (signal_count != 0 ? 2 - : error_count > 0 ? (pass_exit_codes ? greatest_status : 1) + : seen_error () ? (pass_exit_codes ? greatest_status : 1) : 0); } @@ -7723,76 +7410,7 @@ pfatal_with_name (const char *name) static void perror_with_name (const char *name) { - error ("%s: %s", name, xstrerror (errno)); -} - -/* Output an error message and exit. */ - -void -fancy_abort (const char *file, int line, const char *func) -{ - fatal_ice ("internal gcc abort in %s, at %s:%d", func, file, line); -} - -/* Output an error message and exit. */ - -void -fatal_ice (const char *cmsgid, ...) -{ - va_list ap; - - va_start (ap, cmsgid); - - fprintf (stderr, "%s: ", programname); - vfprintf (stderr, _(cmsgid), ap); - va_end (ap); - fprintf (stderr, "\n"); - delete_temp_files (); - exit (pass_exit_codes ? ICE_EXIT_CODE : 1); -} - -void -fatal (const char *cmsgid, ...) -{ - va_list ap; - - va_start (ap, cmsgid); - - fprintf (stderr, "%s: ", programname); - vfprintf (stderr, _(cmsgid), ap); - va_end (ap); - fprintf (stderr, "\n"); - delete_temp_files (); - exit (1); -} - -/* The argument is actually c-format, not gcc-internal-format, - but because functions with identical names are used through - the rest of the compiler with gcc-internal-format, we just - need to hope all users of these functions use the common - subset between c-format and gcc-internal-format. */ - -void -error (const char *gmsgid, ...) -{ - va_list ap; - - va_start (ap, gmsgid); - fprintf (stderr, "%s: ", programname); - vfprintf (stderr, _(gmsgid), ap); - va_end (ap); - - fprintf (stderr, "\n"); -} - -static void -notice (const char *cmsgid, ...) -{ - va_list ap; - - va_start (ap, cmsgid); - vfprintf (stderr, _(cmsgid), ap); - va_end (ap); + error ("%s: %m", name); } static inline void @@ -7947,7 +7565,8 @@ used_arg (const char *p, int len) if (*q == '\0') { invalid_matches: - fatal ("multilib spec '%s' is invalid", multilib_matches); + fatal_error ("multilib spec %qs is invalid", + multilib_matches); } q++; } @@ -8138,8 +7757,8 @@ set_multilib_dir (void) if (*p == '\0') { invalid_exclusions: - fatal ("multilib exclusions '%s' is invalid", - multilib_exclusions); + fatal_error ("multilib exclusions %qs is invalid", + multilib_exclusions); } if (! ok) @@ -8196,8 +7815,8 @@ set_multilib_dir (void) if (*p == '\0') { invalid_select: - fatal ("multilib select '%s' is invalid", - multilib_select); + fatal_error ("multilib select %qs is invalid", + multilib_select); } ++p; } @@ -8337,7 +7956,7 @@ print_multilib_info (void) if (*p == '\0') { invalid_select: - fatal ("multilib select '%s' is invalid", multilib_select); + fatal_error ("multilib select %qs is invalid", multilib_select); } ++p; @@ -8375,8 +7994,8 @@ print_multilib_info (void) if (*e == '\0') { invalid_exclusion: - fatal ("multilib exclusion '%s' is invalid", - multilib_exclusions); + fatal_error ("multilib exclusion %qs is invalid", + multilib_exclusions); } if (! m) @@ -8581,7 +8200,7 @@ getenv_spec_function (int argc, const char **argv) value = getenv (argv[0]); if (!value) - fatal ("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 @@ -8657,6 +8276,27 @@ replace_outfile_spec_function (int argc, const char **argv) return NULL; } +/* remove-outfile built-in spec function. + * + * This looks for the first argument in the outfiles array's name and + * removes it. */ + +static const char * +remove_outfile_spec_function (int argc, const char **argv) +{ + int i; + /* Must have exactly one argument. */ + if (argc != 1) + abort (); + + for (i = 0; i < n_infiles; i++) + { + if (outfiles[i] && !strcmp (outfiles[i], argv[0])) + outfiles[i] = NULL; + } + return NULL; +} + /* Given two version numbers, compares the two numbers. A version number must match the regular expression ([1-9][0-9]*|0)(\.([1-9][0-9]*|0))* @@ -8672,12 +8312,12 @@ compare_version_strings (const char *v1, const char *v2) abort (); rresult = regexec (&r, v1, 0, NULL, 0); if (rresult == REG_NOMATCH) - fatal ("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 ("invalid version number `%s'", v2); + fatal_error ("invalid version number %qs", v2); else if (rresult != 0) abort (); @@ -8720,13 +8360,13 @@ version_compare_spec_function (int argc, const char **argv) bool result; if (argc < 3) - fatal ("too few arguments to %%:version-compare"); + fatal_error ("too few arguments to %%:version-compare"); if (argv[0][0] == '\0') abort (); if ((argv[0][1] == '<' || argv[0][1] == '>') && argv[0][0] != '!') nargs = 2; if (argc != nargs + 3) - fatal ("too many arguments to %%:version-compare"); + fatal_error ("too many arguments to %%:version-compare"); switch_len = strlen (argv[nargs + 1]); for (i = 0; i < n_switches; i++) @@ -8767,7 +8407,7 @@ version_compare_spec_function (int argc, const char **argv) break; default: - fatal ("unknown operator '%s' in %%:version-compare", argv[0]); + fatal_error ("unknown operator %qs in %%:version-compare", argv[0]); } if (! result) return NULL; @@ -8794,6 +8434,38 @@ include_spec_function (int argc, const char **argv) return NULL; } +/* %: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) +{ + const char *file; + + if (argc != 1) + abort (); + + file = find_file (argv[0]); + return file; +} + + +/* %: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. */ @@ -8848,7 +8520,7 @@ compare_debug_dump_opt_spec_function (int arg, static char random_seed[HOST_BITS_PER_WIDE_INT / 4 + 3]; if (arg != 0) - fatal ("too many arguments to %%:compare-debug-dump-opt"); + fatal_error ("too many arguments to %%:compare-debug-dump-opt"); do_spec_2 ("%{fdump-final-insns=*:%*}"); do_spec_1 (" ", 0, NULL); @@ -8915,7 +8587,7 @@ compare_debug_self_opt_spec_function (int arg, const char **argv ATTRIBUTE_UNUSED) { if (arg != 0) - fatal ("too many arguments to %%:compare-debug-self-opt"); + fatal_error ("too many arguments to %%:compare-debug-self-opt"); if (compare_debug >= 0) return NULL; @@ -8950,17 +8622,18 @@ compare_debug_auxbase_opt_spec_function (int arg, int len; if (arg == 0) - fatal ("too few arguments to %%:compare-debug-auxbase-opt"); + fatal_error ("too few arguments to %%:compare-debug-auxbase-opt"); if (arg != 1) - fatal ("too many arguments to %%:compare-debug-auxbase-opt"); + fatal_error ("too many arguments to %%:compare-debug-auxbase-opt"); if (compare_debug >= 0) return NULL; len = strlen (argv[0]); if (len < 3 || strcmp (argv[0] + len - 3, ".gk") != 0) - fatal ("argument to %%:compare-debug-auxbase-opt does not end in .gk"); + fatal_error ("argument to %%:compare-debug-auxbase-opt " + "does not end in .gk"); if (debug_auxbase_opt) return debug_auxbase_opt; |