OSDN Git Service

emit-rtl.c (init_emit): Clear sequence_stack.
[pf3gnuchains/gcc-fork.git] / gcc / gcc.c
index ff13c10..f50e2ec 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -144,6 +144,10 @@ static int cross_compile = 1;
 static int cross_compile = 0;
 #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;
+
 /* This is the obstack which we use to allocate many strings.  */
 
 static struct obstack obstack;
@@ -572,25 +576,28 @@ static int n_default_compilers
 #ifdef LINK_LIBGCC_SPECIAL_1
 /* Have gcc do the search for libgcc.a, but generate -L options as usual.  */
 static char *link_command_spec = "\
-%{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
+%{!fsyntax-only: \
+ %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
                        %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\
-                       %{!A:%{!nostdlib:%S}} %{static:}\
-                       %{L*} %D %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}";
+                       %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
+                       %{L*} %D %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}";
 #else
 #ifdef LINK_LIBGCC_SPECIAL
 /* Have gcc do the search for libgcc.a, and don't generate -L options.  */
 static char *link_command_spec = "\
-%{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
+%{!fsyntax-only: \
+ %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
                        %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\
-                       %{!A:%{!nostdlib:%S}} %{static:}\
-                       %{L*} %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}";
+                       %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
+                       %{L*} %o %{!nostdlib:libgcc.a%s %L libgcc.a%s %{!A:%E}}\n }}}}}}";
 #else
 /* Use -L and have the linker do the search for -lgcc.  */
 static char *link_command_spec = "\
-%{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
+%{!fsyntax-only: \
+ %{!c:%{!M:%{!MM:%{!E:%{!S:ld %l %X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} \
                        %{r} %{s} %{T*} %{t} %{u*} %{x} %{z}\
-                       %{!A:%{!nostdlib:%S}} %{static:}\
-                       %{L*} %D %o %{!nostdlib:-lgcc %L -lgcc %{!A:%E}}\n }}}}}";
+                       %{!A:%{!nostartfiles:%{!nostdlib:%S}}} %{static:}\
+                       %{L*} %D %o %{!nostdlib:-lgcc %L -lgcc %{!A:%E}}\n }}}}}}";
 #endif
 #endif
 
@@ -606,6 +613,211 @@ static char **linker_options;
 static int n_assembler_options;
 static char **assembler_options;
 \f
