OSDN Git Service

* function.c (assign_parms): For a struct value address passed as
[pf3gnuchains/gcc-fork.git] / gcc / gcc.c
index dea12aa..37f8b2c 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, 2002 Free Software Foundation, Inc.
+   1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -202,7 +202,15 @@ static int report_times;
 /* Nonzero means place this string before uses of /, so that include
    and library files can be found in an alternate location.  */
 
+#ifdef TARGET_SYSTEM_ROOT
 static const char *target_system_root = TARGET_SYSTEM_ROOT;
+#else
+static const char *target_system_root = 0;
+#endif
+
+/* Nonzero means pass the updated target_system_root to the compiler.  */
+
+static int target_system_root_changed;
 
 /* Nonzero means write "temp" files in source directory
    and use the source file's name in them, and don't delete them.  */
@@ -421,6 +429,7 @@ or with constant text in a single argument.
  %w    marks the argument containing or following the %w as the
        "output file" of this compilation.  This puts the argument
        into the sequence of arguments that %o will substitute later.
+ %V    indicates that this compilation produces no "output file".
  %W{...}
        like %{...} but mark last argument supplied within
        as a file to be deleted on failure.
@@ -444,7 +453,9 @@ or with constant text in a single argument.
  %P    like %p, but puts `__' before and after the name of each macro.
        (Except macros that already have __.)
        This is for ANSI C.
- %I    Substitute a -iprefix option made from GCC_EXEC_PREFIX.
+ %I    Substitute any of -iprefix (made from GCC_EXEC_PREFIX), -isysroot
+       (made from TARGET_SYSTEM_ROOT), and -isystem (made from COMPILER_PATH
+       and -B options) as necessary.
  %s     current argument is the name of a library or startup file of some sort.
         Search for that file in a standard list of directories
        and substitute the full name found.
@@ -455,12 +466,6 @@ or with constant text in a single argument.
  %X    Output the accumulated linker options specified by compilations.
  %Y    Output the accumulated assembler options specified by compilations.
  %Z    Output the accumulated preprocessor options specified by compilations.
- %v1   Substitute the major version number of GCC.
-       (For version 2.5.3, this is 2.)
- %v2   Substitute the minor version number of GCC.
-       (For version 2.5.3, this is 5.)
- %v3   Substitute the patch level number of GCC.
-       (For version 2.5.3, this is 3.)
  %a     process ASM_SPEC as a spec.
         This allows config.h to specify part of the spec for running as.
  %A    process ASM_FINAL_SPEC as a spec.  A capital A is actually
@@ -675,7 +680,8 @@ 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:%(link_gcc_c_sequence)}}\
+    %{static:} %{L*} %(link_libgcc) %o %{fprofile-arcs:-lgcov}\
+    %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
     %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
 #endif
 
@@ -728,14 +734,12 @@ 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:%{!E:%eGNU C does not support -C without using -E}}\
- %{CC:%{!E:%eGNU C does not support -CC without using -E}}\
+"%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}}\
  %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*} %{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:%{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}\
  %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
  %{E|M|MM:%W{o*}}";
@@ -807,30 +811,10 @@ struct user_specs
 
 static struct user_specs *user_specs_head, *user_specs_tail;
 
-/* This defines which switch letters take arguments.  */
-
-#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \
-  ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \
-   || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \
-   || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x' \
-   || (CHAR) == 'L' || (CHAR) == 'A' || (CHAR) == 'B' || (CHAR) == 'b')
-
 #ifndef SWITCH_TAKES_ARG
 #define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR)
 #endif
 
-/* This defines which multi-letter switches take arguments.  */
-
-#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR)             \
- (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext")     \
-  || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \
-  || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \
-  || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \
-  || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \
-  || !strcmp (STR, "isystem") || !strcmp (STR, "-param") \
-  || !strcmp (STR, "specs") \
-  || !strcmp (STR, "MF") || !strcmp (STR, "MT") || !strcmp (STR, "MQ"))
-
 #ifndef WORD_SWITCH_TAKES_ARG
 #define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR)
 #endif
@@ -886,7 +870,7 @@ static const struct compiler default_compilers[] =
   {".m",  "#Objective-C", 0}, {".mi",  "#Objective-C", 0},
   {".cc", "#C++", 0}, {".cxx", "#C++", 0}, {".cpp", "#C++", 0},
   {".cp", "#C++", 0}, {".c++", "#C++", 0}, {".C", "#C++", 0},
-  {".ii", "#C++", 0},
+  {".CPP", "#C++", 0}, {".ii", "#C++", 0},
   {".ads", "#Ada", 0}, {".adb", "#Ada", 0},
   {".f", "#Fortran", 0}, {".for", "#Fortran", 0}, {".fpp", "#Fortran", 0},
   {".F", "#Fortran", 0}, {".FOR", "#Fortran", 0}, {".FPP", "#Fortran", 0},
@@ -903,20 +887,30 @@ static const struct compiler default_compilers[] =
       %{!E:%{!M:%{!MM:\
           %{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-cpp:\
-               cc1 %(cpp_unique_options) %(cc1_options)}}\
+         %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \
+               %(cpp_options) %{save-temps:%b.i} %{!save-temps:%g.i} \n\
+                   cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} %(cc1_options)}\
+         %{!save-temps:%{!traditional-cpp:%{!no-integrated-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) %(cpp_options) %(cpp_debug_options)", 0},
   {".h", "@c-header", 0},
   {"@c-header",
-   "%{!E:%ecompilation of header file requested} \
-    %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)",
-   0},
+   /* cc1 has an integrated ISO C preprocessor.  We should invoke the
+      external preprocessor if -save-temps is given.  */
+     "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\
+      %{!E:%{!M:%{!MM:\
+         %{save-temps|traditional-cpp:%(trad_capable_cpp) \
+               %(cpp_options) %b.i \n\
+                   cc1 -fpreprocessed %b.i %(cc1_options)\
+                        -o %g.s %{!o*:--output-pch=%i.gch}\
+                        %W{o*:--output-pch=%*}%V}\
+         %{!save-temps:%{!traditional-cpp:\
+               cc1 %(cpp_unique_options) %(cc1_options)\
+                    -o %g.s %{!o*:--output-pch=%i.gch}\
+                    %W{o*:--output-pch=%*}%V}}}}}", 0},
   {".i", "@cpp-output", 0},
   {"@cpp-output",
    "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0},
@@ -1020,6 +1014,7 @@ static const struct option_map option_map[] =
    {"--library-directory", "-L", "a"},
    {"--machine", "-m", "aj"},
    {"--machine-", "-m", "*j"},
+   {"--no-integrated-cpp", "-no-integrated-cpp", 0},
    {"--no-line-commands", "-P", 0},
    {"--no-precompiled-includes", "-noprecomp", 0},
    {"--no-standard-includes", "-nostdinc", 0},
@@ -2528,7 +2523,7 @@ enum path_prefix_priority
   PREFIX_PRIORITY_LAST
 };
 
-/* Add an entry for PREFIX in PLIST.  The PLIST is kept in assending
+/* Add an entry for PREFIX in PLIST.  The PLIST is kept in ascending
    order according to PRIORITY.  Within each PRIORITY, new entries are
    appended.
 
@@ -2724,7 +2719,7 @@ execute ()
     }
 
 #ifdef ENABLE_VALGRIND_CHECKING
-  /* Run the each command through valgrind.  To simplifiy prepending the
+  /* Run the each command through valgrind.  To simplify prepending the
      path to valgrind and the option "-q" (for quiet operation unless
      something triggers), we allocate a separate argv array.  */
 
@@ -3818,14 +3813,23 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
              concat (tooldir_prefix, "lib", dir_separator_str, NULL),
              "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
 
+#if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
+  /* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
+     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)
     {
       char *tmp_prefix = make_relative_prefix (argv[0],
                                               standard_bindir_prefix,
                                               target_system_root);
       if (tmp_prefix && access_check (tmp_prefix, F_OK) == 0)
-       target_system_root = tmp_prefix;
+       {
+         target_system_root = tmp_prefix;
+         target_system_root_changed = 1;
+       }
     }
+#endif
 
   /* More prefixes are enabled in main, after we read the specs file
      and determine whether this is cross-compilation or not.  */
@@ -4216,6 +4220,9 @@ static int
 do_spec_2 (spec)
      const char *spec;
 {
+  const char *string;
+  int result;
+
   clear_args ();
   arg_going = 0;
   delete_this_arg = 0;
@@ -4224,7 +4231,22 @@ do_spec_2 (spec)
   input_from_pipe = 0;
   suffix_subst = NULL;
 
-  return do_spec_1 (spec, 0, NULL);
+  result = do_spec_1 (spec, 0, NULL);
+
+  /* End any pending argument.  */
+  if (arg_going)
+    {
+      obstack_1grow (&obstack, 0);
+      string = obstack_finish (&obstack);
+      if (this_is_library_file)
+       string = find_file (string);
+      store_arg (string, delete_this_arg, this_is_output_file);
+      if (this_is_output_file)
+       outfiles[input_file_number] = string;
+      arg_going = 0;
+    }
+
+  return result;
 }
 
 
@@ -4679,7 +4701,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
                for (t = temp_names; t; t = t->next)
                  if (t->length == suffix_length
                      && strncmp (t->suffix, suffix, suffix_length) == 0
-                     && t->unique == (c == 'u' || c == 'j'))
+                     && t->unique == (c == 'u' || c == 'U' || c == 'j'))
                    break;
 
                /* Make a new association if needed.  %u and %j
@@ -4700,7 +4722,7 @@ do_spec_1 (spec, inswitch, soft_matched_part)
                      }
                    else
                      t->suffix = save_string (suffix, suffix_length);
-                   t->unique = (c == 'u' || c == 'j');
+                   t->unique = (c == 'u' || c == 'U' || c == 'j');
                    temp_filename = make_temp_file (t->suffix);
                    temp_filename_length = strlen (temp_filename);
                    t->filename = temp_filename;
@@ -4734,6 +4756,15 @@ do_spec_1 (spec, inswitch, soft_matched_part)
                  do_spec_1 (" ", 0, NULL);
                }
 
+             if (target_system_root_changed)
+               {
+                 do_spec_1 ("-isysroot", 1, NULL);
+                 /* Make this a separate argument.  */
+                 do_spec_1 (" ", 0, NULL);
+                 do_spec_1 (target_system_root, 1, NULL);
+                 do_spec_1 (" ", 0, NULL);
+               }
+
              for (; pl; pl = pl->next)
                {
                  do_spec_1 ("-isystem", 1, NULL);
@@ -4765,6 +4796,10 @@ do_spec_1 (spec, inswitch, soft_matched_part)
            this_is_library_file = 1;
            break;
 
+         case 'V':
+           outfiles[input_file_number] = NULL;
+           break;
+
          case 'w':
            this_is_output_file = 1;
            break;
@@ -5262,63 +5297,6 @@ do_spec_1 (spec, inswitch, soft_matched_part)
            }
            break;
 
-         case 'v':
-           {
-             int c1 = *p++;  /* Select first or second version number.  */
-             const char *v = compiler_version;
-             const char *q;
-             static const char zeroc = '0';
-
-             /* The format of the version string is
-                ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)?  */
-
-             /* Ignore leading non-digits.  i.e. "foo-" in "foo-2.7.2".  */
-             while (! ISDIGIT (*v))
-               v++;
-             if (v > compiler_version && v[-1] != '-')
-               abort ();
-
-             /* If desired, advance to second version number.  */
-             if (c1 >= '2')
-               {
-                 /* Set V after the first period.  */
-                 while (ISDIGIT (*v))
-                   v++;
-                 if (*v != '.')
-                   abort ();
-                 v++;
-               }
-
-             /* If desired, advance to third version number.
-                 But don't complain if it's not present */
-             if (c1 == '3')
-               {
-                 /* Set V after the second period.  */
-                 while (ISDIGIT (*v))
-                   v++;
-                 if ((*v != 0) && (*v != ' ') && (*v != '.') && (*v != '-'))
-                   abort ();
-                 if (*v != 0)
-                   v++;
-               }
-
-             /* Set Q at the next period or at the end.  */
-             q = v;
-             while (ISDIGIT (*q))
-               q++;
-             if (*q != 0 && q > v && *q != ' ' && *q != '.' && *q != '-')
-               abort ();
-
-             if (q > v)
-               /* Put that part into the command.  */
-               obstack_grow (&obstack, v, q - v);
-             else
-               /* Default to "0" */
-               obstack_grow (&obstack, &zeroc, 1);
-             arg_going = 1;
-           }
-           break;
-
          default:
            error ("spec failure: unrecognized spec option '%c'", c);
            break;
@@ -6079,6 +6057,7 @@ main (argc, argv)
   size_t i;
   int value;
   int linker_was_run = 0;
+  int num_linker_inputs = 0;
   char *explicit_link_files;
   char *specs_file;
   const char *p;
@@ -6182,12 +6161,6 @@ main (argc, argv)
 
   process_command (argc, argv);
 
-  /* Process DRIVER_SELF_SPECS, adding any new options to the end
-     of the command line.  */
-
-  for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
-    do_self_spec (driver_self_specs[i]);
-
   /* Initialize the vector of specs to just the default.
      This means one element containing 0s, as a terminator.  */
 
@@ -6221,6 +6194,12 @@ main (argc, argv)
   if (access (specs_file, R_OK) == 0)
     read_specs (specs_file, TRUE);
 
+  /* Process DRIVER_SELF_SPECS, adding any new options to the end
+     of the command line.  */
+
+  for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
+    do_self_spec (driver_self_specs[i]);
+
   /* If not cross-compiling, look for executables in the standard
      places.  */
   if (*cross_compile == '0')
@@ -6516,9 +6495,15 @@ main (argc, argv)
        error_count++;
     }
 
+  /* Determine if there are any linker input files.  */
+  num_linker_inputs = 0;
+  for (i = 0; (int) i < n_infiles; i++)
+    if (explicit_link_files[i] || outfiles[i] != NULL)
+      num_linker_inputs++;
+
   /* Run ld to link all the compiler output files.  */
 
-  if (error_count == 0)
+  if (num_linker_inputs > 0 && error_count == 0)
     {
       int tmp = execution_count;
 
@@ -6808,11 +6793,11 @@ next_member:
          switches[i].validated = 1;
     }
 
-  p++;
-  if (p[-1] == '|' || p[-1] == '&')
+  if (*p) p++;
+  if (*p && (p[-1] == '|' || p[-1] == '&'))
     goto next_member;
 
-  if (p[-1] == ':')
+  if (*p && p[-1] == ':')
     {
       while (*p && *p != ';' && *p != '}')
        {
@@ -6824,11 +6809,12 @@ next_member:
              else if (p[0] == 'W' && p[1] == '{')
                p = validate_switches (p+2);
            }
-         p++;
+         else
+           p++;
        }
 
-      p++;
-      if (p[-1] == ';')
+      if (*p) p++;
+      if (*p && p[-1] == ';')
        goto next_member;
     }