X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fgcc.c;h=0636579644ff545c63e7d3aff3f060c31f88cbc4;hb=ff84f6db4f5156191531c8d5226bd0ccfc12cf2a;hp=7a5056a5ba02f9295434971fbb00c81c6bb7297d;hpb=6ea4242fb368994f583943b9cffdd14675cb6ad8;p=pf3gnuchains%2Fgcc-fork.git
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 7a5056a5ba0..0636579644f 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1,13 +1,13 @@
/* Compiler driver program that can handle many languages.
Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING. If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.
+along with GCC; see the file COPYING3. If not see
+.
This paragraph is here to try to keep Sun CC from dying.
The number of chars here seems crucial!!!! */
@@ -127,6 +126,9 @@ static const char dir_separator_str[] = { DIR_SEPARATOR, 0 };
/* Flag set by cppspec.c to 1. */
int is_cpp_driver;
+/* Flag set to nonzero if an @file argument has been supplied to gcc. */
+static bool at_file_supplied;
+
/* Flag saying to pass the greatest exit code returned by a sub-process
to the calling program. */
static int pass_exit_codes;
@@ -295,6 +297,7 @@ static void set_spec (const char *, const char *);
static struct compiler *lookup_compiler (const char *, size_t, const char *);
static char *build_search_list (const struct path_prefix *, const char *,
bool, bool);
+static void xputenv (const char *);
static void putenv_from_prefixes (const struct path_prefix *, const char *,
bool);
static int access_check (const char *, int);
@@ -361,6 +364,7 @@ static const char *if_exists_else_spec_function (int, const char **);
static const char *replace_outfile_spec_function (int, const char **);
static const char *version_compare_spec_function (int, const char **);
static const char *include_spec_function (int, const char **);
+static const char *print_asm_header_spec_function (int, const char **);
/* The Specs Language
@@ -516,15 +520,18 @@ or with constant text in a single argument.
part of that switch that matched the '*'.
%{.S:X} substitutes X, if processing a file with suffix S.
%{!.S:X} substitutes X, if NOT processing a file with suffix S.
-
+ %{,S:X} substitutes X, if processing a file which will use spec S.
+ %{!,S:X} substitutes X, if NOT processing a file which will use spec S.
+
%{S|T:X} substitutes X if either -S or -T was given to CC. This may be
- combined with !, ., and * as above binding stronger than the OR.
+ combined with '!', '.', ',', and '*' as above binding stronger
+ than the OR.
If %* appears in X, all of the alternatives must be starred, and
only the first matching alternative is substituted.
%{S:X; if S was given to CC, substitutes X;
T:Y; else if T was given to CC, substitutes Y;
:D} else substitutes D. There can be as many clauses as you need.
- This may be combined with ., !, |, and * as above.
+ This may be combined with '.', '!', ',', '|', and '*' as above.
%(Spec) processes a specification defined in a specs file as *Spec:
%[Spec] as above, but put __ around -D arguments
@@ -649,21 +656,27 @@ proper position among the other output files. */
#define LINKER_NAME "collect2"
#endif
+#ifdef HAVE_AS_DEBUG_PREFIX_MAP
+#define ASM_MAP " %{fdebug-prefix-map=*:--debug-prefix-map %*}"
+#else
+#define ASM_MAP ""
+#endif
+
/* Define ASM_DEBUG_SPEC to be a spec suitable for translating '-g'
to the assembler. */
#ifndef ASM_DEBUG_SPEC
# if defined(DBX_DEBUGGING_INFO) && defined(DWARF2_DEBUGGING_INFO) \
&& defined(HAVE_AS_GDWARF2_DEBUG_FLAG) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
-# define ASM_DEBUG_SPEC \
- (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG \
- ? "%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}" \
- : "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}")
+# define ASM_DEBUG_SPEC \
+ (PREFERRED_DEBUGGING_TYPE == DBX_DEBUG \
+ ? "%{gdwarf-2*:--gdwarf2}%{!gdwarf-2*:%{g*:--gstabs}}" ASM_MAP \
+ : "%{gstabs*:--gstabs}%{!gstabs*:%{g*:--gdwarf2}}" ASM_MAP)
# else
# if defined(DBX_DEBUGGING_INFO) && defined(HAVE_AS_GSTABS_DEBUG_FLAG)
-# define ASM_DEBUG_SPEC "%{g*:--gstabs}"
+# define ASM_DEBUG_SPEC "%{g*:--gstabs}" ASM_MAP
# endif
# if defined(DWARF2_DEBUGGING_INFO) && defined(HAVE_AS_GDWARF2_DEBUG_FLAG)
-# define ASM_DEBUG_SPEC "%{g*:--gdwarf2}"
+# define ASM_DEBUG_SPEC "%{g*:--gdwarf2}" ASM_MAP
# endif
# endif
#endif
@@ -708,7 +721,7 @@ proper position among the other output files. */
%(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\
- %{fopenmp:%:include(libgomp.spec)%(link_gomp)} %(mflib)\
+ %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)} %(mflib)\
%{fprofile-arcs|fprofile-generate|coverage:-lgcov}\
%{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
@@ -781,7 +794,7 @@ static const char *cpp_unique_options =
%{MD:-MD %{!o:%b.d}%{o*:%.d%*}}\
%{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
%{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
- %{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
+ %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}}\
%{remap} %{g3|ggdb3|gstabs3|gcoff3|gxcoff3|gvms3:-dD}\
%{H} %C %{D*&U*&A*} %{i*} %Z %i\
%{fmudflap:-D_MUDFLAP -include mf-runtime.h}\
@@ -818,6 +831,12 @@ static const char *cc1_options =
%{coverage:-fprofile-arcs -ftest-coverage}";
static const char *asm_options =
+"%{--target-help:%:print-asm-header()} "
+#if HAVE_GNU_AS
+/* If GNU AS is used, then convert -w (no warnings), -I, and -v
+ to the assembler equivalents. */
+"%{v} %{w:-W} %{I*} "
+#endif
"%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
static const char *invoke_as =
@@ -851,7 +870,7 @@ static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
/* Adding -fopenmp should imply pthreads. This is particularly important
for targets that use different start files and suchlike. */
#ifndef GOMP_SELF_SPECS
-#define GOMP_SELF_SPECS "%{fopenmp: -pthread}"
+#define GOMP_SELF_SPECS "%{fopenmp|ftree-parallelize-loops=*: -pthread}"
#endif
static const char *const driver_self_specs[] = {
@@ -947,11 +966,14 @@ static const struct compiler default_compilers[] =
{".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},
- {".f90", "#Fortran", 0, 0, 0}, {".f95", "#Fortran", 0, 0, 0},
- {".F90", "#Fortran", 0, 0, 0}, {".F95", "#Fortran", 0, 0, 0},
+ {".f", "#Fortran", 0, 0, 0}, {".F", "#Fortran", 0, 0, 0},
+ {".for", "#Fortran", 0, 0, 0}, {".FOR", "#Fortran", 0, 0, 0},
+ {".ftn", "#Fortran", 0, 0, 0}, {".FTN", "#Fortran", 0, 0, 0},
+ {".fpp", "#Fortran", 0, 0, 0}, {".FPP", "#Fortran", 0, 0, 0},
+ {".f90", "#Fortran", 0, 0, 0}, {".F90", "#Fortran", 0, 0, 0},
+ {".f95", "#Fortran", 0, 0, 0}, {".F95", "#Fortran", 0, 0, 0},
+ {".f03", "#Fortran", 0, 0, 0}, {".F03", "#Fortran", 0, 0, 0},
+ {".f08", "#Fortran", 0, 0, 0}, {".F08", "#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},
@@ -1004,15 +1026,16 @@ static const struct compiler default_compilers[] =
{".s", "@assembler", 0, 1, 0},
{"@assembler",
"%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 1, 0},
+ {".sx", "@assembler-with-cpp", 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)\
+ "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
%{E|M|MM:%(cpp_debug_options)}\
%{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
as %(asm_debug) %(asm_options) %|.s %A }}}}"
#else
- "%(trad_capable_cpp) -lang-asm %(cpp_options)\
+ "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
%{E|M|MM:%(cpp_debug_options)}\
%{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
as %(asm_debug) %(asm_options) %m.s %A }}}}"
@@ -1614,6 +1637,7 @@ static const struct spec_function static_spec_functions[] =
{ "replace-outfile", replace_outfile_spec_function },
{ "version-compare", version_compare_spec_function },
{ "include", include_spec_function },
+ { "print-asm-header", print_asm_header_spec_function },
#ifdef EXTRA_SPEC_FUNCTIONS
EXTRA_SPEC_FUNCTIONS
#endif
@@ -1698,10 +1722,6 @@ init_spec (void)
}
#endif
- /* Initialize here, not in definition. The IRIX 6 O32 cc sometimes chokes
- on ?: in file-scope variable initializations. */
- asm_debug = ASM_DEBUG_SPEC;
-
for (i = ARRAY_SIZE (static_specs) - 1; i >= 0; i--)
{
sl = &static_specs[i];
@@ -1868,7 +1888,7 @@ set_spec (const char *name, const char *spec)
/* Free the old spec. */
if (old_spec && sl->alloc_p)
- free ((void *) old_spec);
+ free (CONST_CAST(char *, old_spec));
sl->alloc_p = 1;
}
@@ -2173,7 +2193,7 @@ read_specs (const char *filename, int main_p)
set_spec (p2, *(sl->ptr_spec));
if (sl->alloc_p)
- free ((void *) *(sl->ptr_spec));
+ free (CONST_CAST (char *, *(sl->ptr_spec)));
*(sl->ptr_spec) = "";
sl->alloc_p = 0;
@@ -2523,18 +2543,18 @@ for_each_path (const struct path_prefix *paths,
Don't repeat any we have already seen. */
if (multi_dir)
{
- free ((char *) multi_dir);
+ free (CONST_CAST (char *, multi_dir));
multi_dir = NULL;
- free ((char *) multi_suffix);
+ free (CONST_CAST (char *, multi_suffix));
multi_suffix = machine_suffix;
- free ((char *) just_multi_suffix);
+ free (CONST_CAST (char *, just_multi_suffix));
just_multi_suffix = just_machine_suffix;
}
else
skip_multi_dir = true;
if (multi_os_dir)
{
- free ((char *) multi_os_dir);
+ free (CONST_CAST (char *, multi_os_dir));
multi_os_dir = NULL;
}
else
@@ -2543,12 +2563,12 @@ for_each_path (const struct path_prefix *paths,
if (multi_dir)
{
- free ((char *) multi_dir);
- free ((char *) multi_suffix);
- free ((char *) just_multi_suffix);
+ free (CONST_CAST (char *, multi_dir));
+ free (CONST_CAST (char *, multi_suffix));
+ free (CONST_CAST (char *, just_multi_suffix));
}
if (multi_os_dir)
- free ((char *) multi_os_dir);
+ free (CONST_CAST (char *, multi_os_dir));
if (ret != path)
free (path);
return ret;
@@ -2579,6 +2599,16 @@ add_to_obstack (char *path, void *data)
return NULL;
}
+/* Add or change the value of an environment variable, outputting the
+ change to standard error if in verbose mode. */
+static void
+xputenv (const char *string)
+{
+ if (verbose_flag)
+ notice ("%s\n", string);
+ putenv (CONST_CAST (char *, string));
+}
+
/* Build a list of search directories from PATHS.
PREFIX is a string to prepend to the list.
If CHECK_DIR_P is true we ensure the directory exists.
@@ -2613,7 +2643,7 @@ static void
putenv_from_prefixes (const struct path_prefix *paths, const char *env_var,
bool do_multi)
{
- putenv (build_search_list (paths, env_var, true, do_multi));
+ xputenv (build_search_list (paths, env_var, true, do_multi));
}
/* Check whether NAME can be accessed in MODE. This is like access,
@@ -2955,7 +2985,7 @@ execute (void)
errmsg = pex_run (pex,
((i + 1 == n_commands ? PEX_LAST : 0)
| (string == commands[i].prog ? PEX_SEARCH : 0)),
- string, (char * const *) commands[i].argv,
+ string, CONST_CAST (char **, commands[i].argv),
NULL, NULL, &err);
if (errmsg != NULL)
{
@@ -2969,7 +2999,7 @@ execute (void)
}
if (string != commands[i].prog)
- free ((void *) string);
+ free (CONST_CAST (char *, string));
}
execution_count++;
@@ -3055,24 +3085,22 @@ See %s for instructions.",
If a switch uses following arguments, then the `part1' field
is the switch itself and the `args' field
is a null-terminated vector containing the following arguments.
- The `live_cond' field is:
- 0 when initialized
- 1 if the switch is true in a conditional spec,
- -1 if false (overridden by a later switch)
- -2 if this switch should be ignored (used in %part1 = &argbuf[i][1];
sw->args = 0;
- sw->live_cond = SWITCH_OK;
+ sw->live_cond = 0;
sw->validated = 0;
sw->ordering = 0;
}
@@ -4577,7 +4616,6 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
const char *p = spec;
int c;
int i;
- const char *string;
int value;
while ((c = *p++))
@@ -4586,19 +4624,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
switch (inswitch ? 'a' : c)
{
case '\n':
- /* End of line: finish any pending argument,
- then run the pending command if one has been started. */
- if (arg_going)
- {
- obstack_1grow (&obstack, 0);
- string = XOBFINISH (&obstack, const char *);
- if (this_is_library_file)
- string = find_file (string);
- store_arg (string, delete_this_arg, this_is_output_file);
- if (this_is_output_file)
- outfiles[input_file_number] = string;
- }
- arg_going = 0;
+ end_going_arg ();
if (argbuf_index > 0 && !strcmp (argbuf[argbuf_index - 1], "|"))
{
@@ -4632,17 +4658,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
break;
case '|':
- /* End any pending argument. */
- if (arg_going)
- {
- obstack_1grow (&obstack, 0);
- string = XOBFINISH (&obstack, const char *);
- if (this_is_library_file)
- string = find_file (string);
- store_arg (string, delete_this_arg, this_is_output_file);
- if (this_is_output_file)
- outfiles[input_file_number] = string;
- }
+ end_going_arg ();
/* Use pipe */
obstack_1grow (&obstack, c);
@@ -4651,19 +4667,9 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
case '\t':
case ' ':
- /* Space or tab ends an argument if one is pending. */
- if (arg_going)
- {
- obstack_1grow (&obstack, 0);
- string = XOBFINISH (&obstack, const char *);
- if (this_is_library_file)
- string = find_file (string);
- store_arg (string, delete_this_arg, this_is_output_file);
- if (this_is_output_file)
- outfiles[input_file_number] = string;
- }
+ end_going_arg ();
+
/* Reinitialize for a new argument. */
- arg_going = 0;
delete_this_arg = 0;
this_is_output_file = 0;
this_is_library_file = 0;
@@ -4837,12 +4843,14 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
if (save_temps_flag)
{
+ char *tmp;
+
temp_filename_length = basename_length + suffix_length;
- temp_filename = alloca (temp_filename_length + 1);
- strncpy ((char *) temp_filename, input_basename, basename_length);
- strncpy ((char *) temp_filename + basename_length, suffix,
- suffix_length);
- *((char *) temp_filename + temp_filename_length) = '\0';
+ tmp = alloca (temp_filename_length + 1);
+ strncpy (tmp, input_basename, basename_length);
+ strncpy (tmp + basename_length, suffix, suffix_length);
+ tmp[temp_filename_length] = '\0';
+ temp_filename = tmp;
if (strcmp (temp_filename, input_filename) != 0)
{
#ifndef HOST_LACKS_INODE_NUMBERS
@@ -5003,9 +5011,63 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
int max = n_infiles;
max += lang_specific_extra_outfiles;
- for (i = 0; i < max; i++)
- if (outfiles[i])
- store_arg (outfiles[i], 0, 0);
+ if (HAVE_GNU_LD && at_file_supplied)
+ {
+ /* We are going to expand `%o' to `@FILE', where FILE
+ is a newly-created temporary filename. The filenames
+ that would usually be expanded in place of %o will be
+ written to the temporary file. */
+
+ char *temp_file = make_temp_file ("");
+ char *at_argument;
+ char **argv;
+ int n_files, j, status;
+ FILE *f;
+
+ at_argument = concat ("@", temp_file, NULL);
+ store_arg (at_argument, 0, 0);
+
+ /* Convert OUTFILES into a form suitable for writeargv. */
+
+ /* Determine how many are non-NULL. */
+ for (n_files = 0, i = 0; i < max; i++)
+ n_files += outfiles[i] != NULL;
+
+ argv = alloca (sizeof (char *) * (n_files + 1));
+
+ /* Copy the strings over. */
+ for (i = 0, j = 0; i < max; i++)
+ if (outfiles[i])
+ {
+ argv[j] = CONST_CAST (char *, outfiles[i]);
+ j++;
+ }
+ argv[j] = NULL;
+
+ f = fopen (temp_file, "w");
+
+ if (f == NULL)
+ fatal ("could not open temporary response file %s",
+ temp_file);
+
+ status = writeargv (argv, f);
+
+ if (status)
+ fatal ("could not write to temporary response file %s",
+ temp_file);
+
+ status = fclose (f);
+
+ if (EOF == status)
+ fatal ("could not close temporary response file %s",
+ temp_file);
+
+ record_temp_file (temp_file, !save_temps_flag, !save_temps_flag);
+ }
+ else
+ for (i = 0; i < max; i++)
+ if (outfiles[i])
+ store_arg (outfiles[i], 0, 0);
break;
}
@@ -5035,18 +5097,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
p = handle_braces (p + 1);
if (p == 0)
return -1;
- /* End any pending argument. */
- if (arg_going)
- {
- obstack_1grow (&obstack, 0);
- string = XOBFINISH (&obstack, const char *);
- if (this_is_library_file)
- string = find_file (string);
- store_arg (string, delete_this_arg, this_is_output_file);
- if (this_is_output_file)
- outfiles[input_file_number] = string;
- arg_going = 0;
- }
+ end_going_arg ();
/* If any args were output, mark the last one for deletion
on failure. */
if (argbuf_index != cur_index)
@@ -5239,7 +5290,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
if (!strncmp (switches[i].part1, p, len - have_wildcard)
&& (have_wildcard || switches[i].part1[len] == '\0'))
{
- switches[i].live_cond = SWITCH_IGNORE;
+ switches[i].live_cond |= SWITCH_IGNORE;
switches[i].validated = 1;
}
@@ -5365,17 +5416,8 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
/* End of string. If we are processing a spec function, we need to
end any pending argument. */
- if (processing_spec_function && arg_going)
- {
- obstack_1grow (&obstack, 0);
- string = XOBFINISH (&obstack, const char *);
- if (this_is_library_file)
- string = find_file (string);
- store_arg (string, delete_this_arg, this_is_output_file);
- if (this_is_output_file)
- outfiles[input_file_number] = string;
- arg_going = 0;
- }
+ if (processing_spec_function)
+ end_going_arg ();
return 0;
}
@@ -5529,27 +5571,24 @@ handle_spec_function (const char *p)
static inline bool
input_suffix_matches (const char *atom, const char *end_atom)
{
- /* We special case the semantics of {.s:...} and {.S:...} and their
- negative variants. Instead of testing the input filename suffix,
- we test whether the input source file is an assembler file or an
- assembler-with-cpp file respectively. This allows us to correctly
- handle the -x command line option. */
-
- if (atom + 1 == end_atom
- && input_file_compiler
- && input_file_compiler->suffix)
- {
- if (*atom == 's')
- return !strcmp (input_file_compiler->suffix, "@assembler");
- if (*atom == 'S')
- return !strcmp (input_file_compiler->suffix, "@assembler-with-cpp");
- }
-
return (input_suffix
&& !strncmp (input_suffix, atom, end_atom - atom)
&& input_suffix[end_atom - atom] == '\0');
}
+/* Subroutine of handle_braces. Returns true if the current
+ input file's spec name matches the atom bracketed by ATOM and END_ATOM. */
+static bool
+input_spec_matches (const char *atom, const char *end_atom)
+{
+ return (input_file_compiler
+ && input_file_compiler->suffix
+ && input_file_compiler->suffix[0] != '\0'
+ && !strncmp (input_file_compiler->suffix + 1, atom,
+ end_atom - atom)
+ && input_file_compiler->suffix[end_atom - atom + 1] == '\0');
+}
+
/* Subroutine of handle_braces. Returns true if a switch
matching the atom bracketed by ATOM and END_ATOM appeared on the
command line. */
@@ -5613,6 +5652,7 @@ handle_braces (const char *p)
const char *orig = p;
bool a_is_suffix;
+ bool a_is_spectype;
bool a_is_starred;
bool a_is_negated;
bool a_matched;
@@ -5633,8 +5673,12 @@ handle_braces (const char *p)
goto invalid;
/* Scan one "atom" (S in the description above of %{}, possibly
- with !, ., or * modifiers). */
- a_matched = a_is_suffix = a_is_starred = a_is_negated = false;
+ with '!', '.', '@', ',', or '*' modifiers). */
+ a_matched = false;
+ a_is_suffix = false;
+ a_is_starred = false;
+ a_is_negated = false;
+ a_is_spectype = false;
SKIP_WHITE();
if (*p == '!')
@@ -5643,6 +5687,8 @@ handle_braces (const char *p)
SKIP_WHITE();
if (*p == '.')
p++, a_is_suffix = true;
+ else if (*p == ',')
+ p++, a_is_spectype = true;
atom = p;
while (ISIDNUM(*p) || *p == '-' || *p == '+' || *p == '='
@@ -5660,7 +5706,7 @@ handle_braces (const char *p)
/* Substitute the switch(es) indicated by the current atom. */
ordered_set = true;
if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix
- || atom == end_atom)
+ || a_is_spectype || atom == end_atom)
goto invalid;
mark_matching_switches (atom, end_atom, a_is_starred);
@@ -5679,7 +5725,8 @@ handle_braces (const char *p)
if (atom == end_atom)
{
if (!n_way_choice || disj_matched || *p == '|'
- || a_is_negated || a_is_suffix || a_is_starred)
+ || a_is_negated || a_is_suffix || a_is_spectype
+ || a_is_starred)
goto invalid;
/* An empty term may appear as the last choice of an
@@ -5690,28 +5737,30 @@ handle_braces (const char *p)
}
else
{
- if (a_is_suffix && a_is_starred)
- goto invalid;
-
- if (!a_is_starred)
- disj_starred = false;
-
- /* Don't bother testing this atom if we already have a
- match. */
- if (!disj_matched && !n_way_matched)
- {
- if (a_is_suffix)
- a_matched = input_suffix_matches (atom, end_atom);
- else
- a_matched = switch_matches (atom, end_atom, a_is_starred);
-
- if (a_matched != a_is_negated)
- {
- disj_matched = true;
- d_atom = atom;
- d_end_atom = end_atom;
- }
- }
+ if ((a_is_suffix || a_is_spectype) && a_is_starred)
+ goto invalid;
+
+ if (!a_is_starred)
+ disj_starred = false;
+
+ /* Don't bother testing this atom if we already have a
+ match. */
+ if (!disj_matched && !n_way_matched)
+ {
+ if (a_is_suffix)
+ a_matched = input_suffix_matches (atom, end_atom);
+ else if (a_is_spectype)
+ a_matched = input_spec_matches (atom, end_atom);
+ else
+ a_matched = switch_matches (atom, end_atom, a_is_starred);
+
+ if (a_matched != a_is_negated)
+ {
+ disj_matched = true;
+ d_atom = atom;
+ d_end_atom = end_atom;
+ }
+ }
}
if (*p == ':')
@@ -5859,7 +5908,8 @@ check_live_switch (int switchnum, int prefix_length)
/* If we already processed this switch and determined if it was
live or not, return our past determination. */
if (switches[switchnum].live_cond != 0)
- return switches[switchnum].live_cond > 0;
+ return ((switches[switchnum].live_cond & SWITCH_LIVE) != 0
+ && (switches[switchnum].live_cond & SWITCH_FALSE) == 0);
/* Now search for duplicate in a manner that depends on the name. */
switch (*name)
@@ -5906,7 +5956,7 @@ check_live_switch (int switchnum, int prefix_length)
}
/* Otherwise the switch is live. */
- switches[switchnum].live_cond = SWITCH_LIVE;
+ switches[switchnum].live_cond |= SWITCH_LIVE;
return 1;
}
@@ -5921,7 +5971,7 @@ check_live_switch (int switchnum, int prefix_length)
static void
give_switch (int switchnum, int omit_first_word)
{
- if (switches[switchnum].live_cond == SWITCH_IGNORE)
+ if ((switches[switchnum].live_cond & SWITCH_IGNORE) != 0)
return;
if (!omit_first_word)
@@ -5946,13 +5996,13 @@ give_switch (int switchnum, int omit_first_word)
while (length-- && !IS_DIR_SEPARATOR (arg[length]))
if (arg[length] == '.')
{
- ((char *)arg)[length] = 0;
+ (CONST_CAST(char *, arg))[length] = 0;
dot = 1;
break;
}
do_spec_1 (arg, 1, NULL);
if (dot)
- ((char *)arg)[length] = '.';
+ (CONST_CAST(char *, arg))[length] = '.';
do_spec_1 (suffix_subst, 1, NULL);
}
else
@@ -6080,6 +6130,11 @@ main (int argc, char **argv)
char *specs_file;
const char *p;
struct user_specs *uptr;
+ char **old_argv = argv;
+
+ /* Initialize here, not in definition. The IRIX 6 O32 cc sometimes chokes
+ on ?: in file-scope variable initializations. */
+ asm_debug = ASM_DEBUG_SPEC;
p = argv[0] + strlen (argv[0]);
while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
@@ -6090,6 +6145,10 @@ main (int argc, char **argv)
expandargv (&argc, &argv);
+ /* Determine if any expansions were made. */
+ if (argv != old_argv)
+ at_file_supplied = true;
+
prune_options (&argc, &argv);
#ifdef GCC_DRIVER_HOST_INITIALIZATION
@@ -6173,11 +6232,11 @@ main (int argc, char **argv)
obstack_init (&collect_obstack);
obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1);
obstack_grow (&collect_obstack, argv[0], strlen (argv[0]) + 1);
- putenv (XOBFINISH (&collect_obstack, char *));
+ xputenv (XOBFINISH (&collect_obstack, char *));
#ifdef INIT_ENVIRONMENT
/* Set up any other necessary machine specific environment variables. */
- putenv (INIT_ENVIRONMENT);
+ xputenv (INIT_ENVIRONMENT);
#endif
/* Make a table of what switches there are (switches, n_switches).
@@ -6412,7 +6471,9 @@ main (int argc, char **argv)
{
if (*sysroot_hdrs_suffix_spec)
{
- printf("%s\n", target_sysroot_hdrs_suffix);
+ printf("%s\n", (target_sysroot_hdrs_suffix
+ ? target_sysroot_hdrs_suffix
+ : ""));
return (0);
}
else
@@ -6469,10 +6530,10 @@ main (int argc, char **argv)
if (! strncmp (version_string, compiler_version, n)
&& compiler_version[n] == 0)
- notice ("gcc version %s\n", version_string);
+ notice ("gcc version %s %s\n", version_string, pkgversion_string);
else
- notice ("gcc driver version %s executing gcc version %s\n",
- version_string, compiler_version);
+ notice ("gcc driver version %s %sexecuting gcc version %s\n",
+ version_string, pkgversion_string, compiler_version);
if (n_infiles == 0)
return (0);
@@ -6680,7 +6741,7 @@ main (int argc, char **argv)
/* Run ld to link all the compiler output files. */
- if (num_linker_inputs > 0 && error_count == 0)
+ if (num_linker_inputs > 0 && error_count == 0 && print_subprocess_help < 2)
{
int tmp = execution_count;
@@ -6696,6 +6757,13 @@ main (int argc, char **argv)
putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH", false);
putenv_from_prefixes (&startfile_prefixes, LIBRARY_PATH_ENV, true);
+ if (print_subprocess_help == 1)
+ {
+ printf (_("\nLinker options\n==============\n\n"));
+ printf (_("Use \"-Wl,OPTION\" to pass \"OPTION\""
+ " to the linker.\n\n"));
+ fflush (stdout);
+ }
value = do_spec (link_command_spec);
if (value < 0)
error_count = 1;
@@ -6707,7 +6775,8 @@ main (int argc, char **argv)
if (! linker_was_run && error_count == 0)
for (i = 0; (int) i < n_infiles; i++)
- if (explicit_link_files[i])
+ if (explicit_link_files[i]
+ && !(infiles[i].language && infiles[i].language[0] == '*'))
error ("%s: linker input file unused because linking not done",
outfiles[i]);
@@ -6940,7 +7009,7 @@ next_member:
p++;
SKIP_WHITE ();
- if (*p == '.')
+ if (*p == '.' || *p == ',')
suffix = true, p++;
atom = p;
@@ -7068,7 +7137,7 @@ used_arg (const char *p, int len)
mswitches
= XNEWVEC (struct mswitchstr, n_mdswitches + (n_switches ? n_switches : 1));
for (i = 0; i < n_switches; i++)
- if (switches[i].live_cond != SWITCH_IGNORE)
+ if ((switches[i].live_cond & SWITCH_IGNORE) == 0)
{
int xlen = strlen (switches[i].part1);
for (j = 0; j < cnt; j++)
@@ -7390,7 +7459,7 @@ set_multilib_dir (void)
if (multilib_dir == NULL && multilib_os_dir != NULL
&& strcmp (multilib_os_dir, ".") == 0)
{
- free ((char *) multilib_os_dir);
+ free (CONST_CAST (char *, multilib_os_dir));
multilib_os_dir = NULL;
}
else if (multilib_dir != NULL && multilib_os_dir == NULL)
@@ -7667,6 +7736,9 @@ static const char *
getenv_spec_function (int argc, const char **argv)
{
char *value;
+ char *result;
+ char *ptr;
+ size_t len;
if (argc != 2)
return NULL;
@@ -7675,7 +7747,21 @@ getenv_spec_function (int argc, const char **argv)
if (!value)
fatal ("environment variable \"%s\" not defined", argv[0]);
- return concat (value, argv[1], NULL);
+ /* We have to escape every character of the environment variable so
+ they are not interpretted as active spec characters. A
+ particulaly painful case is when we are reading a variable
+ holding a windows path complete with \ separators. */
+ len = strlen (value) * 2 + strlen (argv[1]) + 1;
+ result = xmalloc (len);
+ for (ptr = result; *value; ptr += 2)
+ {
+ ptr[0] = '\\';
+ ptr[1] = *value++;
+ }
+
+ strcpy (ptr, argv[1]);
+
+ return result;
}
/* if-exists built-in spec function.
@@ -7871,3 +7957,16 @@ include_spec_function (int argc, const char **argv)
return NULL;
}
+
+/* %:print-asm-header spec function. Print a banner to say that the
+ following output is from the assembler. */
+
+static const char *
+print_asm_header_spec_function (int arg ATTRIBUTE_UNUSED,
+ const char **argv ATTRIBUTE_UNUSED)
+{
+ printf (_("Assembler options\n=================\n\n"));
+ printf (_("Use \"-Wa,OPTION\" to pass \"OPTION\" to the assembler.\n\n"));
+ fflush (stdout);
+ return NULL;
+}