diff options
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r-- | gcc/gcc.c | 568 |
1 files changed, 531 insertions, 37 deletions
diff --git a/gcc/gcc.c b/gcc/gcc.c index a9eec5a7200..d70e4dff9bd 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -240,6 +240,35 @@ static const char *const spec_version = DEFAULT_TARGET_VERSION; static const char *spec_machine = DEFAULT_TARGET_MACHINE; +/* APPLE LOCAL begin CC_PRINT_OPTIONS (radar 3313335) */ +static char *cc_print_options = 0; +static char *cc_print_options_filename; +/* APPLE LOCAL end CC_PRINT_OPTIONS */ + +/* APPLE LOCAL constant cfstrings */ +static int use_constant_cfstrings = 0; +/* APPLE LOCAL begin deployment target */ +/* The deployment target (i.e., the minimum version of MacOS X that + the binary is expected to be used on). */ +static const char *macosx_deployment_target = 0; +static unsigned int macosx_version_min_required = 0; + +/* The following table should be NULL-terminated and kept in + lexicographic order. */ + +static struct macosx_vers { + const char *vers_str; + unsigned int vers_num; +} macosx_vers_tbl[] = { + { "10.0", 1000 }, + { "10.1", 1010 }, + { "10.2", 1020 }, + { "10.3", 1030 }, + { "10.4", 1040 }, + { NULL, 0 } +}; +/* APPLE LOCAL end deployment target */ + /* Nonzero if cross-compiling. When -b is used, the value comes from the `specs' file. */ @@ -325,6 +354,8 @@ static const char *eval_spec_function (const char *, const char *); static const char *handle_spec_function (const char *); static char *save_string (const char *, int); static void set_collect_gcc_options (void); +/* APPLE LOCAL %b/save-temps can clobber input file (radar 2871891) --ilr */ +static const char *check_basename_derived_file (const char *string); static void do_spec_path (struct prefix_list *, const char *, int, int, int, const char *, const char *); static int do_spec_1 (const char *, int, const char *); static int do_spec_2 (const char *); @@ -453,6 +484,10 @@ or with constant text in a single argument. %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. + APPLE LOCAL frameworks + %Q Substitute -iframework default paths. + APPLE LOCAL constant cfstrings + %yC Emit '-mconstant-cfstrings' option, if needed. %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. @@ -696,16 +731,18 @@ proper position among the other output files. */ /* We want %{T*} after %{L*} and %D so that it can be used to specify linker scripts which exist in user specified directories, or in standard directories. */ +/* APPLE LOCAL begin add fcreate-profile */ #ifndef LINK_COMMAND_SPEC #define LINK_COMMAND_SPEC "\ %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\ %(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\ %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\ %{static:} %{L*} %(mfwrap) %(link_libgcc) %o %(mflib)\ - %{fprofile-arcs|fprofile-generate:-lgcov}\ + %{fprofile-arcs|fprofile-generate|fcreate-profile:-lgcov}\ %{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\ %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}" #endif +/* APPLE LOCAL end add fcreate-profile */ #ifndef LINK_LIBGCC_SPEC # ifdef LINK_LIBGCC_SPECIAL @@ -763,10 +800,18 @@ static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC; static const char *trad_capable_cpp = "cc1 -E %{traditional|ftraditional|traditional-cpp:-traditional-cpp}"; +/* APPLE LOCAL begin pch */ +/* When making PCH file use this. */ +static const char *pch = +"-o %g.s %{!o*:--output-pch=%i.gch} %W{o*:--output-pch=%*}%V"; +/* APPLE LOCAL end pch */ + /* We don't wrap .d files in %W{} since a missing .d file, and 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 = +/* APPLE LOCAL constant cfstrings */ +"%yC" "%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}}\ %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I\ %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\ @@ -794,6 +839,13 @@ static const char *cpp_debug_options = "%{d*}"; /* NB: This is shared amongst all front-ends. */ static const char *cc1_options = +/* APPLE LOCAL constant cfstrings */ +"%yC" +/* APPLE LOCAL begin -fast */ +"%{fast:-O3}\ + %{fastf:-O3}\ + %{fastcp:-O3}" +/* APPLE LOCAL end -fast */ "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\ %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\ @@ -942,24 +994,28 @@ static const struct compiler default_compilers[] = {"@c", /* cc1 has an integrated ISO C preprocessor. We should invoke the external preprocessor if -save-temps is given. */ + /* APPLE LOCAL begin treat -fast same as -combine --dbj */ "%{E|M|MM:%(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)}\ + "/* APPLE LOCAL cpp-precomp compatibility */"\ + %{precomp:%ecpp-precomp not supported}%{no-cpp-precomp:}%{Wno-precomp:}\ %{!E:%{!M:%{!MM:\ %{traditional|ftraditional:\ %eGNU C no longer supports -traditional without -E}\ - %{!combine:\ + %{combine|fast|fastf|fastcp:\ + %{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)}};:\ %{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} \ +"/* APPLE LOCAL predictive compilation */"\ + cc1 -fpreprocessed %<fpredictive-compilation* %{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)}} \ - %{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:\ - cc1 %(cpp_unique_options) %(cc1_options)}}\ - %{!fsyntax-only:%(invoke_as)}}}}}}", 0, 1, 1}, + %{!fsyntax-only:%(invoke_as)}}}}}", 0, 1, 1}, + /* APPLE LOCAL end treat -fast same as -combine --dbj */ {"-", "%{!E:%e-E required when input is from standard input}\ %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0}, @@ -971,18 +1027,28 @@ static const struct compiler default_compilers[] = %{!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} \ +"/* APPLE LOCAL predictive compilation */"\ + cc1 -fpreprocessed %<fpredictive-compilation* %{save-temps:%b.i} %{!save-temps:%g.i} \ %(cc1_options)\ - -o %g.s %{!o*:--output-pch=%i.gch}\ - %W{o*:--output-pch=%*}%V}\ +"/* APPLE LOCAL pch */"\ + %(pch)}\ %{!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}, +"/* APPLE LOCAL pch */"\ + %(pch)}}}}}}", 0, 0, 0}, {".i", "@cpp-output", 0, 1, 0}, {"@cpp-output", - "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 1, 0}, - {".s", "@assembler", 0, 1, 0}, + /* APPLE LOCAL predictive compilation */ + "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %<fpredictive-compilation* %{!fsyntax-only:%(invoke_as)}}}}", 0, 1, 0}, + /* APPLE LOCAL begin preprocess .s files 2001-07-24 --sts */ + /* This is kind of lame; the purpose of having .s and .S be treated + differently is so that we can control whether to run the + preprocessor on assembly files. The standard behavior would + still work even on HFS filesystems, because they preserve case, + but we'd have to get a number of projects to change their files, + and of course that's just *too* *hard*. */ + {".s", "@assembler-with-cpp", 0, 1, 0}, + /* APPLE LOCAL end preprocess .s files 2001-07-24 --sts */ {"@assembler", "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 1, 0}, {".S", "@assembler-with-cpp", 0, 1, 0}, @@ -1009,6 +1075,12 @@ static const struct compiler default_compilers[] = static const int n_default_compilers = ARRAY_SIZE (default_compilers) - 1; +/* APPLE LOCAL begin -ObjC 2001-08-03 --sts */ +/* -ObjC is not the same as -x objective-c, since it only affects the + expectation of the language in files already thought to be source + code. */ +static const char *default_language; +/* APPLE LOCAL end -ObjC 2001-08-03 --sts */ /* A vector of options to give to the linker. These options are accumulated by %x, and substituted into the linker command with %X. */ @@ -1524,6 +1596,8 @@ static struct spec_list static_specs[] = 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), + /* APPLE LOCAL pch */ + INIT_STATIC_SPEC ("pch", &pch), INIT_STATIC_SPEC ("cc1", &cc1_spec), INIT_STATIC_SPEC ("cc1_options", &cc1_options), INIT_STATIC_SPEC ("cc1plus", &cc1plus_spec), @@ -2717,7 +2791,8 @@ execute (void) /* If -v, print what we are about to do, and maybe query. */ - if (verbose_flag) + /* APPLE LOCAL begin CC_PRINT_OPTIONS (radar 3313335, 3360444) */ + if (verbose_flag || cc_print_options) { /* For help listings, put a blank line between sub-processes. */ if (print_help_list) @@ -2728,29 +2803,49 @@ execute (void) { const char *const *j; - if (verbose_only_flag) + FILE *f = stderr; + if (cc_print_options) + { + if (cc_print_options_filename) + { + f = fopen (cc_print_options_filename, "a"); + if (!f) + { + fprintf (stderr, "can not open CC_PRINT_OPTIONS_FILE %s\n", + cc_print_options_filename); + exit (1); + } + } + fprintf (f, "[Logging gcc options]"); + } + + if (verbose_only_flag || cc_print_options) { for (j = commands[i].argv; *j; j++) { const char *p; - fprintf (stderr, " \""); + fprintf (f, " \""); for (p = *j; *p; ++p) { if (*p == '"' || *p == '\\' || *p == '$') - fputc ('\\', stderr); - fputc (*p, stderr); + fputc ('\\', f); + fputc (*p, f); } - fputc ('"', stderr); + fputc ('"', f); } } else for (j = commands[i].argv; *j; j++) - fprintf (stderr, " %s", *j); + fprintf (f, " %s", *j); /* Print a pipe symbol after all but the last command. */ if (i + 1 != n_commands) - fprintf (stderr, " |"); - fprintf (stderr, "\n"); + fprintf (f, " |"); + fprintf (f, "\n"); + + if (cc_print_options_filename) + fclose (f); +/* APPLE LOCAL end CC_PRINT_OPTIONS */ } fflush (stderr); if (verbose_only_flag != 0) @@ -2809,6 +2904,17 @@ execute (void) char *errmsg_fmt, *errmsg_arg; const char *string = commands[i].argv[0]; + /* APPLE LOCAL begin verbose help (radar #2920964) */ + if (verbose_flag && print_help_list + && (!strcmp ("/usr/libexec/gcc/darwin/ppc/as", string) + || !strcmp ("/usr/libexec/gcc/darwin/i386/as", string) + || !strcmp ("ld", string))) + { + /* Do nothing. + as and ld do not entertain --help. */ + } + else + /* APPLE LOCAL end */ /* For some bizarre reason, the second argument of execvp() is char *const *, not const char *const *. */ commands[i].pid = pexecute (string, (char *const *) commands[i].argv, @@ -2848,6 +2954,16 @@ execute (void) int status; int pid; + /* APPLE LOCAL begin verbose help (radar #2920964) */ + if (verbose_flag && print_help_list + && (!strcmp ("as", commands[i].prog) + || !strcmp ("ld", commands[i].prog))) + { + /* as and ld do not entertain --help. */ + i++; + continue; + } + /* APPLE LOCAL end */ pid = pwait (commands[i].pid, &status, 0); gcc_assert (pid >= 0); @@ -2951,9 +3067,14 @@ struct infile { const char *name; const char *language; + /* APPLE LOCAL begin IMI */ struct compiler *incompiler; + + /* Use separate temp file for each input file. */ + const char *temp_filename; bool compiled; bool preprocessed; + /* APPLE LOCAL end IMI */ }; /* Also a vector of input files specified. */ @@ -2967,6 +3088,15 @@ int n_infiles; static bool combine_inputs; +/* APPLE LOCAL begin IMA variables */ + +/* True if "-traditional-cpp" appears on commandline. */ +static int traditional_cpp_flag = 0; + +/* True if "-E" appears on commandline. */ +static int capital_e_flag = 0; +/* APPLE LOCAL end */ + /* This counts the number of libraries added by lang_specific_driver, so that we can tell if there were any user supplied any files or libraries. */ @@ -3174,6 +3304,13 @@ process_command (int argc, const char **argv) } } + /* APPLE LOCAL begin translate_options */ + /* FSF patch pending. Move translate_options() call before -b processing + so that -bundle like options can be translated, if required. */ + /* Convert new-style -- options to old-style. */ + translate_options (&argc, (const char *const **) &argv); + /* APPLE LOCAL end */ + /* 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] == '-' @@ -3376,6 +3513,24 @@ process_command (int argc, const char **argv) } } + /* APPLE LOCAL begin deployment target */ + /* Retrieve the deployment target from the environment, and then decide + whether to enable '-fconstant-cfstrings' by default. */ + macosx_deployment_target = getenv ("MACOSX_DEPLOYMENT_TARGET"); + if (macosx_deployment_target) + { + struct macosx_vers *v = macosx_vers_tbl; + + while (v->vers_str && strcmp (macosx_deployment_target, v->vers_str)) + v++; + if (v->vers_str) + { + macosx_version_min_required = v->vers_num; + use_constant_cfstrings = (macosx_version_min_required >= 1020); + } + } + /* APPLE LOCAL end deployment target */ + /* Convert new-style -- options to old-style. */ translate_options (&argc, (const char *const **) &argv); @@ -3431,8 +3586,15 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" /* CPP driver cannot obtain switch from cc1_options. */ if (is_cpp_driver) add_preprocessor_option ("--help", 6); + /* APPLE LOCAL begin verbose help (radar #2920964) */ +#if 0 + /* Our assembler and linkder do not support --help. */ + /* APPLE LOCAL end */ add_assembler_option ("--help", 6); add_linker_option ("--help", 6); + /* APPLE LOCAL begin verbose help (radar #2920964) */ +#endif + /* APPLE LOCAL end */ } else if (strcmp (argv[i], "-ftarget-help") == 0) { @@ -3549,6 +3711,43 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" save_temps_flag = 1; n_switches++; } + /* APPLE LOCAL begin IMA */ + else if (strcmp (argv[i], "-fast") == 0 + || strcmp (argv[i], "-fastf") == 0 + || strcmp (argv[i], "-fastcp") == 0) + { + combine_flag = 1; + n_switches++; + } + else if (strcmp (argv[i], "-traditional-cpp") == 0) + { + traditional_cpp_flag = 1; + n_switches++; + } + else if (strcmp (argv[i], "-E") == 0) + { + capital_e_flag = 1; + n_switches++; + } + /* APPLE LOCAL end IMA */ + /* APPLE LOCAL begin -weak_* (radar 3235250) */ + else if (strcmp (argv[i], "-weak_library") == 0) + { + if (i + 1 == argc) + fatal ("argument to `-weak_library' is missing"); + + n_infiles += 2; + i++; + } + else if (strcmp (argv[i], "-weak_framework") == 0) + { + if (i + 1 == argc) + fatal ("argument to `-weak_framework' is missing"); + + n_infiles += 2; + i++; + } + /* APPLE LOCAL end -weak_* (radar 3235250) */ else if (strcmp (argv[i], "-combine") == 0) { combine_flag = 1; @@ -3600,6 +3799,22 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" verbose_only_flag++; verbose_flag++; } + /* APPLE LOCAL begin constant cfstrings */ + else if (strcmp (argv[i], "-fconstant-cfstrings") == 0) + use_constant_cfstrings = 1; + else if (strcmp (argv[i], "-fno-constant-cfstrings") == 0) + use_constant_cfstrings = 0; + /* APPLE LOCAL end constant cfstrings */ + /* APPLE LOCAL begin frameworks */ + else if (strcmp (argv[i], "-framework") == 0) + { + if (i + 1 == argc) + fatal ("argument to `-framework' is missing"); + + n_infiles += 2; + i++; + } + /* APPLE LOCAL end frameworks */ else if (argv[i][0] == '-' && argv[i][1] != 0) { const char *p = &argv[i][1]; @@ -3885,6 +4100,33 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" /* More prefixes are enabled in main, after we read the specs file and determine whether this is cross-compilation or not. */ + /* APPLE LOCAL begin constant cfstrings */ + /* Check if '-fconstant-cfstrings' usage is valid, given our deployment + target. If not, issue a warning and then suppress the option. */ + if (use_constant_cfstrings) + { + if (macosx_version_min_required && macosx_version_min_required < 1020) + { + error ("warning: `-fconstant-cfstrings' ignored because MACOSX_DEPLOYMENT_TARGET is \"%s\"", + macosx_deployment_target); + use_constant_cfstrings = 0; + } + } + /* APPLE LOCAL end constant cfstrings */ + /* APPLE LOCAL begin deployment target */ + /* Synthesize the deployment target manifest constant. */ + if (macosx_version_min_required) + { +#define VERSION_MIN_REQUIRED_FMT "-D__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__=%d" + char *macro_def = xmalloc (strlen (VERSION_MIN_REQUIRED_FMT) + 30); + + sprintf (macro_def, VERSION_MIN_REQUIRED_FMT, macosx_version_min_required); + add_preprocessor_option (macro_def, strlen (macro_def)); + free (macro_def); +#undef VERSION_MIN_REQUIRED_FMT + } + /* APPLE LOCAL end deployment target */ + /* Then create the space for the vectors and scan again. */ switches = xmalloc ((n_switches + 1) * sizeof (struct switchstr)); @@ -3991,14 +4233,62 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" infiles[n_infiles].language = "*"; infiles[n_infiles++].name = argv[i]; } + /* APPLE LOCAL begin -weak_* (radar 3235250) */ + else if (strncmp (argv[i], "-weak-l", 7) == 0) + { + infiles[n_infiles].language = "*"; + infiles[n_infiles++].name = argv[i]; + } + else if (strcmp (argv[i], "-weak_library") == 0) + { + infiles[n_infiles].language = "*"; + infiles[n_infiles++].name = argv[i]; + infiles[n_infiles].language = "*"; + infiles[n_infiles++].name = argv[++i]; + } + else if (strcmp (argv[i], "-weak_framework") == 0) + { + infiles[n_infiles].language = "*"; + infiles[n_infiles++].name = argv[i]; + infiles[n_infiles].language = "*"; + infiles[n_infiles++].name = argv[++i]; + } + /* APPLE LOCAL end -weak_* (radar #3235250) */ else if (strcmp (argv[i], "-specs") == 0) i++; else if (strncmp (argv[i], "-specs=", 7) == 0) ; + /* APPLE LOCAL begin -ObjC 2001-08-03 --sts */ + else if (!strcmp (argv[i], "-ObjC") || !strcmp (argv[i], "-fobjc")) + { + default_language = "objective-c"; + add_linker_option ("-ObjC", 5); + } + else if (strcmp (argv[i], "-ObjC++") == 0) + { + default_language = "objective-c++"; + add_linker_option ("-ObjC", 5); + } + /* APPLE LOCAL end -ObjC 2001-08-03 --sts */ else if (strcmp (argv[i], "-time") == 0) ; else if (strcmp (argv[i], "-###") == 0) ; + /* APPLE LOCAL begin constant cfstrings */ + else if (strcmp (argv[i], "-fconstant-cfstrings") == 0) + ; + else if (strcmp (argv[i], "-fno-constant-cfstrings") == 0) + ; + /* APPLE LOCAL end constant cfstrings */ + /* APPLE LOCAL begin frameworks */ + else if (strcmp (argv[i], "-framework") == 0) + { + infiles[n_infiles].language = "*"; + infiles[n_infiles++].name = argv[i]; + infiles[n_infiles].language = "*"; + infiles[n_infiles++].name = argv[++i]; + } + /* APPLE LOCAL end frameworks */ else if (argv[i][0] == '-' && argv[i][1] != 0) { const char *p = &argv[i][1]; @@ -4228,6 +4518,14 @@ static int delete_this_arg; is the output file name of this compilation. */ static int this_is_output_file; +/* APPLE LOCAL begin %b/save-temps can clobber input file (radar 2871891) --ilr */ +/* Nonzero if %b or %B has been seen; the next arg to be terminated + is a temp file based on the input file's basename. This has + the potential to be the same as the input file itself so we + need to take precautions if it is. */ +static int this_is_basename_derived_file = 0; +/* APPLE LOCAL end %b/save-temps can clobber input file (radar 2871891) --ilr */ + /* Nonzero means %s has been seen; the next arg to be terminated is the name of a library file and we should try the standard search dirs for it. */ @@ -4248,6 +4546,10 @@ do_spec (const char *spec) { int value; + /* APPLE LOCAL begin %b/save-temps can clobber input file (radar 2871891) --ilr */ + this_is_basename_derived_file = 0; + /* APPLE LOCAL end %b/save-temps can clobber input file (radar 2871891) --ilr */ + value = do_spec_2 (spec); /* Force out any unfinished command. @@ -4266,6 +4568,81 @@ do_spec (const char *spec) return value; } +/* APPLE LOCAL begin %b/save-temps can clobber input file (radar 2871891) --ilr */ +/* For %b and %B specs, which create a filename based on the input + file's basename, there is a possibility that the resulting file + is the same as the input file. Assuming that such names are + intended to be used as intermediate (temporary) files there is + the risk of clobbering the input file. We check for that here + and use a temp file instead if that would happen. */ + +static const char * +check_basename_derived_file (const char *string) +{ + int suffix_length, string_length; + const char *suffix; + + static struct base_temp_name { + int suffix_length; + int filename_length; + const char *filename; + struct base_temp_name *next; + } *t, *base_temp_names = NULL; + + if (strcmp (string, input_filename) != 0) + { + struct stat st_temp; + + /* Note, set_input() resets input_stat_set to 0. This can also + be done buy or for %U, %u, and %g. */ + if (input_stat_set == 0) + { + input_stat_set = stat (input_filename, &input_stat); + if (input_stat_set >= 0) + input_stat_set = 1; + } + + if (input_stat_set != 1 + || stat (string, &st_temp) < 0 + || input_stat.st_dev != st_temp.st_dev + || input_stat.st_ino != st_temp.st_ino) + { + this_is_basename_derived_file = 0; + return string; + } + } + + string_length = strlen (string); + suffix_length = string_length - basename_length; + suffix = string + string_length - suffix_length; + + if (suffix_length > 0) + { + for (t = base_temp_names; t; t = t->next) + if (t->suffix_length == suffix_length + && strcmp (t->filename + t->filename_length - suffix_length, + suffix) == 0) + break; + } + else + t = NULL; + + if (!t) + { + t = (struct base_temp_name *) xmalloc (sizeof (struct base_temp_name)); + t->next = base_temp_names; + base_temp_names = t; + + t->filename = make_temp_file (suffix); + t->filename_length = strlen (t->filename); + t->suffix_length = suffix_length; + } + + delete_this_arg = 1; + return t->filename; +} +/* APPLE LOCAL end %b/save-temps can clobber input file (radar 2871891) --ilr */ + static int do_spec_2 (const char *spec) { @@ -4519,9 +4896,14 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) { obstack_1grow (&obstack, 0); string = obstack_finish (&obstack); - if (this_is_library_file) + /* APPLE LOCAL begin %b/save-temps can clobber input file (radar 2871891) --ilr */ + if (this_is_basename_derived_file) + string = check_basename_derived_file (string); + else if (this_is_library_file) string = find_file (string); - store_arg (string, delete_this_arg, this_is_output_file); + store_arg (string, delete_this_arg, this_is_output_file + || this_is_basename_derived_file); + /* APPLE LOCAL end %b/save-temps can clobber input file (radar 2871891) --ilr */ if (this_is_output_file) outfiles[input_file_number] = string; } @@ -4554,6 +4936,8 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) arg_going = 0; delete_this_arg = 0; this_is_output_file = 0; + /* APPLE LOCAL %b/save-temps can clobber input file (radar 2871891) --ilr */ + this_is_basename_derived_file = 0; this_is_library_file = 0; input_from_pipe = 0; break; @@ -4564,9 +4948,14 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) { obstack_1grow (&obstack, 0); string = obstack_finish (&obstack); - if (this_is_library_file) + /* APPLE LOCAL begin %b/save-temps can clobber input file (radar 2871891) --ilr */ + if (this_is_basename_derived_file) + string = check_basename_derived_file (string); + else if (this_is_library_file) string = find_file (string); - store_arg (string, delete_this_arg, this_is_output_file); + store_arg (string, delete_this_arg, this_is_output_file + || this_is_basename_derived_file); + /* APPLE LOCAL end %b/save-temps can clobber input file (radar 2871891) --ilr */ if (this_is_output_file) outfiles[input_file_number] = string; } @@ -4583,9 +4972,14 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) { obstack_1grow (&obstack, 0); string = obstack_finish (&obstack); - if (this_is_library_file) + /* APPLE LOCAL begin %b/save-temps can clobber input file (radar 2871891) --ilr */ + if (this_is_basename_derived_file) + string = check_basename_derived_file (string); + else if (this_is_library_file) string = find_file (string); - store_arg (string, delete_this_arg, this_is_output_file); + store_arg (string, delete_this_arg, this_is_output_file + || this_is_basename_derived_file); + /* APPLE LOCAL end %b/save-temps can clobber input file (radar 2871891) --ilr */ if (this_is_output_file) outfiles[input_file_number] = string; } @@ -4593,6 +4987,8 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) arg_going = 0; delete_this_arg = 0; this_is_output_file = 0; + /* APPLE LOCAL %b/save-temps can clobber input file (radar 2871891) --ilr */ + this_is_basename_derived_file = 0; this_is_library_file = 0; break; @@ -4603,6 +4999,8 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) fatal ("spec '%s' invalid", spec); case 'b': + /* APPLE LOCAL %b/save-temps can clobber input file (radar 2871891) --ilr */ + this_is_basename_derived_file = 1; obstack_grow (&obstack, input_basename, basename_length); arg_going = 1; break; @@ -4816,6 +5214,15 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) suffix. */ for (t = temp_names; t; t = t->next) if (t->length == suffix_length + /* APPLE LOCAL begin IMA */ +#if 0 + /* This causes gcc.dg/cpp/trad/builtins.c to fail. + Disable this for now. */ + /* Create new temp file for each source file. */ + && strcmp (suffix, ".i") + && strcmp (suffix, ".ii") +#endif + /* APPLE LOCAL end IMA */ && strncmp (t->suffix, suffix, suffix_length) == 0 && t->unique == (c == 'u' || c == 'U' || c == 'j')) break; @@ -4843,13 +5250,17 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) temp_filename_length = strlen (temp_filename); t->filename = temp_filename; t->filename_length = temp_filename_length; + /* APPLE LOCAL begin IMA */ + infiles[input_file_number].temp_filename = temp_filename; + /* APPLE LOCAL end IMA */ } if (saved_suffix) free (saved_suffix); obstack_grow (&obstack, t->filename, t->filename_length); - delete_this_arg = 1; + /* APPLE LOCAL what is this for? */ + delete_this_arg = (save_temps_flag == 0); } arg_going = 1; break; @@ -4903,6 +5314,26 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) } break; + /* APPLE LOCAL begin constant cfstrings */ + case 'y': + { + int c1 = *p++; + + if (c1 == 'C') + { + if (use_constant_cfstrings) + { + do_spec_1 (" ", 0, NULL); + do_spec_1 ("-mconstant-cfstrings", 1, NULL); + do_spec_1 (" ", 0, NULL); + } + } + else + abort (); + } + break; + /* APPLE LOCAL end constant cfstrings */ + case 'o': { int max = n_infiles; @@ -6033,6 +6464,11 @@ main (int argc, const char **argv) const char *p; struct user_specs *uptr; + /* APPLE LOCAL begin CC_PRINT_OPTIONS (radar 3313335, 3360444) */ + cc_print_options = getenv ("CC_PRINT_OPTIONS"); + cc_print_options_filename = getenv ("CC_PRINT_OPTIONS_FILE"); + /* APPLE LOCAL end */ + p = argv[0] + strlen (argv[0]); while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1])) --p; @@ -6457,8 +6893,10 @@ main (int argc, const char **argv) infiles[i].compiled = false; infiles[i].preprocessed = false; } - - if (combine_flag && save_temps_flag) + + /* APPLE LOCAL begin IMA */ + if (combine_flag + && (save_temps_flag || traditional_cpp_flag || capital_e_flag)) { bool save_combine_inputs = combine_inputs; /* Must do a separate pre-processing pass for C & Objective-C files, to @@ -6485,7 +6923,7 @@ main (int argc, const char **argv) input_filename, &input_file_compiler->spec[1]); this_file_error = 1; } - else + else if (capital_e_flag) { value = do_spec (input_file_compiler->spec); infiles[i].preprocessed = true; @@ -6500,8 +6938,34 @@ main (int argc, const char **argv) if (value < 0) this_file_error = 1; } + else if (save_temps_flag) + { + value = do_spec (input_file_compiler->spec); + infiles[i].preprocessed = TRUE; + if (have_o_argbuf_index) + infiles[i].name = argbuf[have_o_argbuf_index]; + else + abort (); + + infiles[i].incompiler = lookup_compiler (infiles[i].name, + strlen (infiles[i].name), + infiles[i].language); + + } + else if (traditional_cpp_flag) + { + /* Temp file name is stored in infiles->temp_filename. + Use it as input file name. */ + infiles[i].name = infiles[i].temp_filename; + infiles[i].incompiler = lookup_compiler (infiles[i].name, + strlen (infiles[i].name), + infiles[i].language); + } } + if (value < 0) + this_file_error = 1; + if (this_file_error) { delete_failure_queue (); @@ -6512,6 +6976,7 @@ main (int argc, const char **argv) } combine_inputs = save_combine_inputs; } +/* APPLE LOCAL end IMI */ for (i = 0; (int) i < n_infiles; i++) { @@ -6548,7 +7013,15 @@ main (int argc, const char **argv) input_filename, &input_file_compiler->spec[1]); this_file_error = 1; } - else + /* APPLE LOCAL begin IMA */ + /* Check if -E is not used on command line OR input file is + assembly file. If -E is used then do not invoke compiler + again, because preprocessed output is already generated + above. However + 1) If -E is used with assembly input file then continue. + 2) If inputs are not combined then continue. */ + else if (!capital_e_flag || !combine_inputs) + /* APPLE LOCAL end IMA */ { value = do_spec (input_file_compiler->spec); infiles[i].compiled = true; @@ -6704,6 +7177,27 @@ lookup_compiler (const char *name, size_t length, const char *language) if (cp >= compilers) { + /* APPLE LOCAL begin -ObjC 2001-08-03 --sts */ + /* We found a language, but because we set a default language, + override with the default. */ + if (default_language) + { + struct compiler *ncomp = lookup_compiler (NULL, 0, default_language); +#if 0 /* unhelpful without docs to educate users, skip for now -sts 2002-01-01 */ + if (cp == ncomp + || (cp->spec[0] == '@' + && ncomp + && strcmp (cp->spec, ncomp->suffix) == 0)) + { + if (strcmp (default_language, "objective-c") == 0) + error ("Warning: -ObjC/-fobjc option is redundant"); + if (strcmp (default_language, "objective-c++") == 0) + error ("Warning: -ObjC++ option is redundant"); + } +#endif + return ncomp; + } + /* APPLE LOCAL end -ObjC 2001-08-03 --sts */ if (cp->spec[0] != '@') /* A non-alias entry: return it. */ return cp; |