+/* Define how to map long options into short ones.  */
+
+/* This structure describes one mapping.  */
+struct option_map
+{
+  /* The long option's name.  */
+  char *name;
+  /* The equivalent short option.  */
+  char *equivalent;
+  /* Argument info.  A string of flag chars; NULL equals no options.
+     a => argument required.
+     o => argument optional.
+     j => join argument to equivalent, making one word.
+     * => allow other text after NAME as an argument.  */
+  char *arg_info;
+};
+
+/* This is the table of mappings.  Mappings are tried sequentially
+   for each option encountered; the first one that matches, wins.  */
+
+struct option_map option_map[] =
+ {
+   {"--profile-blocks", "-a", 0},
+   {"--target", "-b", "a"},
+   {"--compile", "-c", 0},
+   {"--dump", "-d", "a"},
+   {"--entry", "-e", 0},
+   {"--debug", "-g", "oj"},
+   {"--include", "-include", "a"},
+   {"--imacros", "-imacros", "a"},
+   {"--include-prefix", "-iprefix", "a"},
+   {"--include-directory-after", "-idirafter", "a"},
+   {"--include-with-prefix", "-iwithprefix", "a"},
+   {"--machine-", "-m", "*j"},
+   {"--machine", "-m", "aj"},
+   {"--no-standard-includes", "-nostdinc", 0},
+   {"--no-standard-libraries", "-nostdlib", 0},
+   {"--no-precompiled-includes", "-noprecomp", 0},
+   {"--output", "-o", "a"},
+   {"--profile", "-p", 0},
+   {"--quiet", "-q", 0},
+   {"--silent", "-q", 0},
+   {"--force-link", "-u", "a"},
+   {"--verbose", "-v", 0},
+   {"--no-warnings", "-w", 0},
+   {"--language", "-x", "a"},
+
+   {"--assert", "-A", "a"},
+   {"--prefix", "-B", "a"},
+   {"--comments", "-C", 0},
+   {"--define-macro", "-D", "a"},
+   {"--preprocess", "-E", 0},
+   {"--trace-includes", "-H", 0},
+   {"--include-directory", "-I", "a"},
+   {"--include-barrier", "-I-", 0},
+   {"--library-directory", "-L", "a"},
+   {"--dependencies", "-M", 0},
+   {"--user-dependencies", "-MM", 0},
+   {"--write-dependencies", "-MD", 0},
+   {"--write-user-dependencies", "-MMD", 0},
+   {"--optimize", "-O", "oj"},
+   {"--no-line-commands", "-P", 0},
+   {"--assemble", "-S", 0},
+   {"--undefine-macro", "-U", "a"},
+   {"--version", "-V", "a"},
+   {"--for-assembler", "-Wa", "a"},
+   {"--extra-warnings", "-W", 0},
+   {"--all-warnings", "-Wall", 0},
+   {"--warn-", "-W", "*j"},
+   {"--for-linker", "-Xlinker", "a"},
+
+   {"--ansi", "-ansi", 0},
+   {"--traditional", "-traditional", 0},
+   {"--traditional-cpp", "-traditional-cpp", 0},
+   {"--trigraphs", "-trigraphs", 0},
+   {"--pipe", "-pipe", 0},
+   {"--dumpbase", "-dumpbase", "a"},
+   {"--pedantic", "-pedantic", 0},
+   {"--pedantic-errors", "-pedantic-errors", 0},
+   {"--save-temps", "-save-temps", 0},
+   {"--print-libgcc-file-name", "-print-libgcc-file-name", 0},
+   {"--static", "-static", 0},
+   {"--shared", "-shared", 0},
+   {"--symbolic", "-symbolic", 0},
+   {"--", "-f", "*j"}
+ };
+\f
+/* Translate the options described by *ARGCP and *ARGVP.
+   Make a new vector and store it back in *ARGVP,
+   and store its length in *ARGVC.  */
+
+static void
+translate_options (argcp, argvp)
+     int *argcp;
+     char ***argvp;
+{
+  int i, j;
+  int argc = *argcp;
+  char **argv = *argvp;
+  char **newv = (char **) xmalloc ((argc + 2) * 2 * sizeof (char *));
+  int newindex = 0;
+
+  i = 0;
+  newv[newindex++] = argv[i++];
+
+  while (i < argc)
+    {
+      /* Translate -- options.  */
+      if (argv[i][0] == '-' && argv[i][1] == '-')
+       {
+         /* Find a mapping that applies to this option.  */
+         for (j = 0; j < sizeof (option_map) / sizeof (option_map[0]); j++)
+           {
+             int optlen = strlen (option_map[j].name);
+             int complen = strlen (argv[i]);
+             if (complen > optlen)
+               complen = optlen;
+             if (!strncmp (argv[i], option_map[j].name, complen))
+               {
+                 int extra = strlen (argv[i]) > optlen;
+                 char *arg = 0;
+
+                 if (extra)
+                   {
+                     /* If the option has an argument, accept that.  */
+                     if (argv[i][optlen] == '=')
+                       arg = argv[i] + optlen + 1;
+                     /* If this mapping allows extra text at end of name,
+                        accept that as "argument".  */
+                     else if (index (option_map[j].arg_info, '*') != 0)
+                       arg = argv[i] + optlen;
+                     /* Otherwise, extra text at end means mismatch.
+                        Try other mappings.  */
+                     else
+                       continue;
+                   }
+                 else if (index (option_map[j].arg_info, '*') != 0)
+                   error ("Incomplete `%s' option", option_map[j].name);
+
+                 /* Handle arguments.  */
+                 if (index (option_map[j].arg_info, 'o') != 0)
+                   {
+                     if (arg == 0)
+                       {
+                         if (i + 1 == argc)
+                           error ("Missing argument to `%s' option",
+                                  option_map[j].name);
+                         arg = argv[++i];
+                       }
+                   }
+                 else if (index (option_map[j].arg_info, 'a') == 0)
+                   {
+                     if (arg != 0)
+                       error ("Extraneous argument to `%s' option",
+                              option_map[j].name);
+                     arg = 0;
+                   }
+
+                 /* Store the translation as one argv elt or as two.  */
+                 if (arg != 0 && index (option_map[j].arg_info, 'j') != 0)
+                   newv[newindex++] = concat (option_map[j].equivalent,
+                                              arg, "");
+                 else if (arg != 0)
+                   {
+                     newv[newindex++] = option_map[j].equivalent;
+                     newv[newindex++] = arg;
+                   }
+                 else
+                   newv[newindex++] = option_map[j].equivalent;
+
+                 break;
+               }
+           }
+         i++;
+       }
+      /* Handle old-fashioned options--just copy them through,
+        with their arguments.  */
+      else if (argv[i][0] == '-')
+       {
+         char *p = argv[i] + 1;
+         int c = *p;
+         int nskip = 1;
+
+         if (SWITCH_TAKES_ARG (c) > (p[1] != 0))
+           nskip += SWITCH_TAKES_ARG (c) - (p[1] != 0);
+         else if (WORD_SWITCH_TAKES_ARG (p))
+           nskip += WORD_SWITCH_TAKES_ARG (p);
+
+         while (nskip > 0)
+           {
+             newv[newindex++] = argv[i++];
+             nskip--;
+           }
+       }
+      else
+       /* Ordinary operands, or +e options.  */
+       newv[newindex++] = argv[i++];
+    }
+
+  newv[newindex] = 0;
+
+  *argvp = newv;
+  *argcp = newindex;
+}
+\f
 /* Read compilation specs from a file named FILENAME,
    replacing the default ones.
 
@@ -937,10 +1149,10 @@ static char *standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
 static char *standard_startfile_prefix_1 = "/lib/";
 static char *standard_startfile_prefix_2 = "/usr/lib/";
 
-#ifndef TOOLDIR_PREFIX
-#define TOOLDIR_PREFIX "/usr/local/"
+#ifndef TOOLDIR_BASE_PREFIX
+#define TOOLDIR_BASE_PREFIX "/usr/local/"
 #endif
-static char *tooldir_base_prefix = TOOLDIR_PREFIX;
+static char *tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
 static char *tooldir_prefix;
 
 /* Clear out the vector of arguments (after a command is executed).  */
