diff options
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r-- | gcc/gcc.c | 763 |
1 files changed, 712 insertions, 51 deletions
diff --git a/gcc/gcc.c b/gcc/gcc.c index 6b487c2ba92..816a59ff25a 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -235,6 +235,32 @@ static const char *const spec_version = DEFAULT_TARGET_VERSION; static const char *spec_machine = DEFAULT_TARGET_MACHINE; +/* APPLE LOCAL begin constant cfstrings */ +static int use_constant_cfstrings = 0; +/* 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; +unsigned int macosx_version_min_required = 0; + +/* APPLE LOCAL 3313335 */ +static char *cc_print_options = 0; +static char *cc_print_options_filename; +/* 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 constant cfstrings */ + /* Nonzero if cross-compiling. When -b is used, the value comes from the `specs' file. */ @@ -319,6 +345,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 int do_spec_1 (const char *, int, const char *); static int do_spec_2 (const char *); static void do_option_spec (const char *, const char *); @@ -445,6 +473,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 framework headers + %Q Substitute -iframework default paths. + APPLE LOCAL constant cfstrings + %yC Emit '-fconstant-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. @@ -755,11 +787,22 @@ 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}"; +/* When making PCH file use this. */ +/* APPLE LOCAL Symbol Separation */ +/* Add fsave-repository constructs for Symbol Separation */ +static const char *pch = +"%{!fsave-repository*:-o %g.s %{!o*:--output-pch=%i.pch} %W{o*:--output-pch=%*}%V}"; + +/* APPLE LOCAL Symbol Separation */ +static const char *dbg_ss= "%{fsave-repository*: -gfull %(invoke_as)}"; + /* 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 = "%{C|CC:%{!E:%eGCC does not support -C or -CC without -E}}\ +"/* APPLE LOCAL framework headers */"\ + %{!traditional:%{!ftraditional:%{!traditional-cpp:%Q}}} %{F*}\ %{!Q:-quiet} %{nostdinc*} %{C} %{CC} %{v} %{I*&F*} %{P} %I\ %{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\ %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\ @@ -785,7 +828,17 @@ static const char *cpp_debug_options = "%{d*}"; /* NB: This is shared amongst all front-ends. */ static const char *cc1_options = +/* APPLE LOCAL constant cfstrings */ +/* APPLE LOCAL Symbol Separation */ +/* Add fsave-repository construct for Symbol Separation */ +"%yC" +/* APPLE LOCAL begin -fast option */ +"%{fast:-O3}\ + %{fastf:-O3}\ + %{fastcp:-O3}" +/* APPLE LOCAL end -fast option */ "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ + %{fsave-repository*:-gfull}\ %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\ %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\ %{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\ @@ -797,7 +850,15 @@ static const char *cc1_options = %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}"; static const char *asm_options = -"%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}"; +/* APPLE LOCAL -fast */ +/* APPLE LOCAL Symbol Separation */ +/* Add fsave-repository constructs for Symbol Separation */ +"%a %Y \ + %{fast:-force_cpusubtype_ALL}\ + %{fastf:-force_cpusubtype_ALL}\ + %{fastcp:-force_cpusubtype_ALL}\ + %{c:%W{o*}%{!o*:%{!fsave-repository*:-o %w%b%O} %{fsave-repository*:-o %w%i%O}}}\ + %{!c:%{!fsave-repository*:-o %d%w%u%O} %{fsave-repository*:%W{o*}%{!o*:-o %w%i%O}}}"; static const char *invoke_as = #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT @@ -924,16 +985,17 @@ static const struct compiler default_compilers[] = /* 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)}\ + "/* 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}\ %{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)}\ + %(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}, + cc1 %(cpp_unique_options) %(cc1_options)}}\ + %{!fsyntax-only:\ + %{!traditional-cpp:%(invoke_as)}}}}}}", 0}, {"-", "%{!E:%e-E required when input is from standard input}\ %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0}, @@ -947,16 +1009,23 @@ static const struct compiler default_compilers[] = %(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}\ + "/* APPLE LOCAL symbol separation */"\ + %(dbg_ss) %(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}, + "/* APPLE LOCAL symbol separation */"\ + %(dbg_ss) %(pch)}}}}}}", 0}, {".i", "@cpp-output", 0}, {"@cpp-output", "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0}, - {".s", "@assembler", 0}, + /* APPLE LOCAL 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}, {"@assembler", "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0}, {".S", "@assembler-with-cpp", 0}, @@ -983,6 +1052,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 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. */ @@ -1070,6 +1145,8 @@ static const struct option_map option_map[] = {"--pedantic-errors", "-pedantic-errors", 0}, {"--pie", "-pie", 0}, {"--pipe", "-pipe", 0}, + /* APPLE LOCAL -precomp-trustfile */ + {"--precomp-trustfile", "-precomp-trustfile", "a"}, {"--prefix", "-B", "a"}, {"--preprocess", "-E", 0}, {"--print-search-dirs", "-print-search-dirs", 0}, @@ -1085,6 +1162,8 @@ static const struct option_map option_map[] = {"--quiet", "-q", 0}, {"--resource", "-fcompile-resource=", "aj"}, {"--save-temps", "-save-temps", 0}, + /* APPLE LOCAL Symbol Separation */ + {"--save-repository", "-fsave-repository=", "aj"}, {"--shared", "-shared", 0}, {"--silent", "-q", 0}, {"--specs", "-specs=", "aj"}, @@ -1386,6 +1465,13 @@ static struct path_prefix startfile_prefixes = { 0, 0, "startfile" }; static struct path_prefix include_prefixes = { 0, 0, "include" }; +/* APPLE LOCAL begin framework headers */ +#ifdef FRAMEWORK_HEADERS +/* A vector of the frameworks to search. */ +static struct path_prefix default_framework_paths = {0, 0, "default_frameworks"}; +#endif /* FRAMEWORK_HEADERS */ +/* APPLE LOCAL end framework headers */ + /* Suffix to attach to directories searched for commands. This looks like `MACHINE/VERSION/'. */ @@ -1486,6 +1572,9 @@ 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), + INIT_STATIC_SPEC ("pch", &pch), + /* APPLE LOCAL Symbol Separtion */ + INIT_STATIC_SPEC ("dbg_ss", &dbg_ss), INIT_STATIC_SPEC ("cc1", &cc1_spec), INIT_STATIC_SPEC ("cc1_options", &cc1_options), INIT_STATIC_SPEC ("cc1plus", &cc1plus_spec), @@ -2665,6 +2754,11 @@ execute (void) X_OK, 0); if (string) commands[n_commands].argv[0] = string; + /* APPLE LOCAL begin radar 2466994 - pass linker output through c++filt ilr */ + else if (strcmp (commands[n_commands].prog, "c++filt3") == 0 + && access ("/usr/bin/c++filt3", X_OK) != 0) + continue; + /* APPLE LOCAL end radar 2466994 - pass linker output through c++filt ilr */ n_commands++; } @@ -2672,7 +2766,8 @@ execute (void) /* If -v, print what we are about to do, and maybe query. */ - if (verbose_flag) + /* APPLE LOCAL 3313335 */ + if (verbose_flag || cc_print_options) { /* For help listings, put a blank line between sub-processes. */ if (print_help_list) @@ -2683,29 +2778,50 @@ execute (void) { const char *const *j; - if (verbose_only_flag) + /* APPLE LOCAL begin 3313335 and 3360444 */ + 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 3313335 and 3360444 */ } fflush (stderr); if (verbose_only_flag != 0) @@ -2764,6 +2880,17 @@ execute (void) char *errmsg_fmt, *errmsg_arg; const char *string = commands[i].argv[0]; + /* APPLE LOCAL begin 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 2920964 */ /* 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, @@ -2803,6 +2930,16 @@ execute (void) int status; int pid; + /* APPLE LOCAL begin 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 2920964 */ pid = pwait (commands[i].pid, &status, 0); if (pid < 0) abort (); @@ -2907,6 +3044,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. */ @@ -2920,6 +3065,22 @@ int n_infiles; static bool combine_inputs; +/* True if input files are assembly files. (.s or .S extension) */ +static bool assembly_input; + +/* True if "-c" appears on commandline. */ +static int have_c = 0; + +/* True if "-o" appears on commandline. */ + +static int have_o = 0; + +/* 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; + /* 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. */ @@ -3106,8 +3267,6 @@ process_command (int argc, const char **argv) char *temp1; const char *spec_lang = 0; int last_language_n_infiles; - int have_c = 0; - int have_o = 0; int lang_n_infiles = 0; #ifdef MODIFY_TARGET_NAME int is_modify_target_name; @@ -3133,6 +3292,13 @@ process_command (int argc, const char **argv) } } + /* APPLE LOCAL begin */ + /* 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, &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] == '-' @@ -3336,6 +3502,24 @@ process_command (int argc, const char **argv) } } + /* APPLE LOCAL begin constant cfstrings */ + /* 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 constant cfstrings */ + /* Convert new-style -- options to old-style. */ translate_options (&argc, (const char *const **) &argv); @@ -3391,8 +3575,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 2920964 */ +#if 0 + /* Our assembler and linkder do not support --help. */ + /* APPLE LOCAL end 2920964 */ add_assembler_option ("--help", 6); add_linker_option ("--help", 6); + /* APPLE LOCAL begin 2920964 */ +#endif + /* APPLE LOCAL end 2920964 */ } else if (strcmp (argv[i], "-ftarget-help") == 0) { @@ -3509,6 +3700,46 @@ 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], "-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 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 3235250 */ + /* APPLE LOCAL begin Symbol Separation */ + else if (strcmp (argv[i], "-save-repository") == 0) + { + if (i + 1 == argc) + fatal ("argument to `-save-repository' is missing"); + + n_infiles++; + i++; + } + /* APPLE LOCAL end Symbol Separation */ else if (strcmp (argv[i], "-specs") == 0) { struct user_specs *user = xmalloc (sizeof (struct user_specs)); @@ -3555,6 +3786,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 framework */ + else if (strcmp (argv[i], "-framework") == 0) + { + if (i + 1 == argc) + fatal ("argument to `-framework' is missing"); + + n_infiles += 2; + i++; + } + /* APPLE LOCAL end framework */ else if (argv[i][0] == '-' && argv[i][1] != 0) { const char *p = &argv[i][1]; @@ -3744,8 +3991,6 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" } } - combine_inputs = (have_c && have_o && lang_n_infiles > 1); - if ((save_temps_flag || report_times) && use_pipes) { /* -save-temps overrides -pipe, so that temp files are produced */ @@ -3844,6 +4089,30 @@ 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; + } + else + add_preprocessor_option ("-D__CONSTANT_CFSTRINGS__", 24); + } + /* Synthesize the deployment target manifest constant. */ + if (macosx_version_min_required) + { + char macro_def[40]; + + sprintf (macro_def, "-DMAC_OS_X_VERSION_MIN_REQUIRED=%d", macosx_version_min_required); + add_preprocessor_option (macro_def, strlen (macro_def)); + } + /* APPLE LOCAL end constant cfstrings */ + /* Then create the space for the vectors and scan again. */ switches = xmalloc ((n_switches + 1) * sizeof (struct switchstr)); @@ -3950,14 +4219,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 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 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 framework */ + 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 framework */ else if (argv[i][0] == '-' && argv[i][1] != 0) { const char *p = &argv[i][1]; @@ -4185,6 +4502,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 begin %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. */ @@ -4205,6 +4530,9 @@ do_spec (const char *spec) { int value; + /* APPLE LOCAL %b/save-temps can clobber input file (radar 2871891) ilr */ + this_is_basename_derived_file = 0; + value = do_spec_2 (spec); /* Force out any unfinished command. @@ -4223,6 +4551,82 @@ 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 (string) + 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) { @@ -4375,9 +4779,15 @@ 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) + /* APPLE LOCAL end %b/save-temps can clobber input file (radar 2871891) ilr */ string = find_file (string); - store_arg (string, delete_this_arg, this_is_output_file); + /* APPLE LOCAL %b/save-temps can clobber input file (radar 2871891) ilr */ + store_arg (string, delete_this_arg, this_is_output_file + || this_is_basename_derived_file); if (this_is_output_file) outfiles[input_file_number] = string; } @@ -4410,6 +4820,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; @@ -4420,9 +4832,15 @@ 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) + /* APPLE LOCAL end %b/save-temps can clobber input file (radar 2871891) ilr */ string = find_file (string); - store_arg (string, delete_this_arg, this_is_output_file); + /* APPLE LOCAL radar 2871891 - %b/%B & -save-temps can clobber input file ilr */ + store_arg (string, delete_this_arg, this_is_output_file + || this_is_basename_derived_file); if (this_is_output_file) outfiles[input_file_number] = string; } @@ -4439,9 +4857,15 @@ 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) + /* APPLE LOCAL end %b/save-temps can clobber input file (radar 2871891) ilr */ string = find_file (string); - store_arg (string, delete_this_arg, this_is_output_file); + /* APPLE LOCAL %b/save-temps can clobber input file (radar 2871891) ilr */ + store_arg (string, delete_this_arg, this_is_output_file + || this_is_basename_derived_file); if (this_is_output_file) outfiles[input_file_number] = string; } @@ -4449,6 +4873,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; @@ -4459,11 +4885,14 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) fatal ("invalid specification! Bug in cc"); 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; case 'B': + /* APPLE LOCAL %b/save-temps can clobber input file (radar 2871891) ilr */ obstack_grow (&obstack, input_basename, suffixed_basename_length); arg_going = 1; break; @@ -4751,6 +5180,11 @@ 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 */ + /* Create new temp file for each source file. */ + && strcmp (suffix, ".i") + && strcmp (suffix, ".ii") + /* APPLE LOCAL end IMA */ && strncmp (t->suffix, suffix, suffix_length) == 0 && t->unique == (c == 'u' || c == 'U' || c == 'j')) break; @@ -4778,22 +5212,33 @@ 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; case 'i': +/* APPLE LOCAL begin IMI */ if (combine_inputs) { for (i = 0; (int) i < n_infiles; i++) - store_arg (infiles[i].name, 0, 0); + if ((!infiles[i].language) || (infiles[i].language[0] != '*')) + if (infiles[i].incompiler == input_file_compiler) + { + store_arg (infiles[i].name, 0, 0); + infiles[i].compiled = TRUE; + } +/* APPLE LOCAL end IMI */ } else { @@ -4838,6 +5283,45 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) } break; + /* APPLE LOCAL begin framework headers */ + case 'Q': +#ifdef FRAMEWORK_HEADERS + { + struct prefix_list *dfpl = default_framework_paths.plist; + + for (; dfpl; dfpl = dfpl->next) + { + char *tmpstr = xmalloc (strlen (dfpl->prefix) + 5); + sprintf (tmpstr, "-F%s", dfpl->prefix); + do_spec_1 (tmpstr, 1, NULL); + do_spec_1 (" ", 0, NULL); /* fh */ + free (tmpstr); + } + } +#endif /* FRAMEWORK_HEADERS */ + break; + /* APPLE LOCAL end framework headers */ + + /* 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 ("-fconstant-cfstrings", 1, NULL); + do_spec_1 (" ", 0, NULL); + } + } + else + abort (); + } + break; + /* APPLE LOCAL end constant cfstrings */ + case 'o': { int max = n_infiles; @@ -5941,6 +6425,11 @@ main (int argc, const char **argv) const char *p; struct user_specs *uptr; + /* APPLE LOCAL begin 3313335 */ + cc_print_options = getenv ("CC_PRINT_OPTIONS"); + cc_print_options_filename = getenv ("CC_PRINT_OPTIONS_FILE"); + /* APPLE LOCAL end 3313335 */ + p = argv[0] + strlen (argv[0]); while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1])) --p; @@ -6330,28 +6819,136 @@ main (int argc, const char **argv) explicit_link_files = xcalloc (1, n_infiles); - if (combine_inputs) +/* APPLE LOCAL begin IMI */ { int lang_n_infiles = 0; + bool singular_input_language = TRUE; for (i = 0; (int) i < n_infiles; i++) { const char *name = infiles[i].name; - struct compiler *compiler - = lookup_compiler (name, strlen (name), infiles[i].language); - if (compiler == NULL) - error ("%s: linker input file unused because linking not done", - name); - else if (lang_n_infiles > 0 && compiler != input_file_compiler) - fatal ("cannot specify -o with -c or -S and multiple languages"); - else + struct compiler *compiler = lookup_compiler (name, strlen (name), infiles[i].language); + if (lang_n_infiles > 0 && compiler != input_file_compiler + && infiles[i].language && infiles[i].language[0] != '*') + { + singular_input_language = FALSE; + infiles[i].incompiler = compiler; + } + else if (infiles[i].language && infiles[i].language[0] == '*') + { + explicit_link_files[i] = 1; + infiles[i].incompiler = NULL; + } + else if (compiler) { lang_n_infiles++; input_file_compiler = compiler; + infiles[i].incompiler = compiler; } + else + { + /* Since there is no compiler for this input file, assume it is a + linker file. */ + explicit_link_files[i] = 1; + infiles[i].incompiler = NULL; + } + infiles[i].compiled = FALSE; + infiles[i].preprocessed = FALSE; } } - for (i = 0; (int) i < (combine_inputs ? 1 : n_infiles); i++) + if (save_temps_flag || traditional_cpp_flag || capital_e_flag) + { + /* Must do a separate pre-processing pass for C & Objective-C files, to + obtain individual .i files. */ + + for (i=0; (int) i < n_infiles; i++) + { + int this_file_error = 0; + + input_file_number = i; + set_input (infiles[i].name); + if ((infiles[i].incompiler) + && (strcmp(infiles[i].incompiler->suffix, "@c") == 0 + || strcmp (infiles[i].incompiler->suffix, ".m") == 0 + || strcmp (infiles[i].incompiler->suffix, ".c") == 0)) + { + input_file_compiler = infiles[i].incompiler; + } + else + continue; + + /* outfiles[i] = input_filename;*/ + + if (input_file_compiler) + { + { + value = do_spec (input_file_compiler->spec); + infiles[i].preprocessed = TRUE; + + if (infiles[i].preprocessed && !capital_e_flag) + { + if (save_temps_flag) + { + char *name = (char *) xmalloc ((strlen(infiles[i].name) + 1) + * sizeof (char)); + char *dot, *p; + strcpy (name, infiles[i].name); + dot = strrchr (name, '.'); + dot++; + if (*dot == 'c') + *dot = 'i'; + else if (*dot == 'm') + { + dot++; + *dot = 'i'; + dot++; + *dot = '\0'; + } + + infiles[i].incompiler = lookup_compiler (name, + strlen (name), + infiles[i].language); + + /* Save temps files are created in current working directory. + Extract basename by removing directory names from input + file name. */ + for (p = name; *p; p++) + if (IS_DIR_SEPARATOR (*p)) + name = p + 1; + infiles[i].name = name; + + } + 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; + break; + } + } + + } + + if (this_file_error) + { + delete_failure_queue (); + error_count++; + } + clear_failure_queue (); + } + } +/* APPLE LOCAL end IMI */ + + for (i = 0; (int) i < n_infiles; i++) { int this_file_error = 0; @@ -6360,16 +6957,49 @@ main (int argc, const char **argv) input_file_number = i; set_input (infiles[i].name); - /* Use the same thing in %o, unless cp->spec says otherwise. */ +/* APPLE LOCAL begin IMI */ - outfiles[i] = input_filename; + if (infiles[i].compiled) + continue; + else + { + const char *name = infiles[i].name; + char *dot = strrchr (name, '.'); + int len = strlen (name); + char *ext = (char *) xmalloc (len*sizeof(char)); + + if (dot) + strcpy (ext, dot); + else + ext[0] = '\0'; + + /* IMI currently only works for C and Objective-C, so make sure the + source file belongs to one of those, or don't attempt IMI. */ - /* Figure out which compiler from the file's suffix. */ + if ((strcmp (ext, ".m") == 0) + || (strcmp (ext, ".c") == 0) + || (strcmp (ext, ".i") == 0) + || (strcmp (ext, ".s") == 0) + || (strcmp (ext, ".S") == 0)) + combine_inputs = TRUE; + else + combine_inputs = FALSE; + + if (combine_inputs) + { + if ((strcmp (ext, ".s") == 0) || strcmp (ext, ".S") == 0) + assembly_input = TRUE; + else + assembly_input = FALSE; + } + input_file_compiler = infiles[i].incompiler; + } - if (! combine_inputs) - input_file_compiler - = lookup_compiler (infiles[i].name, input_filename_length, - infiles[i].language); +/* APPLE LOCAL end IMI */ + + /* Use the same thing in %o, unless cp->spec says otherwise. */ + + outfiles[i] = input_filename; if (input_file_compiler) { @@ -6381,9 +7011,18 @@ 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 || assembly_input || !combine_inputs) + /* APPLE LOCAL end IMA */ { value = do_spec (input_file_compiler->spec); + infiles[i].compiled = true; if (value < 0) this_file_error = 1; } @@ -6448,7 +7087,8 @@ main (int argc, const char **argv) value = do_spec (link_command_spec); if (value < 0) - error_count = 1; + error_count = 1; + linker_was_run = (tmp != execution_count); } @@ -6536,6 +7176,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; |