aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcc.c
diff options
context:
space:
mode:
authorCaroline Tice <ctice@apple.com>2004-04-05 19:23:27 +0000
committerCaroline Tice <ctice@gcc.gnu.org>2004-04-05 12:23:27 -0700
commit0855eab7a30bb98dc47a4a23de3dc1da85503bfb (patch)
tree54ddbad12efc3bc6774bcd0268a91392513224da /gcc/gcc.c
parent26be75dbef9e280475d6fdbd3f38955d511ca02d (diff)
downloadgcc-0855eab7a30bb98dc47a4a23de3dc1da85503bfb.zip
gcc-0855eab7a30bb98dc47a4a23de3dc1da85503bfb.tar.gz
gcc-0855eab7a30bb98dc47a4a23de3dc1da85503bfb.tar.bz2
gcc.c (combine_flag): New global variable, for new driver option.
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. From-SVN: r80435
Diffstat (limited to 'gcc/gcc.c')
-rw-r--r--gcc/gcc.c210
1 files changed, 163 insertions, 47 deletions
diff --git a/gcc/gcc.c b/gcc/gcc.c
index d69d78a..f90cba3 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;
+ }
}
}