OSDN Git Service

* ChangeLog: Follow spelling conventions.
[pf3gnuchains/gcc-fork.git] / gcc / gcc.c
index 6c9beb5..3bff09a 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1,6 +1,6 @@
 /* Compiler driver program that can handle many languages.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
-   1999, 2000, 2001 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -93,9 +93,6 @@ extern int getrusage PARAMS ((int, struct rusage *));
 /* FIXME: when autoconf is fixed, remove the host check - dj */
 #if defined(TARGET_EXECUTABLE_SUFFIX) && defined(HOST_EXECUTABLE_SUFFIX)
 #define HAVE_TARGET_EXECUTABLE_SUFFIX
-#else
-#undef TARGET_EXECUTABLE_SUFFIX
-#define TARGET_EXECUTABLE_SUFFIX ""
 #endif
 
 /* By default there is no special suffix for host executables.  */
@@ -122,13 +119,6 @@ extern int getrusage PARAMS ((int, struct rusage *));
 
 static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
 
-#define obstack_chunk_alloc xmalloc
-#define obstack_chunk_free free
-
-#ifndef GET_ENV_PATH_LIST
-#define GET_ENV_PATH_LIST(VAR,NAME)    do { (VAR) = getenv (NAME); } while (0)
-#endif
-
 /* Most every one is fine with LIBRARY_PATH.  For some, it conflicts.  */
 #ifndef LIBRARY_PATH_ENV
 #define LIBRARY_PATH_ENV "LIBRARY_PATH"
@@ -213,7 +203,7 @@ static const char *compiler_version;
 
 /* The target version specified with -V */
 
-static const char *spec_version = DEFAULT_TARGET_VERSION;
+static const char *const spec_version = DEFAULT_TARGET_VERSION;
 
 /* The target machine specified with -b.  */
 
@@ -234,7 +224,7 @@ static const char *cross_compile = "0";
    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.  */
 
-const struct modify_target
+static const struct modify_target
 {
   const char *const sw;
   const enum add_del {ADD, DELETE} add_del;
@@ -242,7 +232,7 @@ const struct modify_target
 }
 modify_target[] = MODIFY_TARGET_NAME;
 #endif
+
 /* The number of errors that have occurred; the link phase will not be
    run if this is non-zero.  */
 static int error_count = 0;
@@ -299,6 +289,7 @@ static const char *handle_braces PARAMS ((const char *));
 static char *save_string       PARAMS ((const char *, int));
 static void set_collect_gcc_options PARAMS ((void));
 static int do_spec_1           PARAMS ((const char *, int, const char *));
+static int do_spec_2           PARAMS ((const char *));
 static const char *find_file   PARAMS ((const char *));
 static int is_directory                PARAMS ((const char *, const char *, int));
 static void validate_switches  PARAMS ((const char *));
@@ -323,7 +314,7 @@ static void clear_args                      PARAMS ((void));
 static void fatal_error                        PARAMS ((int));
 #ifdef ENABLE_SHARED_LIBGCC
 static void init_gcc_specs              PARAMS ((struct obstack *,
-                                                const char *,
+                                                const char *, const char *,
                                                 const char *));
 #endif
 #if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
@@ -445,7 +436,6 @@ or with constant text in a single argument.
        if multilib_dir is not set or is ".", output "".
  %S     process STARTFILE_SPEC as a spec.  A capital S is actually used here.
  %E     process ENDFILE_SPEC as a spec.  A capital E is actually used here.
- %c    process SIGNED_CHAR_SPEC as a spec.
  %C     process CPP_SPEC as a spec.
  %1    process CC1_SPEC as a spec.
  %2    process CC1PLUS_SPEC as a spec.