@@ -1955,6 +2167,9 @@ process_command (argc, argv)
        }
     }
 
+  /* Convert new-style -- options to old-style.  */
+  translate_options (&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.
      Here we also parse the switches that cc itself uses (e.g. -v).  */
@@ -2067,7 +2282,7 @@ process_command (argc, argv)
          assembler_options[n_assembler_options - 1] = argv[i] + prev;
        }
       else if (argv[i][0] == '+' && argv[i][1] == 'e')
-       /* Compensate for the +e options to the C++ front-end.  */
+       /* The +e options to the C++ front-end.  */
        n_switches++;
       else if (argv[i][0] == '-' && argv[i][1] != 0 && argv[i][1] != 'l')
        {
@@ -2204,7 +2419,7 @@ process_command (argc, argv)
       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-compatability.  We do
+            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.  */
@@ -2279,8 +2494,17 @@ process_command (argc, argv)
        }
       else
        {
-         infiles[n_infiles].language = spec_lang;
-         infiles[n_infiles++].name = argv[i];
+         if ((argv[i][0] != '-' || argv[i][1] != 'l')
+             && access (argv[i], R_OK) < 0)
+           {
+             perror_with_name (argv[i]);
+             error_count++;
+           }
+         else
+           {
+             infiles[n_infiles].language = spec_lang;
+             infiles[n_infiles++].name = argv[i];
+           }
        }
     }
 
@@ -3354,12 +3578,14 @@ main (argc, argv)
   register int i;
   int j;
   int value;
-  int error_count = 0;
   int linker_was_run = 0;
   char *explicit_link_files;
   char *specs_file;
+  char *p;
 
-  programname = argv[0];
+  p = argv[0] + strlen (argv[0]);
+  while (p != argv[0] && p[-1] != '/') --p;
+  programname = p;
 
   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
     signal (SIGINT, fatal_error);
@@ -3378,10 +3604,11 @@ main (argc, argv)
   obstack_init (&obstack);
 
   /* Set up to remember the pathname of gcc and any options
-     needed for collect.  */
+     needed for collect.  We use argv[0] instead of programname because
+     we need the complete pathname.  */
   obstack_init (&collect_obstack);
   obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=")-1);
-  obstack_grow (&collect_obstack, programname, strlen (programname)+1);
+  obstack_grow (&collect_obstack, argv[0], strlen (argv[0])+1);
   putenv (obstack_finish (&collect_obstack));
 
   /* Choose directory for temp files.  */