diff options
author | ctice <ctice@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-04-05 19:23:27 +0000 |
---|---|---|
committer | ctice <ctice@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-04-05 19:23:27 +0000 |
commit | dc1dd09bb3af8958e470da36dea9cb9085a2ffb1 (patch) | |
tree | 54ddbad12efc3bc6774bcd0268a91392513224da /gcc/gcc.c | |
parent | 5e016e74046c113b230056dd4674eef736b322bb (diff) | |
download | gcc-dc1dd09bb3af8958e470da36dea9cb9085a2ffb1.tar.gz |
2004-04-05 Caroline Tice <ctice@apple.com>
* gcc.c (combine_flag): New global variable, for new driver option.
(struct compiler): Add two new fields, to be used when
combining multiple input files in a single pass (IMA).
(default_compilers): Add values for the new fields to all
compiler entries. Modify the "@c" compiler entry for doing IMA
properly with "-save-temps" and the "combine" flag.
(option_map): Add new driver option, "--combine", to tell driver
to pass multiple input files to compiler at one time.
(have_o_argbuf_index): New global variable.
(store_arg): Modify to assign value to have_o_argbuf_index.
(struct infile): Add three new fields, to help with IMA.
(display_help): Add help for new "combine" option.
(process_command): Remove local variable have_o; add code to check
for new "combine" option; remove assignment to combine_inputs.
(do_spec_1): Modify to deal with IMA better.
(main): Make variable 'lang_n_infiles' local to entire function
rather than to a single block. Use flag combine_flag to
determine whether to do IMA or not; Modify loop initializing
infiles to deal properly with linker files.
Add code for doing preprocessing in presence of
IMA with "-save-temps" flag. Modify "main" loop to handle
multiple input files, in multiple languages, with or without
preprocessing, gracefully.
* toplev.c (set_src_pwd): Modify to not complain if attempting to
re-set it to same directory it's previously been set to (avoid
irritating, meaningless warning messages when doing IMA with
save-temps).
* doc/invoke.texi: Add "-combine" to list of Overall Options;
remove documentation about IMA that is no longer accurate; Add
documentation explaining what "-combine" does.
* ada/lang-specs.h: Add initialization values for new fields in
"struct compiler".
* cp/lang-specs.h: Likewise.
* f/lang-specs.h: Likewise.
* java/lang-specs.h: Likewise.
* objc/lang-specs.h: Likewise.
* treelang/lang-specs.h: Likewise.
Fix gcc driver to work properly with IMI.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@80435 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r-- | gcc/gcc.c | 210 |
1 files changed, 163 insertions, 47 deletions
diff --git a/gcc/gcc.c b/gcc/gcc.c index d69d78a0d03..f90cba3d136 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -218,6 +218,10 @@ static const char *target_sysroot_hdrs_suffix = 0; static int save_temps_flag; +/* Nonzero means pass multiple source files to the compiler at one time. */ + +static int combine_flag = 0; + /* Nonzero means use pipes to communicate between subprocesses. Overridden by either of the above two flags. */ @@ -861,6 +865,10 @@ struct compiler const char *cpp_spec; /* If non-NULL, substitute this spec for `%C', rather than the usual cpp_spec. */ + const int combinable; /* If non-zero, compiler can deal with + multiple source files at once (IMA). */ + const int needs_preprocessing; /* If non-zero, source files need to + be run through a preprocessor. */ }; /* Pointer to a vector of `struct compiler' that gives the spec for @@ -886,19 +894,21 @@ static const struct compiler default_compilers[] = were not present when we built the driver, we will hit these copies and be given a more meaningful error than "file not used since linking is not done". */ - {".m", "#Objective-C", 0}, {".mi", "#Objective-C", 0}, - {".cc", "#C++", 0}, {".cxx", "#C++", 0}, {".cpp", "#C++", 0}, - {".cp", "#C++", 0}, {".c++", "#C++", 0}, {".C", "#C++", 0}, - {".CPP", "#C++", 0}, {".ii", "#C++", 0}, - {".ads", "#Ada", 0}, {".adb", "#Ada", 0}, - {".f", "#Fortran", 0}, {".for", "#Fortran", 0}, {".fpp", "#Fortran", 0}, - {".F", "#Fortran", 0}, {".FOR", "#Fortran", 0}, {".FPP", "#Fortran", 0}, - {".r", "#Ratfor", 0}, - {".p", "#Pascal", 0}, {".pas", "#Pascal", 0}, - {".java", "#Java", 0}, {".class", "#Java", 0}, - {".zip", "#Java", 0}, {".jar", "#Java", 0}, + {".m", "#Objective-C", 0, 0, 0}, {".mi", "#Objective-C", 0, 0, 0}, + {".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0}, + {".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0}, + {".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0}, + {".CPP", "#C++", 0, 0, 0}, {".ii", "#C++", 0, 0, 0}, + {".ads", "#Ada", 0, 0, 0}, {".adb", "#Ada", 0, 0, 0}, + {".f", "#Fortran", 0, 0, 0}, {".for", "#Fortran", 0, 0, 0}, + {".fpp", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0}, + {".FOR", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0}, + {".r", "#Ratfor", 0, 0, 0}, + {".p", "#Pascal", 0, 0, 0}, {".pas", "#Pascal", 0, 0, 0}, + {".java", "#Java", 0, 0, 0}, {".class", "#Java", 0, 0, 0}, + {".zip", "#Java", 0, 0, 0}, {".jar", "#Java", 0, 0, 0}, /* Next come the entries for C. */ - {".c", "@c", 0}, + {".c", "@c", 0, 1, 1}, {"@c", /* cc1 has an integrated ISO C preprocessor. We should invoke the external preprocessor if -save-temps is given. */ @@ -906,17 +916,24 @@ static const struct compiler default_compilers[] = %{!E:%{!M:%{!MM:\ %{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} \ %(cc1_options)}\ %{!save-temps:%{!traditional-cpp:%{!no-integrated-cpp:\ cc1 %(cpp_unique_options) %(cc1_options)}}}\ - %{!fsyntax-only:%(invoke_as)}}}}", 0}, + %{!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}, {"-", "%{!E:%e-E required when input is from standard input}\ - %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0}, - {".h", "@c-header", 0}, + %(trad_capable_cpp) %(cpp_options) %(cpp_debug_options)", 0, 0, 0}, + {".h", "@c-header", 0, 0, 0}, {"@c-header", /* cc1 has an integrated ISO C preprocessor. We should invoke the external preprocessor if -save-temps is given. */ @@ -931,14 +948,14 @@ static const struct compiler default_compilers[] = %{!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}, - {".i", "@cpp-output", 0}, + %W{o*:--output-pch=%*}%V}}}}}}", 0, 0, 0}, + {".i", "@cpp-output", 0, 1, 0}, {"@cpp-output", "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0}, - {".s", "@assembler", 0}, + {".s", "@assembler", 0, 1, 0}, {"@assembler", - "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0}, - {".S", "@assembler-with-cpp", 0}, + "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 1, 0}, + {".S", "@assembler-with-cpp", 0, 1, 0}, {"@assembler-with-cpp", #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT "%(trad_capable_cpp) -lang-asm %(cpp_options)\ @@ -951,11 +968,11 @@ static const struct compiler default_compilers[] = %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\ as %(asm_debug) %(asm_options) %m.s %A }}}}" #endif - , 0}, + , 0, 1, 0}, #include "specs.h" /* Mark end of table. */ - {0, 0, 0} + {0, 0, 0, 0, 0} }; /* Number of elements in default_compilers, not counting the terminator. */ @@ -1009,6 +1026,7 @@ static const struct option_map option_map[] = {"--classpath", "-fclasspath=", "aj"}, {"--bootclasspath", "-fbootclasspath=", "aj"}, {"--CLASSPATH", "-fclasspath=", "aj"}, + {"--combine", "-combine", 0}, {"--comments", "-C", 0}, {"--comments-in-macros", "-CC", 0}, {"--compile", "-c", 0}, @@ -1778,6 +1796,11 @@ static int argbuf_length; static int argbuf_index; +/* Position in the argbuf array containing the name of the output file + (the value associated with the "-o" flag). */ + +static int have_o_argbuf_index = 0; + /* This is the list of suffixes and codes (%g/%u/%U/%j) and the associated temp file. If the HOST_BIT_BUCKET is used for %j, no entry is made for it here. */ @@ -1836,6 +1859,8 @@ store_arg (const char *arg, int delete_always, int delete_failure) argbuf[argbuf_index++] = arg; argbuf[argbuf_index] = 0; + if (strcmp (arg, "-o") == 0) + have_o_argbuf_index = argbuf_index; if (delete_always || delete_failure) record_temp_file (arg, delete_always, delete_failure); } @@ -2891,6 +2916,9 @@ struct infile { const char *name; const char *language; + struct compiler *incompiler; + bool compiled; + bool preprocessed; }; /* Also a vector of input files specified. */ @@ -3005,6 +3033,7 @@ display_help (void) fputs (_(" -Xassembler <arg> Pass <arg> on to the assembler\n"), stdout); fputs (_(" -Xpreprocessor <arg> Pass <arg> on to the preprocessor\n"), stdout); fputs (_(" -Xlinker <arg> Pass <arg> 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 (_(" -pipe Use pipes rather than intermediate files\n"), stdout); fputs (_(" -time Time the execution of each subprocess\n"), stdout); @@ -3091,7 +3120,6 @@ process_command (int argc, const char **argv) 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; @@ -3493,6 +3521,11 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" save_temps_flag = 1; n_switches++; } + else if (strcmp (argv[i], "-combine") == 0) + { + combine_flag = 1; + n_switches++; + } else if (strcmp (argv[i], "-specs") == 0) { struct user_specs *user = xmalloc (sizeof (struct user_specs)); @@ -3635,7 +3668,6 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n" goto normal_switch; case 'o': - have_o = 1; #if defined(HAVE_TARGET_EXECUTABLE_SUFFIX) if (! have_c) { @@ -3728,8 +3760,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 */ @@ -4777,7 +4807,12 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part) 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; + } } else { @@ -5919,6 +5954,7 @@ main (int argc, const char **argv) size_t i; int value; int linker_was_run = 0; + int lang_n_infiles = 0; int num_linker_inputs = 0; char *explicit_link_files; char *specs_file; @@ -6314,28 +6350,99 @@ main (int argc, const char **argv) explicit_link_files = xcalloc (1, n_infiles); - if (combine_inputs) + if (combine_flag) + combine_inputs = true; + else + combine_inputs = false; + + for (i = 0; (int) i < n_infiles; i++) { - int lang_n_infiles = 0; - 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 - { - lang_n_infiles++; - input_file_compiler = compiler; - } - } + const char *name = infiles[i].name; + struct compiler *compiler = lookup_compiler (name, + strlen (name), + infiles[i].language); + + if (compiler && !(compiler->combinable)) + combine_inputs = false; + + if (lang_n_infiles > 0 && compiler != input_file_compiler + && infiles[i].language && infiles[i].language[0] != '*') + infiles[i].incompiler = compiler; + 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 (combine_flag && save_temps_flag) + { + bool save_combine_inputs = combine_inputs; + /* Must do a separate pre-processing pass for C & Objective-C files, to + obtain individual .i files. */ + + combine_inputs = false; + 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 + && (infiles[i].incompiler)->needs_preprocessing) + input_file_compiler = infiles[i].incompiler; + else + continue; + + if (input_file_compiler) + { + if (input_file_compiler->spec[0] == '#') + { + error ("%s: %s compiler not installed on this system", + input_filename, &input_file_compiler->spec[1]); + this_file_error = 1; + } + else + { + 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); + + if (value < 0) + { + this_file_error = 1; + break; + } + } + } + + if (this_file_error) + { + delete_failure_queue (); + error_count++; + } + clear_failure_queue (); + } + combine_inputs = save_combine_inputs; + } + + for (i = 0; (int) i < n_infiles; i++) { int this_file_error = 0; @@ -6344,6 +6451,9 @@ main (int argc, const char **argv) input_file_number = i; set_input (infiles[i].name); + if (infiles[i].compiled) + continue; + /* Use the same thing in %o, unless cp->spec says otherwise. */ outfiles[i] = input_filename; @@ -6354,6 +6464,8 @@ main (int argc, const char **argv) input_file_compiler = lookup_compiler (infiles[i].name, input_filename_length, infiles[i].language); + else + input_file_compiler = infiles[i].incompiler; if (input_file_compiler) { @@ -6368,8 +6480,12 @@ main (int argc, const char **argv) else { value = do_spec (input_file_compiler->spec); + infiles[i].compiled = true; if (value < 0) - this_file_error = 1; + { + this_file_error = 1; + break; + } } } |