@@ -511,7 +501,7 @@ CC also knows implicitly that arguments starting in `-l' are to be
 treated as compiler output files, and passed to the linker in their
 proper position among the other output files.  */
 \f
-/* Define the macros used for specs %a, %l, %L, %S, %c, %C, %1.  */
+/* Define the macros used for specs %a, %l, %L, %S, %C, %1.  */
 
 /* config.h can define ASM_SPEC to provide extra args to the assembler
    or extra switch-translations.  */
@@ -582,17 +572,6 @@ proper position among the other output files.  */
 #define ENDFILE_SPEC ""
 #endif
 
-/* This spec is used for telling cpp whether char is signed or not.  */
-#ifndef SIGNED_CHAR_SPEC
-/* Use #if rather than ?:
-   because MIPS C compiler rejects like ?: in initializers.  */
-#if DEFAULT_SIGNED_CHAR
-#define SIGNED_CHAR_SPEC "%{funsigned-char:-D__CHAR_UNSIGNED__}"
-#else
-#define SIGNED_CHAR_SPEC "%{!fsigned-char:-D__CHAR_UNSIGNED__}"
-#endif
-#endif
-
 #ifndef LINKER_NAME
 #define LINKER_NAME "collect2"
 #endif
@@ -621,6 +600,13 @@ proper position among the other output files.  */
 
 /* Here is the spec for running the linker, after compiling all files.  */
 
+/* This is overridable by the target in case they need to specify the
+   -lgcc and -lc order specially, yet not require them to override all
+   of LINK_COMMAND_SPEC.  */
+#ifndef LINK_GCC_C_SEQUENCE_SPEC
+#define LINK_GCC_C_SEQUENCE_SPEC "%G %L %G"
+#endif
+
 /* -u* was put back because both BSD and SysV seem to support it.  */
 /* %{static:} simply prevents an error message if the target machine
    doesn't handle -static.  */
@@ -632,7 +618,7 @@ proper position among the other output files.  */
 %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
     %(linker) %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r} %{s} %{t}\
     %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
-    %{static:} %{L*} %(link_libgcc) %o %{!nostdlib:%{!nodefaultlibs:%G %L %G}}\
+    %{static:} %{L*} %(link_libgcc) %o %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
     %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
 #endif
 
@@ -646,12 +632,16 @@ proper position among the other output files.  */
 # endif
 #endif
 
-static const char *asm_debug = ASM_DEBUG_SPEC;
+#ifndef STARTFILE_PREFIX_SPEC
+# define STARTFILE_PREFIX_SPEC ""
+#endif
+
+static const char *asm_debug;
 static const char *cpp_spec = CPP_SPEC;
 static const char *cpp_predefines = CPP_PREDEFINES;
 static const char *cc1_spec = CC1_SPEC;
 static const char *cc1plus_spec = CC1PLUS_SPEC;
-static const char *signed_char_spec = SIGNED_CHAR_SPEC;
+static const char *link_gcc_c_sequence_spec = LINK_GCC_C_SEQUENCE_SPEC;
 static const char *asm_spec = ASM_SPEC;
 static const char *asm_final_spec = ASM_FINAL_SPEC;
 static const char *link_spec = LINK_SPEC;
@@ -663,6 +653,7 @@ static const char *switches_need_spaces = SWITCHES_NEED_SPACES;
 static const char *linker_name_spec = LINKER_NAME;
 static const char *link_command_spec = LINK_COMMAND_SPEC;
 static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
+static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
 
 /* Standard options to cpp, cc1, and as, to reduce duplication in specs.
    There should be no need to override these in target dependent files,
@@ -670,35 +661,45 @@ static const char *link_libgcc_spec = LINK_LIBGCC_SPEC;
    of the GCC driver can correctly drive older tool chains with the
    appropriate -B options.  */
 
+/* When cpplib handles traditional preprocessing, get rid of this, and
+   call cc1 (or cc1obj in objc/lang-specs.h) from the main specs so
+   that we default the front end language better.  */
 static const char *trad_capable_cpp =
-"%{traditional|ftraditional|traditional-cpp:trad}cpp0";
+"cc1 -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp}";
 
-static const char *cpp_options =
+static const char *cpp_unique_options =
 "%{C:%{!E:%eGNU C does not support -C without using -E}}\
- %{std*} %{nostdinc*}\
- %{C} %{v} %{I*} %{P} %{$} %I\
- %{MD:-M -MF %W{!o: %b.d}%W{o*:%.d%*}}\
- %{MMD:-MM -MF %W{!o: %b.d}%W{o*:%.d%*}}\
- %{M} %{MM} %W{MF*} %{MG} %{MP} %{MQ*} %{MT*} %{M|MD|MM|MMD:%{o*:-MQ %*}}\
+ %{CC:%{!E:%eGNU C does not support -CC without using -E}}\
+ %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*} %{P} %I\
+ %{MD:-MD %W{!o: %b.d}%W{o*:%.d%*}}\
+ %{MMD:-MMD %W{!o: %b.d}%W{o*:%.d%*}}\
+ %{M} %{MM} %W{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
+ %{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
  %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3}\
  %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
- %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\
- %{fno-inline|O0|!O*:-D__NO_INLINE__} %{ffast-math:-D__FAST_MATH__}\
- %{fshort-wchar:-U__WCHAR_TYPE__ -D__WCHAR_TYPE__=short\\ unsigned\\ int}\
- %{ffreestanding:-D__STDC_HOSTED__=0} %{fno-hosted:-D__STDC_HOSTED__=0}\
- %{!ffreestanding:%{!fno-hosted:-D__STDC_HOSTED__=1}}\
- %{fshow-column} %{fno-show-column}\
- %{fleading-underscore} %{fno-leading-underscore}\
- %{fno-operator-names} %{ftabstop=*} %{remap}\
- %{g3:-dD} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*&U*&A*} %{i*} %Z %i\
- %{E:%{!M*:%W{o*}}}";
+ %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
+ %{E|M|MM:%W{o*}}";
+
+/* This contains cpp options which are common with cc1_options and are passed
+   only when preprocessing only to avoid duplication.  We pass the cc1 spec
+   options to the preprocessor so that it the cc1 spec may manipulate
+   options used to set target flags.  Those special target flags settings may
+   in turn cause preprocessor symbols to be defined specially.  */
+static const char *cpp_options =
+"%(cpp_unique_options) %1 %{std*} %{W*&pedantic*} %{w} %{m*} %{f*}\
+ %{O*} %{undef}";
+
+/* This contains cpp options which are not passed when the preprocessor
+   output will be used by another program.  */
+static const char *cpp_debug_options = "%{d*}";
 
 /* NB: This is shared amongst all front-ends.  */
 static const char *cc1_options =
 "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
  %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\
- %{g*} %{O*} %{W*} %{w} %{pedantic*} %{std*} %{ansi}\
- %{traditional} %{v:-version} %{pg:-p} %{p} %{f*}\
+ -auxbase%{c|S:%{o*:-strip%*}%{!o*: %b}}%{!c:%{!S: %b}}\
+ %{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\
+ %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
  %{Qn:-fno-ident} %{--help:--help}\
  %{--target-help:--target-help}\
  %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
@@ -742,8 +743,7 @@ static struct user_specs *user_specs_head, *user_specs_tail;
   ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
    || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
    || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x' \
-   || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'V' \
-   || (CHAR) == 'B' || (CHAR) == 'b')
+   || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'B' || (CHAR) == 'b')
 
 #ifndef SWITCH_TAKES_ARG
 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
@@ -807,7 +807,7 @@ static int n_compilers;
 
 /* The default list of file name suffixes and their compilation specs.  */
 
-static struct compiler default_compilers[] =
+static const struct compiler default_compilers[] =
 {
   /* Add lists of suffixes of known languages here.  If those languages
      were not present when we built the driver, we will hit these copies
@@ -822,33 +822,31 @@ static struct compiler default_compilers[] =
   {".F", "#Fortran", 0}, {".FOR", "#Fortran", 0}, {".FPP", "#Fortran", 0},
   {".r", "#Ratfor", 0},
   {".p", "#Pascal", 0}, {".pas", "#Pascal", 0},
-  {".ch", "#Chill", 0}, {".chi", "#Chill", 0},
   {".java", "#Java", 0}, {".class", "#Java", 0},
   {".zip", "#Java", 0}, {".jar", "#Java", 0},
   /* Next come the entries for C.  */
   {".c", "@c", 0},
   {"@c",
    /* cc1 has an integrated ISO C preprocessor.  We should invoke the
-      external preprocessor if -save-temps or -traditional is given.  */
-     "%{E|M|MM:%(trad_capable_cpp) -lang-c %{ansi:-std=c89} %(cpp_options)}\
+      external preprocessor if -save-temps is given.  */
+     "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
       %{!E:%{!M:%{!MM:\
-         %{save-temps:%(trad_capable_cpp) -lang-c %{ansi:-std=c89}\
+          %{traditional|ftraditional:\
+%eGNU C no longer supports -traditional without -E}\
+         %{save-temps|traditional-cpp:%(trad_capable_cpp) \
                %(cpp_options) %b.i \n\
                    cc1 -fpreprocessed %b.i %(cc1_options)}\
-         %{!save-temps:\
-           %{traditional|ftraditional|traditional-cpp:\
-               tradcpp0 -lang-c %{ansi:-std=c89} %(cpp_options) %{!pipe:%g.i} |\n\
-                   cc1 -fpreprocessed %{!pipe:%g.i} %(cc1_options)}\
-           %{!traditional:%{!ftraditional:%{!traditional-cpp:\
-               cc1 -lang-c %{ansi:-std=c89} %(cpp_options) %(cc1_options)}}}}\
+         %{!save-temps:%{!traditional-cpp:\
+               cc1 %(cpp_unique_options) %(cc1_options)}}\
         %{!fsyntax-only:%(invoke_as)}}}}", 0},
   {"-",
    "%{!E:%e-E required when input is from standard input}\
-    %(trad_capable_cpp) -lang-c %{ansi:-std=c89} %(cpp_options)", 0},
+    %(trad_capable_cpp) %(cpp_options)", 0},
   {".h", "@c-header", 0},
   {"@c-header",
    "%{!E:%ecompilation of header file requested} \
-    %(trad_capable_cpp) -lang-c %{ansi:-std=c89} %(cpp_options)", 0},
+    %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)",
+   0},
   {".i", "@cpp-output", 0},
   {"@cpp-output",
    "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
@@ -858,6 +856,7 @@ static struct compiler default_compilers[] =
   {".S", "@assembler-with-cpp", 0},
   {"@assembler-with-cpp",
    "%(trad_capable_cpp) -lang-asm %(cpp_options)\
+      %{E|M|MM:%(cpp_debug_options)}\
       %{!M:%{!MM:%{!E:%{!S:-o %{|!pipe:%g.s} |\n\
        as %(asm_debug) %(asm_options) %{!pipe:%g.s} %A }}}}", 0},
 #include "specs.h"
@@ -867,8 +866,7 @@ static struct compiler default_compilers[] =
 
 /* Number of elements in default_compilers, not counting the terminator.  */
 
-static int n_default_compilers
-  = (sizeof default_compilers / sizeof (struct compiler)) - 1;
+static const int n_default_compilers = ARRAY_SIZE (default_compilers) - 1;
 
 /* A vector of options to give to the linker.
    These options are accumulated by %x,
@@ -915,8 +913,10 @@ static const struct option_map option_map[] =
    {"--assemble", "-S", 0},
    {"--assert", "-A", "a"},
    {"--classpath", "-fclasspath=", "aj"},
-   {"--CLASSPATH", "-fCLASSPATH=", "aj"},
+   {"--bootclasspath", "-fbootclasspath=", "aj"},
+   {"--CLASSPATH", "-fclasspath=", "aj"},
    {"--comments", "-C", 0},
+   {"--comments-in-macros", "-CC", 0},
    {"--compile", "-c", 0},
    {"--debug", "-g", "oj"},
    {"--define-macro", "-D", "aj"},
@@ -965,6 +965,7 @@ static const struct option_map option_map[] =
    {"--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},
@@ -982,7 +983,6 @@ static const struct option_map option_map[] =
    {"--use-version", "-V", "a"},
    {"--user-dependencies", "-MM", 0},
    {"--verbose", "-v", 0},
-   {"--version", "-dumpversion", 0},
    {"--warn-", "-W", "*j"},
    {"--write-dependencies", "-MD", 0},
    {"--write-user-dependencies", "-MMD", 0},
@@ -1184,7 +1184,7 @@ translate_options (argcp, argvp)
            nskip += SWITCH_TAKES_ARG (c) - (p[1] != 0);
          else if (WORD_SWITCH_TAKES_ARG (p))
            nskip += WORD_SWITCH_TAKES_ARG (p);
-         else if ((c == 'B' || c == 'b' || c == 'V' || c == 'x')
+         else if ((c == 'B' || c == 'b' || c == 'x')
                   && p[1] == 0)
            nskip += 1;
          else if (! strcmp (p, "Xlinker"))
@@ -1368,17 +1368,19 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("invoke_as",               &invoke_as),
   INIT_STATIC_SPEC ("cpp",                     &cpp_spec),
   INIT_STATIC_SPEC ("cpp_options",             &cpp_options),
+  INIT_STATIC_SPEC ("cpp_debug_options",       &cpp_debug_options),
+  INIT_STATIC_SPEC ("cpp_unique_options",      &cpp_unique_options),
   INIT_STATIC_SPEC ("trad_capable_cpp",                &trad_capable_cpp),
   INIT_STATIC_SPEC ("cc1",                     &cc1_spec),
   INIT_STATIC_SPEC ("cc1_options",             &cc1_options),
   INIT_STATIC_SPEC ("cc1plus",                 &cc1plus_spec),
+  INIT_STATIC_SPEC ("link_gcc_c_sequence",     &link_gcc_c_sequence_spec),
   INIT_STATIC_SPEC ("endfile",                 &endfile_spec),
   INIT_STATIC_SPEC ("link",                    &link_spec),
   INIT_STATIC_SPEC ("lib",                     &lib_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 ("signed_char",             &signed_char_spec),
   INIT_STATIC_SPEC ("predefines",              &cpp_predefines),
   INIT_STATIC_SPEC ("cross_compile",           &cross_compile),
   INIT_STATIC_SPEC ("version",                 &compiler_version),
@@ -1392,6 +1394,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("md_exec_prefix",          &md_exec_prefix),
   INIT_STATIC_SPEC ("md_startfile_prefix",     &md_startfile_prefix),
   INIT_STATIC_SPEC ("md_startfile_prefix_1",   &md_startfile_prefix_1),
+  INIT_STATIC_SPEC ("startfile_prefix_spec",   &startfile_prefix_spec),
 };
 
 #ifdef EXTRA_SPECS             /* additional specs needed */
@@ -1416,29 +1419,29 @@ static struct spec_list *specs = (struct spec_list *) 0;
 
 #ifdef ENABLE_SHARED_LIBGCC
 static void
-init_gcc_specs (obstack, shared_name, static_name)
+init_gcc_specs (obstack, shared_name, static_name, eh_name)
      struct obstack *obstack;
      const char *shared_name;
      const char *static_name;
+     const char *eh_name;
 {
-  char buffer[128];
-
-  /* If we see -shared-libgcc, then use the shared version.  */
-  sprintf (buffer, "%%{shared-libgcc:%s %s}", shared_name, static_name);
-  obstack_grow (obstack, buffer, strlen (buffer));
-  /* If we see -static-libgcc, then use the static version.  */
-  sprintf (buffer, "%%{static-libgcc:%s}", static_name);
-  obstack_grow (obstack, buffer, strlen (buffer));
-  /* Otherwise, if we see -shared, then use the shared version.  */
-  sprintf (buffer,
-          "%%{!shared-libgcc:%%{!static-libgcc:%%{shared:%s %s}}}", 
-          shared_name, static_name);
-  obstack_grow (obstack, buffer, strlen (buffer));
-  /* Otherwise, use the static version.  */
-  sprintf (buffer, 
-          "%%{!shared-libgcc:%%{!static-libgcc:%%{!shared:%s}}}", 
-          static_name);
-  obstack_grow (obstack, buffer, strlen (buffer));
+  char *buf;
+
+  buf = concat ("%{static|static-libgcc:", static_name, " ", eh_name,
+               "}%{!static:%{!static-libgcc:",
+               "%{!shared:%{!shared-libgcc:", static_name, " ",
+               eh_name, "}%{shared-libgcc:", shared_name, " ",
+               static_name, "}}%{shared:",
+#ifdef LINK_EH_SPEC
+               "%{shared-libgcc:", shared_name,
+               "}%{!shared-libgcc:", static_name, "}",
+#else
+               shared_name,
+#endif
+               "}}}", NULL);
+
+  obstack_grow (obstack, buf, strlen (buf));
+  free (buf);
 }
 #endif /* ENABLE_SHARED_LIBGCC */
 
@@ -1455,7 +1458,7 @@ init_spec ()
     return;                    /* Already initialized.  */
 
   if (verbose_flag)
-    notice ("Using builtin specs.\n");
+    notice ("Using built-in specs.\n");
 
 #ifdef EXTRA_SPECS
   extra_specs = (struct spec_list *)
@@ -1473,6 +1476,10 @@ init_spec ()
     }
 #endif
 
+  /* Initialize here, not in definition.  The IRIX 6 O32 cc sometimes chokes
+     on ?: in file-scope variable initializations.  */
+  asm_debug = ASM_DEBUG_SPEC;
+
   for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
     {
       sl = &static_specs[i];
@@ -1511,12 +1518,12 @@ init_spec ()
   {
     const char *p = libgcc_spec;
     int in_sep = 1;
+
     /* Transform the extant libgcc_spec into one that uses the shared libgcc
        when given the proper command line arguments.  */
     while (*p)
       {
-        if (in_sep && *p == '-' && strncmp (p, "-lgcc", 5) == 0)
+       if (in_sep && *p == '-' && strncmp (p, "-lgcc", 5) == 0)
          {
            init_gcc_specs (&obstack,
 #ifdef NO_SHARED_LIBGCC_MULTILIB
@@ -1525,7 +1532,8 @@ init_spec ()
                            "-lgcc_s%M"
 #endif
                            ,
-                           "-lgcc");
+                           "-lgcc",
+                           "-lgcc_eh");
            p += 5;
            in_sep = 0;
          }
@@ -1540,7 +1548,8 @@ init_spec ()
                            "-lgcc_s%M"
 #endif
                            ,
-                           "libgcc.a%s");
+                           "libgcc.a%s",
+                           "libgcc_eh.a%s");
            p += 10;
            in_sep = 0;
          }
@@ -1565,6 +1574,12 @@ init_spec ()
     asm_spec = obstack_finish (&obstack);
   }
 #endif
+#ifdef LINK_EH_SPEC
+  /* Prepend LINK_EH_SPEC to whatever link_spec we had before.  */
+  obstack_grow (&obstack, LINK_EH_SPEC, sizeof(LINK_EH_SPEC) - 1);
+  obstack_grow0 (&obstack, link_spec, strlen (link_spec));
+  link_spec = obstack_finish (&obstack);
+#endif
 
   specs = sl;
 }
@@ -1765,7 +1780,7 @@ load_specs (filename)
 
    A suffix which starts with `*' is a definition for
    one of the machine-specific sub-specs.  The "suffix" should be
