X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgcc.c;h=de429f87c410867aebc1f07cde5ccd6a0d482e5b;hb=d4fde4e2afafd24003c45c1e9419fc42637b9586;hp=7914e4b6f35494ca7e2b4cbffe5a4e2da202632c;hpb=098cc23f66994beeede0d3c2d6be39e84c8f8deb;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/gcc.c b/gcc/gcc.c index 7914e4b6f35..de429f87c41 100644 --- 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, 2003, 2004, 2005, 2006, 2007, 2008 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -17,10 +17,7 @@ for more details. You should have received a copy of the GNU General Public License along with GCC; see the file COPYING3. If not see -. - -This paragraph is here to try to keep Sun CC from dying. -The number of chars here seems crucial!!!! */ +. */ /* This program is the user interface to the C compiler and possibly to other compilers. It is used because compilation is a complicated procedure @@ -221,7 +218,15 @@ static const char *target_sysroot_hdrs_suffix = 0; /* Nonzero means write "temp" files in source directory and use the source file's name in them, and don't delete them. */ -static int save_temps_flag; +static enum save_temps { + SAVE_TEMPS_NONE, /* no -save-temps */ + SAVE_TEMPS_CWD, /* -save-temps in current directory */ + SAVE_TEMPS_OBJ /* -save-temps in object directory */ +} save_temps_flag; + +/* Output file to use to get the object directory for -save-temps=obj */ +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. */ @@ -396,7 +401,8 @@ or with constant text in a single argument. %i substitute the name of the input file being processed. %b substitute the basename of the input file being processed. This is the substring up to (and not including) the last period - and not including the directory. + and not including the directory unless -save-temps was specified + to put temporaries in a different location. %B same as %b, but include the file suffix (text after the last period). %gSUFFIX substitute a file name that has suffix SUFFIX and is chosen @@ -439,7 +445,7 @@ or with constant text in a single argument. it is subsequently output with %*. SUFFIX is terminated by the next space or %. %d marks the argument containing or following the %d as a - temporary file name, so that that file will be deleted if CC exits + temporary file name, so that that file will be deleted if GCC exits successfully. Unlike %g, this contributes no text to the argument. %w marks the argument containing or following the %w as the "output file" of this compilation. This puts the argument @@ -508,12 +514,12 @@ or with constant text in a single argument. argument vector in the usual fashion. The function returns a string which is processed as if it had appeared literally as part of the current spec. - %{S} substitutes the -S switch, if that switch was given to CC. + %{S} substitutes the -S switch, if that switch was given to GCC. If that switch was not specified, this substitutes nothing. Here S is a metasyntactic variable. - %{S*} substitutes all the switches specified to CC whose names start + %{S*} substitutes all the switches specified to GCC whose names start with -S. This is used for -o, -I, etc; switches that take - arguments. CC considers `-o foo' as being one switch whose + arguments. GCC considers `-o foo' as being one switch whose name starts with `o'. %{o*} would substitute this text, including the space; thus, two arguments would be generated. %{S*&T*} likewise, but preserve order of S and T options (the order @@ -521,10 +527,10 @@ or with constant text in a single argument. of ampersand-separated variables; for each the wild card is optional. Useful for CPP as %{D*&U*&A*}. - %{S:X} substitutes X, if the -S switch was given to CC. - %{!S:X} substitutes X, if the -S switch was NOT given to CC. + %{S:X} substitutes X, if the -S switch was given to GCC. + %{!S:X} substitutes X, if the -S switch was NOT given to GCC. %{S*:X} substitutes X if one or more switches whose names start - with -S was given to CC. Normally X is substituted only + with -S was given to GCC. Normally X is substituted only once, no matter how many such switches appeared. However, if %* appears somewhere in X, then X will be substituted once for each matching switch, with the %* replaced by the @@ -534,13 +540,13 @@ or with constant text in a single argument. %{,S:X} substitutes X, if processing a file which will use spec S. %{!,S:X} substitutes X, if NOT processing a file which will use spec S. - %{S|T:X} substitutes X if either -S or -T was given to CC. This may be + %{S|T:X} substitutes X if either -S or -T was given to GCC. This may be combined with '!', '.', ',', and '*' as above binding stronger than the OR. If %* appears in X, all of the alternatives must be starred, and only the first matching alternative is substituted. - %{S:X; if S was given to CC, substitutes X; - T:Y; else if T was given to CC, substitutes Y; + %{S:X; if S was given to GCC, substitutes X; + T:Y; else if T was given to GCC, substitutes Y; :D} else substitutes D. There can be as many clauses as you need. This may be combined with '.', '!', ',', '|', and '*' as above. @@ -564,15 +570,15 @@ The character | at the beginning of the predicate text is used to indicate that a command should be piped to the following command, but only if -pipe is specified. -Note that it is built into CC which switches take arguments and which +Note that it is built into GCC which switches take arguments and which do not. You might think it would be useful to generalize this to allow each compiler's spec to say which switches take arguments. But -this cannot be done in a consistent fashion. CC cannot even decide +this cannot be done in a consistent fashion. GCC cannot even decide which input files have been specified without knowing which switches take arguments, and it must know which input files to compile in order to tell which compilers to run. -CC also knows implicitly that arguments starting in `-l' are to be +GCC 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. */ @@ -680,14 +686,14 @@ proper position among the other output files. */ && defined(HAVE_AS_GDWARF2_DEBUG_FLAG) && defined(HAVE_AS_GSTABS_DEBUG_FLAG) # define ASM_DEBUG_SPEC \ (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG \ - ? "%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}" ASM_MAP \ - : "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}" ASM_MAP) + ? "%{!g0:%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}}" ASM_MAP \ + : "%{!g0:%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}}" ASM_MAP) # else # if defined(DBX_DEBUGGING_INFO) && defined(HAVE_AS_GSTABS_DEBUG_FLAG) -# define ASM_DEBUG_SPEC "%{g*:--gstabs}" ASM_MAP +# define ASM_DEBUG_SPEC "%{g*:%{!g0:--gstabs}}" ASM_MAP # endif # if defined(DWARF2_DEBUGGING_INFO) && defined(HAVE_AS_GDWARF2_DEBUG_FLAG) -# define ASM_DEBUG_SPEC "%{g*:--gdwarf2}" ASM_MAP +# define ASM_DEBUG_SPEC "%{g*:%{!g0:--gdwarf2}}" ASM_MAP # endif # endif #endif @@ -819,14 +825,14 @@ static const char *cpp_unique_options = in turn cause preprocessor symbols to be defined specially. */ static const char *cpp_options = "%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\ - %{f*} %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*}\ - %{undef} %{save-temps:-fpch-preprocess}"; + %{f*} %{g*:%{!g0:%{g*} %{!fno-working-directory:-fworking-directory}}} %{O*}\ + %{undef} %{save-temps*:-fpch-preprocess}"; /* 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. */ +/* 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 %B %{d*} %{m*} %{a*}\ @@ -999,17 +1005,17 @@ static const struct compiler default_compilers[] = %{traditional|ftraditional:\ %eGNU C no longer supports -traditional without -E}\ %{!combine:\ - %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ - %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\ - cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \ + %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ + %(cpp_options) -o %{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:\ + %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\ cc1 %(cpp_unique_options) %(cc1_options)}}}\ %{!fsyntax-only:%(invoke_as)}} \ %{combine:\ - %{save-temps|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ - %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i}}\ - %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\ + %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ + %(cpp_options) -o %{save-temps*:%b.i} %{!save-temps*:%g.i}}\ + %{!save-temps*:%{!traditional-cpp:%{!no-integrated-cpp:\ cc1 %(cpp_unique_options) %(cc1_options)}}\ %{!fsyntax-only:%(invoke_as)}}}}}}", 0, 1, 1}, {"-", @@ -1021,13 +1027,13 @@ static const struct compiler default_compilers[] = 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|no-integrated-cpp:%(trad_capable_cpp) \ - %(cpp_options) -o %{save-temps:%b.i} %{!save-temps:%g.i} \n\ - cc1 -fpreprocessed %{save-temps:%b.i} %{!save-temps:%g.i} \ + %{save-temps*|traditional-cpp|no-integrated-cpp:%(trad_capable_cpp) \ + %(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}\ - %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\ + %{!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}, @@ -3231,10 +3237,11 @@ display_help (void) fputs (_(" -pass-exit-codes Exit with highest error code from a phase\n"), stdout); fputs (_(" --help Display this information\n"), stdout); fputs (_(" --target-help Display target specific command line options\n"), stdout); - fputs (_(" --help={target|optimizers|warnings|undocumented|params}[,{[^]joined|[^]separate}]\n"), stdout); + fputs (_(" --help={target|optimizers|warnings|params|[^]{joined|separate|undocumented}}[,...]\n"), stdout); fputs (_(" Display specific types of command line options\n"), stdout); if (! verbose_flag) fputs (_(" (Use '-v --help' to display command line options of sub-processes)\n"), stdout); + fputs (_(" --version Display compiler version information\n"), stdout); fputs (_(" -dumpspecs Display all of the built in spec strings\n"), stdout); fputs (_(" -dumpversion Display the version of the compiler\n"), stdout); fputs (_(" -dumpmachine Display the compiler's target processor\n"), stdout); @@ -3257,6 +3264,7 @@ display_help (void) fputs (_(" -Xlinker Pass on to the linker\n"), stdout); fputs (_(" -combine Pass multiple source files to compiler at once\n"), stdout); fputs (_(" -save-temps Do not delete intermediate files\n"), stdout); + 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= Override built-in specs with the contents of \n"), stdout); @@ -3374,8 +3382,10 @@ process_command (int argc, const char **argv) 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') && (NULL != strchr(argv[1] + 2,'-'))))) + && (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; @@ -3383,10 +3393,15 @@ process_command (int argc, const char **argv) 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') && ( NULL != strchr(argv[1] + 2,'-'))))) + && (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; @@ -3423,8 +3438,18 @@ process_command (int argc, const char **argv) new_argv = XDUPVEC (char *, argv, argc + 1); new_argv[0] = new_argv0; - execvp (new_argv0, new_argv); - fatal ("couldn't run '%s': %s", new_argv0, xstrerror (errno)); + 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); } /* Set up the default search paths. If there is no GCC_EXEC_PREFIX, @@ -3627,7 +3652,7 @@ process_command (int argc, const char **argv) /* translate_options () has turned --version into -fversion. */ printf (_("%s %s%s\n"), programname, pkgversion_string, version_string); - printf ("Copyright %s 2008 Free Software Foundation, Inc.\n", + printf ("Copyright %s 2009 Free Software Foundation, Inc.\n", _("(C)")); 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"), @@ -3774,9 +3799,20 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" n_infiles++; else if (strcmp (argv[i], "-save-temps") == 0) { - save_temps_flag = 1; + 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], "-combine") == 0) { combine_flag = 1; @@ -3845,7 +3881,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" switch (c) { case 'b': - if (NULL == strchr(argv[i] + 2, '-')) + if (p[1] && NULL == strchr (argv[i] + 2, '-')) goto normal_switch; /* Fall through. */ @@ -3950,6 +3986,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" else argv[i] = convert_filename (argv[i], ! have_c, 0); #endif + /* Save the output name in case -save-temps=obj was used. */ + save_temps_prefix = xstrdup ((p[1] == 0) ? argv[i + 1] : argv[i] + 1); goto normal_switch; default: @@ -4007,6 +4045,25 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" } } + /* If -save-temps=obj and -o name, create the prefix to use for %b. + Otherwise just make -save-temps=obj the same as -save-temps=cwd. */ + if (save_temps_flag == SAVE_TEMPS_OBJ && save_temps_prefix != NULL) + { + save_temps_length = strlen (save_temps_prefix); + temp = strrchr (lbasename (save_temps_prefix), '.'); + if (temp) + { + save_temps_length -= strlen (temp); + save_temps_prefix[save_temps_length] = '\0'; + } + + } + else if (save_temps_prefix != NULL) + { + free (save_temps_prefix); + save_temps_prefix = NULL; + } + if (save_temps_flag && use_pipes) { /* -save-temps overrides -pipe, so that temp files are produced */ @@ -4761,12 +4818,18 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) fatal ("spec '%s' invalid", spec); case 'b': - obstack_grow (&obstack, input_basename, basename_length); + if (save_temps_length) + obstack_grow (&obstack, save_temps_prefix, save_temps_length); + else + obstack_grow (&obstack, input_basename, basename_length); arg_going = 1; break; case 'B': - obstack_grow (&obstack, input_basename, suffixed_basename_length); + if (save_temps_length) + obstack_grow (&obstack, save_temps_prefix, save_temps_length); + else + obstack_grow (&obstack, input_basename, suffixed_basename_length); arg_going = 1; break; @@ -4912,6 +4975,26 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) suffix_length += strlen (TARGET_OBJECT_SUFFIX); } + /* If -save-temps=obj and -o were specified, use that for the + temp file. */ + if (save_temps_length) + { + char *tmp; + temp_filename_length + = save_temps_length + suffix_length + 1; + tmp = (char *) alloca (temp_filename_length); + memcpy (tmp, save_temps_prefix, save_temps_length); + memcpy (tmp + save_temps_length, suffix, suffix_length); + tmp[save_temps_length + suffix_length] = '\0'; + temp_filename = save_string (tmp, + temp_filename_length + 1); + obstack_grow (&obstack, temp_filename, + temp_filename_length); + arg_going = 1; + delete_this_arg = 0; + break; + } + /* 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 @@ -4923,13 +5006,13 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) if (save_temps_flag) { char *tmp; - - temp_filename_length = basename_length + suffix_length; - tmp = (char *) alloca (temp_filename_length + 1); - strncpy (tmp, input_basename, basename_length); - strncpy (tmp + basename_length, suffix, suffix_length); - tmp[temp_filename_length] = '\0'; + temp_filename_length = basename_length + suffix_length + 1; + tmp = (char *) alloca (temp_filename_length); + memcpy (tmp, input_basename, basename_length); + memcpy (tmp + basename_length, suffix, suffix_length); + tmp[basename_length + suffix_length] = '\0'; temp_filename = tmp; + if (strcmp (temp_filename, input_filename) != 0) { #ifndef HOST_LACKS_INODE_NUMBERS @@ -6150,16 +6233,7 @@ set_input (const char *filename) input_filename = filename; input_filename_length = strlen (input_filename); - - input_basename = input_filename; -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - /* Skip drive name so 'x:foo' is handled properly. */ - if (input_basename[1] == ':') - input_basename += 2; -#endif - for (p = input_basename; *p; p++) - if (IS_DIR_SEPARATOR (*p)) - input_basename = p + 1; + input_basename = lbasename (input_filename); /* Find a suffix starting with the last period, and set basename_length to exclude that suffix. */ @@ -6587,7 +6661,10 @@ main (int argc, char **argv) /* We do not exit here. Instead we have created a fake input file called 'help-dummy' which needs to be compiled, and we pass this - on the various sub-processes, along with the --help switch. */ + on the various sub-processes, along with the --help switch. + Ensure their output appears after ours. */ + fputc ('\n', stdout); + fflush (stdout); } if (verbose_flag) @@ -8044,7 +8121,7 @@ include_spec_function (int argc, const char **argv) if (argc != 1) abort (); - file = find_a_file (&startfile_prefixes, argv[0], R_OK, 0); + file = find_a_file (&startfile_prefixes, argv[0], R_OK, true); read_specs (file ? file : argv[0], FALSE); return NULL;