-   *asm, *cc1, *cpp, *link, *startfile, *signed_char, etc.
+   *asm, *cc1, *cpp, *link, *startfile, etc.
    The corresponding spec is stored in asm_spec, etc.,
    rather than in the `compilers' vector.
 
@@ -1853,8 +1868,9 @@ read_specs (filename, main_p)
            {
              int name_len;
              struct spec_list *sl;
+             struct spec_list *newsl;
 
-             /* Get original name */
+             /* Get original name */
              p1 += sizeof "%rename";
              while (*p1 == ' ' || *p1 == '\t')
                p1++;
@@ -1900,6 +1916,11 @@ read_specs (filename, main_p)
              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'",
+                   filename, p1, p2);
+
              if (verbose_flag)
                {
                  notice ("rename spec %s to %s\n", p1, p2);
@@ -2321,7 +2342,7 @@ make_relative_prefix (progname, bin_prefix, prefix)
     {
       char *temp;
 
-      GET_ENV_PATH_LIST (temp, "PATH");
+      GET_ENVIRONMENT (temp, "PATH");
       if (temp)
        {
          char *startp, *endp, *nstore;
@@ -2733,11 +2754,11 @@ execute ()
        {
          const char *const *j;
 
-         if (verbose_only_flag)
-           {
+         if (verbose_only_flag)
+           {
              for (j = commands[i].argv; *j; j++)
                {
-                 char *p;
+                 const char *p;
                  fprintf (stderr, " \"");
                  for (p = *j; *p; ++p)
                    {
@@ -2747,8 +2768,8 @@ execute ()
                    }
                  fputc ('"', stderr);
                }
-           }
-         else
+           }
+         else
            for (j = commands[i].argv; *j; j++)
              fprintf (stderr, " %s", *j);
 
@@ -2759,7 +2780,7 @@ execute ()
        }
       fflush (stderr);
       if (verbose_only_flag != 0)
-        return 0;
+       return 0;
 #ifdef DEBUG
       notice ("\nGo ahead? (y or n) ");
       fflush (stderr);
@@ -2943,9 +2964,6 @@ const char **outfiles;
 /* Used to track if none of the -B paths are used.  */
 static int warn_B;
 
-/* Used to track if standard path isn't used and -b or -V is specified.  */
-static int warn_std;
-
 /* Gives value to pass as "warn" to add_prefix for standard prefixes.  */
 static int *warn_std_ptr = 0;
 \f
@@ -3037,7 +3055,7 @@ display_help ()
   fputs (_("  -save-temps              Do not delete intermediate files\n"), stdout);
   fputs (_("  -pipe                    Use pipes rather than intermediate files\n"), stdout);
   fputs (_("  -time                    Time the execution of each subprocess\n"), stdout);
-  fputs (_("  -specs=<file>            Override builtin specs with the contents of <file>\n"), stdout);
+  fputs (_("  -specs=<file>            Override built-in specs with the contents of <file>\n"), stdout);
   fputs (_("  -std=<standard>          Assume that the input sources are for <standard>\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);
@@ -3051,7 +3069,7 @@ display_help ()
   fputs (_("\
   -x <language>            Specify the language of the following input files\n\
                            Permissable languages include: c c++ assembler none\n\
-                           'none' means revert to the default behaviour of\n\
+                           'none' means revert to the default behavior of\n\
                            guessing the language based on the file's extension\n\
 "), stdout);
 
@@ -3141,7 +3159,7 @@ process_command (argc, argv)
   int j;
 #endif
 
-  GET_ENV_PATH_LIST (gcc_exec_prefix, "GCC_EXEC_PREFIX");
+  GET_ENVIRONMENT (gcc_exec_prefix, "GCC_EXEC_PREFIX");
 
   n_switches = 0;
   n_infiles = 0;
@@ -3160,6 +3178,61 @@ process_command (argc, argv)
        }
     }
 
+  /* If there is a -V or -b option (or both), process it now, before
+     trying to interpret the rest of the command line.  */
+  if (argc > 1 && argv[1][0] == '-'
+      && (argv[1][1] == 'V' || argv[1][1] == 'b'))
+    {
+      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;
+      
+      while (argc > 1 && argv[1][0] == '-'
+            && (argv[1][1] == 'V' || argv[1][1] == 'b'))
+       {
+         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 = xmemdup (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 = xmemdup (argv, (argc + 1) * sizeof (argv[0]),
+                         (argc + 1) * sizeof (argv[0]));
+      new_argv[0] = new_argv0;
+
+      execvp (new_argv0, new_argv);
+      fatal ("couldn't run `%s': %s", new_argv0, xstrerror (errno));
+    }
+
   /* Set up the default search paths.  If there is no GCC_EXEC_PREFIX,
      see if we can create it from the pathname specified in argv[0].  */
 
@@ -3199,7 +3272,7 @@ process_command (argc, argv)
   /* COMPILER_PATH and LIBRARY_PATH have values
      that are lists of directory names with colons.  */
 
-  GET_ENV_PATH_LIST (temp, "COMPILER_PATH");
+  GET_ENVIRONMENT (temp, "COMPILER_PATH");
   if (temp)
     {
       const char *startp, *endp;
@@ -3234,7 +3307,7 @@ process_command (argc, argv)
        }
     }
 
-  GET_ENV_PATH_LIST (temp, LIBRARY_PATH_ENV);
+  GET_ENVIRONMENT (temp, LIBRARY_PATH_ENV);
   if (temp && *cross_compile == '0')
     {
       const char *startp, *endp;
@@ -3267,7 +3340,7 @@ process_command (argc, argv)
     }
 
   /* Use LPATH like LIBRARY_PATH (for the CMU build program).  */
-  GET_ENV_PATH_LIST (temp, "LPATH");
+  GET_ENVIRONMENT (temp, "LPATH");
   if (temp && *cross_compile == '0')
     {
       const char *startp, *endp;
@@ -3307,7 +3380,6 @@ process_command (argc, 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.
-     Also parse any switches that determine the configuration name, such as -b.
      Here we also parse the switches that cc itself uses (e.g. -v).  */
 
   for (i = 1; i < argc; i++)
@@ -3332,6 +3404,17 @@ process_command (argc, argv)
          printf ("%s\n", spec_machine);
          exit (0);
        }
+      else if (strcmp (argv[i], "-fversion") == 0)
+       {
+         /* translate_options () has turned --version into -fversion.  */
+         printf (_("%s (GCC) %s\n"), programname, version_string);
+         fputs (_("Copyright (C) 2002 Free Software Foundation, Inc.\n"),
+                stdout);
+         fputs (_("This is free software; see the source for copying conditions.  There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
+                stdout);
+         exit (0);
+       }
       else if (strcmp (argv[i], "-fhelp") == 0)
        {
          /* translate_options () has turned --help into -fhelp.  */
@@ -3348,20 +3431,20 @@ process_command (argc, argv)
          add_linker_option ("--help", 6);
        }
       else if (strcmp (argv[i], "-ftarget-help") == 0)
-        {
-          /* translate_options() has turned --target-help into -ftarget-help.  */
-          target_help_flag = 1;
+       {
+         /* translate_options() has turned --target-help into -ftarget-help.  */
+         target_help_flag = 1;
 
-          /* We will be passing a dummy file on to the sub-processes.  */
-          n_infiles++;
-          n_switches++;
+         /* 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);
-        }
+         add_assembler_option ("--target-help", 13);
+         add_linker_option ("--target-help", 13);
+       }
       else if (! strcmp (argv[i], "-pass-exit-codes"))
        {
          pass_exit_codes = 1;
@@ -3495,15 +3578,8 @@ process_command (argc, argv)
          switch (c)
            {
            case 'b':
-             n_switches++;
-             if (p[1] == 0 && i + 1 == argc)
-               fatal ("argument to `-b' is missing");
-             if (p[1] == 0)
-               spec_machine = argv[++i];
-             else
-               spec_machine = p + 1;
-
-             warn_std_ptr = &warn_std;
+           case 'V':
+             fatal ("`-%c' must come at the start of the command line", c);
              break;
 
            case 'B':
@@ -3536,7 +3612,7 @@ process_command (argc, argv)
                    tmp[++ len] = 0;
                    value = tmp;
                  }
-               
+
                /* As a kludge, if the arg is "[foo/]stageN/", just
                   add "[foo/]include" to the include prefix.  */
                if ((len == 7
@@ -3579,48 +3655,6 @@ process_command (argc, argv)
              verbose_flag++;
              break;
 
-           case 'V':
-             n_switches++;
-             if (p[1] == 0 && i + 1 == argc)
-               fatal ("argument to `-V' is missing");
-             if (p[1] == 0)
-               spec_version = argv[++i];
-             else
-               spec_version = p + 1;
-             compiler_version = spec_version;
-             warn_std_ptr = &warn_std;
-
-             /* Validate the version number.  Use the same checks
-                done when inserting it into a spec.
-
-                The format of the version string is
-                ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)?  */
-             {
-               const char *v = compiler_version;
-
-               /* Ignore leading non-digits.  i.e. "foo-" in "foo-2.7.2".  */
-               while (! ISDIGIT (*v))
-                 v++;
-
-               if (v > compiler_version && v[-1] != '-')
-                 fatal ("invalid version number format");
-
-               /* Set V after the first period.  */
-               while (ISDIGIT (*v))
-                 v++;
-
-               if (*v != '.')
-                 fatal ("invalid version number format");
-
-               v++;
-               while (ISDIGIT (*v))
-                 v++;
-
-               if (*v != 0 && *v != ' ' && *v != '.' && *v != '-')
-                 fatal ("invalid version number format");
-             }
-             break;
-
            case 'S':
            case 'c':
              if (p[1] == 0)
@@ -3676,8 +3710,7 @@ process_command (argc, argv)
 #ifdef MODIFY_TARGET_NAME
              is_modify_target_name = 0;
 
-             for (j = 0;
-                  j < sizeof modify_target / sizeof modify_target[0]; j++)
+             for (j = 0; j < ARRAY_SIZE (modify_target); j++)
                if (! strcmp (argv[i], modify_target[j].sw))
                  {
                    char *new_name
@@ -3710,7 +3743,7 @@ process_command (argc, argv)
 
              if (is_modify_target_name)
                break;
-#endif               
+#endif
 
              n_switches++;
 
@@ -3812,7 +3845,7 @@ process_command (argc, argv)
 #ifdef MODIFY_TARGET_NAME
       is_modify_target_name = 0;
 
-      for (j = 0; j < sizeof modify_target / sizeof modify_target[0]; j++)
+      for (j = 0; j < ARRAY_SIZE (modify_target); j++)
        if (! strcmp (argv[i], modify_target[j].sw))
          is_modify_target_name = 1;
 
@@ -3900,7 +3933,7 @@ process_command (argc, argv)
          /* -save-temps overrides -pipe, so that temp files are produced */
          if (save_temps_flag)
            error ("warning: -pipe ignored because -save-temps specified");
-          /* -time overrides -pipe because we can't get correct stats when
+         /* -time overrides -pipe because we can't get correct stats when
             multiple children are running at once.  */
          else if (report_times)
            error ("warning: -pipe ignored because -time specified");
@@ -3979,7 +4012,7 @@ process_command (argc, argv)
          else
            {
              char ch = switches[n_switches].part1[0];
-             if (ch == 'V' || ch == 'b' || ch == 'B')
+             if (ch == 'B')
                switches[n_switches].validated = 1;
            }
          n_switches++;
@@ -4155,15 +4188,7 @@ do_spec (spec)
 {
   int value;
 
-  clear_args ();
-  arg_going = 0;
-  delete_this_arg = 0;
-  this_is_output_file = 0;
-  this_is_library_file = 0;
-  input_from_pipe = 0;
-  suffix_subst = NULL;
-
-  value = do_spec_1 (spec, 0, NULL);
+  value = do_spec_2 (spec);
 
   /* Force out any unfinished command.
      If -pipe, this forces out the last command if it ended in `|'.  */
@@ -4181,6 +4206,21 @@ do_spec (spec)
   return value;
 }
 
+static int
+do_spec_2 (spec)
+     const char *spec;
+{
+  clear_args ();
+  arg_going = 0;
+  delete_this_arg = 0;
+  this_is_output_file = 0;
+  this_is_library_file = 0;
+  input_from_pipe = 0;
+  suffix_subst = NULL;
+
+  return do_spec_1 (spec, 0, NULL);
+}
+
 /* Process the sub-spec SPEC as a portion of a larger spec.
    This is like processing a whole spec except that we do
    not initialize at the beginning and we do not supply a
@@ -4509,7 +4549,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
                      }
                    suffix_length += strlen (TARGET_OBJECT_SUFFIX);
                  }
-               
+
                /* If the 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
@@ -4517,7 +4557,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
                   gcc -save-temps foo.s would clobber foo.s with the
                   output of cpp0).  So check for this condition and
                   generate a temp file as the intermediate.  */
-                  
+
                if (save_temps_flag)
                  {
                    temp_filename_length = basename_length + suffix_length;
@@ -4529,7 +4569,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
                    if (strcmp (temp_filename, input_filename) != 0)
                      {
                        struct stat st_temp;
-                       
+
                        /* Note, set_input() resets input_stat_set to 0.  */
                        if (input_stat_set == 0)
                          {
@@ -4537,17 +4577,17 @@ do_spec_1 (spec, inswitch, soft_matched_part)
                            if (input_stat_set >= 0)
                              input_stat_set = 1;
                          }
-                         
+
                        /* If we have the stat for the 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.  */
-                       
+
                        if (input_stat_set != 1
                            || stat (temp_filename, &st_temp) < 0
                            || input_stat.st_dev != st_temp.st_dev
                            || input_stat.st_ino != st_temp.st_ino)
-                         {
+                         {
                            temp_filename = save_string (temp_filename,
                                                         temp_filename_length + 1);
                            obstack_grow (&obstack, temp_filename,
@@ -4752,17 +4792,11 @@ do_spec_1 (spec, inswitch, soft_matched_part)
              return value;
            break;
 
-         case 'c':
-           value = do_spec_1 (signed_char_spec, 0, NULL);
-           if (value != 0)
-             return value;
-           break;
-
          case 'C':
            {
              const char *const spec
-               = (input_file_compiler->cpp_spec 
-                  ? input_file_compiler->cpp_spec 
+               = (input_file_compiler->cpp_spec
+                  ? input_file_compiler->cpp_spec
                   : cpp_spec);
              value = do_spec_1 (spec, 0, NULL);
              if (value != 0)
@@ -4990,17 +5024,17 @@ do_spec_1 (spec, inswitch, soft_matched_part)
            obstack_1grow (&obstack, '%');
            break;
 
-         case '.':
-          {
-            unsigned len = 0;
+         case '.':
+           {
+             unsigned len = 0;
 
-            while (p[len] && p[len] != ' ' && p[len] != '%')
-              len++;
-             suffix_subst = save_string (p - 1, len + 1);
-             p += len;
-           }
+             while (p[len] && p[len] != ' ' && p[len] != '%')
+               len++;
+             suffix_subst = save_string (p - 1, len + 1);
+             p += len;
+           }
           break;
-          
+
          case '*':
            if (soft_matched_part)
              {
@@ -5011,7 +5045,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
              /* Catch the case where a spec string contains something like
                 '%{foo:%*}'.  ie there is no * in the pattern on the left
                 hand side of the :.  */
-             error ("spec failure: '%%*' has not been initialised 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.
@@ -5163,7 +5197,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
            break;
 
          default:
-           error ("spec failure: unrecognised spec option '%c'", c);
+           error ("spec failure: unrecognized spec option '%c'", c);
            break;
          }
        break;
@@ -5699,7 +5733,7 @@ set_input (filename)
     }
   else
     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
      INPUT_STAT_SET signals that the stat is needed.  */
@@ -5866,8 +5900,10 @@ main (argc, argv)
   if (access (specs_file, R_OK) == 0)
     read_specs (specs_file, TRUE);
 
-  /* If not cross-compiling, look for startfiles in the standard places.  */
-  if (*cross_compile == '0')
+  /* If not cross-compiling, look for startfiles in the standard places.
+     Similarly, don't add the standard prefixes if startfile handling
+     will be under control of startfile_prefix_spec.  */
+  if (*cross_compile == '0' && *startfile_prefix_spec == 0)
     {
       if (*md_exec_prefix)
        {
@@ -5925,6 +5961,16 @@ main (argc, argv)
                    "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL);
     }
 
+  if (*startfile_prefix_spec != 0
+      && do_spec_2 (startfile_prefix_spec) == 0
+      && do_spec_1 (" ", 0, NULL) == 0)
+    {
+      int ndx;
+      for (ndx = 0; ndx < argbuf_index; ndx++)
+       add_prefix (&startfile_prefixes, argbuf[ndx], "BINUTILS",
+                   PREFIX_PRIORITY_LAST, 0, NULL);
+    }
+
   /* Process any user specified specs in the order given on the command
      line.  */
   for (uptr = user_specs_head; uptr; uptr = uptr->next)
@@ -5993,7 +6039,7 @@ main (argc, argv)
 
   if (target_help_flag)
    {
-      /* Print if any target specific options.*/
+      /* Print if any target specific options.  */
 
       /* We do not exit here. Instead we have created a fake input file
          called 'target-dummy' which needs to be compiled, and we pass this
@@ -6089,7 +6135,7 @@ main (argc, argv)
       input_file_compiler
        = lookup_compiler (infiles[i].name, input_filename_length,
                           infiles[i].language);
-      
+
       if (input_file_compiler)
        {
          /* Ok, we found an applicable compiler.  Run its spec.  */
@@ -6228,7 +6274,7 @@ lookup_compiler (name, length, language)
              && !strcmp (cp->suffix,
                          name + length - strlen (cp->suffix))
         ))
-        break;
+       break;
     }
 
 #if defined (OS2) ||defined (HAVE_DOS_BASED_FILE_SYSTEM)
@@ -6371,7 +6417,7 @@ validate_all_switches ()
     {
       p = comp->spec;
       while ((c = *p++))
-       if (c == '%' && *p == '{')
+       if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
          /* We have a switch spec.  */
          validate_switches (p + 1);
     }
@@ -6381,14 +6427,14 @@ validate_all_switches ()
     {
       p = *(spec->ptr_spec);
       while ((c = *p++))
-       if (c == '%' && *p == '{')
+       if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
          /* We have a switch spec.  */
          validate_switches (p + 1);
     }
 
   p = link_command_spec;
   while ((c = *p++))
-    if (c == '%' && *p == '{')
+    if (c == '%' && (*p == '{' || (*p == 'W' && *++p == '{')))
       /* We have a switch spec.  */
       validate_switches (p + 1);
 }