/* 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 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation,
+ Inc.
This file is part of GCC.
static int access_check (const char *, int);
static char *find_a_file (struct path_prefix *, const char *, int, int);
static void add_prefix (struct path_prefix *, const char *, const char *,
- int, int, int *, int);
+ int, int, int);
static void add_sysrooted_prefix (struct path_prefix *, const char *,
- const char *, int, int, int *, int);
+ const char *, int, int, int);
static void translate_options (int *, const char *const **);
static char *skip_whitespace (char *);
static void delete_if_ordinary (const char *);
static const char *if_exists_spec_function (int, const char **);
static const char *if_exists_else_spec_function (int, const char **);
+static const char *replace_outfile_spec_function (int, const char **);
\f
/* The Specs Language
%l process LINK_SPEC as a spec.
%L process LIB_SPEC as a spec.
%G process LIBGCC_SPEC as a spec.
- %M output multilib_dir with directory separators replaced with "_";
- if multilib_dir is not set or is ".", output "".
%S process STARTFILE_SPEC as a spec. A capital S is actually used here.
%E process ENDFILE_SPEC as a spec. A capital E is actually used here.
%C process CPP_SPEC as a spec.
#ifndef LIBGCC_SPEC
#if defined(REAL_LIBGCC_SPEC)
#define LIBGCC_SPEC REAL_LIBGCC_SPEC
-#elif defined(LINK_LIBGCC_SPECIAL) || defined(LINK_LIBGCC_SPECIAL_1)
+#elif defined(LINK_LIBGCC_SPECIAL_1)
/* Have gcc do the search for libgcc.a. */
#define LIBGCC_SPEC "libgcc.a%s"
#else
%(linker) %l " LINK_PIE_SPEC "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
%{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
%{static:} %{L*} %(mfwrap) %(link_libgcc) %o %(mflib)\
- %{fprofile-arcs|fprofile-generate:-lgcov}\
+ %{fprofile-arcs|fprofile-generate|coverage:-lgcov}\
%{!nostdlib:%{!nodefaultlibs:%(link_gcc_c_sequence)}}\
%{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
#endif
#ifndef LINK_LIBGCC_SPEC
-# ifdef LINK_LIBGCC_SPECIAL
-/* Don't generate -L options for startfile prefix list. */
-# define LINK_LIBGCC_SPEC ""
-# else
-/* Do generate them. */
-# define LINK_LIBGCC_SPEC "%D"
-# endif
+/* Generate -L options for startfile prefix list. */
+# define LINK_LIBGCC_SPEC "%D"
#endif
#ifndef STARTFILE_PREFIX_SPEC
%{MMD:-MMD %{!o:%b.d}%{o*:%.d%*}}\
%{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
%{!E:%{!M:%{!MM:%{MD|MMD:%{o*:-MQ %*}}}}}\
- %{trigraphs} %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
+ %{remap} %{g3:-dD} %{H} %C %{D*&U*&A*} %{i*} %Z %i\
%{fmudflap:-D_MUDFLAP -include mf-runtime.h}\
%{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h}\
%{E|M|MM:%W{o*}}";
options used to set target flags. Those special target flags settings may
in turn cause preprocessor symbols to be defined specially. */
static const char *cpp_options =
-"%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
- %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}";
+"%(cpp_unique_options) %1 %{m*} %{std*&ansi&trigraphs} %{W*&pedantic*} %{w}\
+ %{f*} %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*}\
+ %{undef} %{save-temps:-fpch-preprocess}";
/* This contains cpp options which are not passed when the preprocessor
output will be used by another program. */
"%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
%1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\
%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\
- %{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\
+ %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
%{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
%{Qn:-fno-ident} %{--help:--help}\
%{--target-help:--target-help}\
%{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
%{fsyntax-only:-o %j} %{-param*}\
- %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}";
+ %{fmudflap|fmudflapth:-fno-builtin -fno-merge-constants}\
+ %{coverage:-fprofile-arcs -ftest-coverage}";
static const char *asm_options =
"%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
and be given a more meaningful error than "file not used since
linking is not done". */
{".m", "#Objective-C", 0, 0, 0}, {".mi", "#Objective-C", 0, 0, 0},
+ {".mm", "#Objective-C++", 0, 0, 0}, {".M", "#Objective-C++", 0, 0, 0},
+ {".mii", "#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},
{"--dependencies", "-M", 0},
{"--dump", "-d", "a"},
{"--dumpbase", "-dumpbase", "a"},
+ {"--encoding", "-fencoding=", "aj"},
{"--entry", "-e", 0},
{"--extra-warnings", "-W", 0},
+ {"--extdirs", "-fextdirs=", "aj"},
{"--for-assembler", "-Wa", "a"},
{"--for-linker", "-Xlinker", "a"},
{"--force-link", "-u", "a"},
+ {"--coverage", "-coverage", 0},
{"--imacros", "-imacros", "a"},
{"--include", "-include", "a"},
{"--include-barrier", "-I-", 0},
{"--output", "-o", "a"},
{"--output-class-directory", "-foutput-class-dir=", "ja"},
{"--param", "--param", "a"},
+ {"--pass-exit-codes", "-pass-exit-codes", 0},
{"--pedantic", "-pedantic", 0},
{"--pedantic-errors", "-pedantic-errors", 0},
{"--pie", "-pie", 0},
else if (strchr (arginfo, '*') != 0)
{
- error ("incomplete `%s' option", option_map[j].name);
+ error ("incomplete '%s' option", option_map[j].name);
break;
}
{
if (i + 1 == argc)
{
- error ("missing argument to `%s' option",
+ error ("missing argument to '%s' option",
option_map[j].name);
break;
}
else if (strchr (arginfo, 'o') == 0)
{
if (arg != 0)
- error ("extraneous argument to `%s' option",
+ error ("extraneous argument to '%s' option",
option_map[j].name);
arg = 0;
}
struct prefix_list *next; /* Next in linked list. */
int require_machine_suffix; /* Don't use without machine_suffix. */
/* 2 means try both machine_suffix and just_machine_suffix. */
- int *used_flag_ptr; /* 1 if a file was found with this prefix. */
int priority; /* Sort key - priority within list. */
int os_multilib; /* 1 if OS multilib scheme should be used,
0 for GCC multilib scheme. */
/* Default prefixes to attach to command names. */
+#ifndef STANDARD_STARTFILE_PREFIX_1
+#define STANDARD_STARTFILE_PREFIX_1 "/lib/"
+#endif
+#ifndef STANDARD_STARTFILE_PREFIX_2
+#define STANDARD_STARTFILE_PREFIX_2 "/usr/lib/"
+#endif
+
#ifdef CROSS_COMPILE /* Don't use these prefixes for a cross compiler. */
#undef MD_EXEC_PREFIX
#undef MD_STARTFILE_PREFIX
static const char *md_startfile_prefix = MD_STARTFILE_PREFIX;
static const char *md_startfile_prefix_1 = MD_STARTFILE_PREFIX_1;
static const char *const standard_startfile_prefix = STANDARD_STARTFILE_PREFIX;
-static const char *const standard_startfile_prefix_1 = "/lib/";
-static const char *const standard_startfile_prefix_2 = "/usr/lib/";
+static const char *const standard_startfile_prefix_1
+ = STANDARD_STARTFILE_PREFIX_1;
+static const char *const standard_startfile_prefix_2
+ = STANDARD_STARTFILE_PREFIX_2;
static const char *const tooldir_base_prefix = TOOLDIR_BASE_PREFIX;
static const char *tooldir_prefix;
{
{ "if-exists", if_exists_spec_function },
{ "if-exists-else", if_exists_else_spec_function },
+ { "replace-outfile", replace_outfile_spec_function },
{ 0, 0 }
};
if (in_sep && *p == '-' && strncmp (p, "-lgcc", 5) == 0)
{
init_gcc_specs (&obstack,
-#ifdef NO_SHARED_LIBGCC_MULTILIB
"-lgcc_s"
-#else
- "-lgcc_s%M"
+#ifdef USE_LIBUNWIND_EXCEPTIONS
+ " -lunwind"
#endif
,
"-lgcc",
"-lgcc_eh"
#ifdef USE_LIBUNWIND_EXCEPTIONS
+# ifdef HAVE_LD_STATIC_DYNAMIC
+ " %{!static:-Bstatic} -lunwind %{!static:-Bdynamic}"
+# else
" -lunwind"
+# endif
#endif
);
/* Ug. We don't know shared library extensions. Hope that
systems that use this form don't do shared libraries. */
init_gcc_specs (&obstack,
-#ifdef NO_SHARED_LIBGCC_MULTILIB
- "-lgcc_s"
-#else
- "-lgcc_s%M"
-#endif
- ,
+ "-lgcc_s",
"libgcc.a%s",
"libgcc_eh.a%s"
#ifdef USE_LIBUNWIND_EXCEPTIONS
strcat (temp, multilib_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
/* Now try just the multilib_name. */
strcat (temp, machine_suffix);
strcat (temp, multilib_name);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
/* Certain prefixes are tried with just the machine type,
strcat (temp, multilib_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
strcpy (temp, pl->prefix);
strcat (temp, just_machine_suffix);
strcat (temp, multilib_name);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
/* Certain prefixes can't be used without the machine suffix
strcat (temp, this_name);
strcat (temp, file_suffix);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
strcpy (temp, pl->prefix);
strcat (temp, this_name);
if (access_check (temp, mode) == 0)
- {
- if (pl->used_flag_ptr != 0)
- *pl->used_flag_ptr = 1;
- return temp;
- }
+ return temp;
}
}
static void
add_prefix (struct path_prefix *pprefix, const char *prefix,
const char *component, /* enum prefix_priority */ int priority,
- int require_machine_suffix, int *warn, int os_multilib)
+ int require_machine_suffix, int os_multilib)
{
struct prefix_list *pl, **prev;
int len;
pl = xmalloc (sizeof (struct prefix_list));
pl->prefix = prefix;
pl->require_machine_suffix = require_machine_suffix;
- pl->used_flag_ptr = warn;
pl->priority = priority;
pl->os_multilib = os_multilib;
- if (warn)
- *warn = 0;
/* Insert after PREV. */
pl->next = (*prev);
add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
const char *component,
/* enum prefix_priority */ int priority,
- int require_machine_suffix, int *warn, int os_multilib)
+ int require_machine_suffix, int os_multilib)
{
if (!IS_ABSOLUTE_PATH (prefix))
- abort ();
+ fatal ("system path '%s' is not absolute", prefix);
if (target_system_root)
{
}
add_prefix (pprefix, prefix, component, priority,
- require_machine_suffix, warn, os_multilib);
+ require_machine_suffix, os_multilib);
}
\f
/* Execute the command specified by the arguments on the current line of spec.
struct command *commands; /* each command buffer with above info. */
- if (processing_spec_function)
- abort ();
+ gcc_assert (!processing_spec_function);
/* Count # of piped commands. */
for (n_commands = 1, i = 0; i < argbuf_index; i++)
int pid;
pid = pwait (commands[i].pid, &status, 0);
- if (pid < 0)
- abort ();
+ gcc_assert (pid >= 0);
#ifdef HAVE_GETRUSAGE
if (report_times)
/* And a vector of corresponding output files is made up later. */
const char **outfiles;
-
-/* Used to track if none of the -B paths are used. */
-static int warn_B;
-
-/* Gives value to pass as "warn" to add_prefix for standard prefixes. */
-static int *warn_std_ptr = 0;
\f
#if defined(HAVE_TARGET_OBJECT_SUFFIX) || defined(HAVE_TARGET_EXECUTABLE_SUFFIX)
argv += 2;
}
else
- fatal ("`-%c' option must have argument", opt);
+ fatal ("'-%c' option must have argument", opt);
if (opt == 'V')
new_version = arg;
else
new_argv[0] = new_argv0;
execvp (new_argv0, new_argv);
- fatal ("couldn't run `%s': %s", new_argv0, xstrerror (errno));
+ fatal ("couldn't run '%s': %s", new_argv0, xstrerror (errno));
}
/* Set up the default search paths. If there is no GCC_EXEC_PREFIX,
set_std_prefix (gcc_exec_prefix, len);
add_prefix (&exec_prefixes, gcc_libexec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ PREFIX_PRIORITY_LAST, 0, 0);
add_prefix (&startfile_prefixes, gcc_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ PREFIX_PRIORITY_LAST, 0, 0);
}
/* COMPILER_PATH and LIBRARY_PATH have values
else
nstore[endp - startp] = 0;
add_prefix (&exec_prefixes, nstore, 0,
- PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ PREFIX_PRIORITY_LAST, 0, 0);
add_prefix (&include_prefixes, nstore, 0,
- PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ PREFIX_PRIORITY_LAST, 0, 0);
if (*endp == 0)
break;
endp = startp = endp + 1;
else
nstore[endp - startp] = 0;
add_prefix (&startfile_prefixes, nstore, NULL,
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ PREFIX_PRIORITY_LAST, 0, 1);
if (*endp == 0)
break;
endp = startp = endp + 1;
else
nstore[endp - startp] = 0;
add_prefix (&startfile_prefixes, nstore, NULL,
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ PREFIX_PRIORITY_LAST, 0, 1);
if (*endp == 0)
break;
endp = startp = endp + 1;
{
/* translate_options () has turned --version into -fversion. */
printf (_("%s (GCC) %s\n"), programname, version_string);
- printf ("Copyright %s 2004 Free Software Foundation, Inc.\n",
+ printf ("Copyright %s 2005 Free Software Foundation, Inc.\n",
_("(C)"));
fputs (_("This is free software; see the source for copying conditions. There is NO\n\
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
else if (strcmp (argv[i], "-Xlinker") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-Xlinker' is missing");
+ fatal ("argument to '-Xlinker' is missing");
n_infiles++;
i++;
else if (strcmp (argv[i], "-Xpreprocessor") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-Xpreprocessor' is missing");
+ fatal ("argument to '-Xpreprocessor' is missing");
add_preprocessor_option (argv[i+1], strlen (argv[i+1]));
}
else if (strcmp (argv[i], "-Xassembler") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-Xassembler' is missing");
+ fatal ("argument to '-Xassembler' is missing");
add_assembler_option (argv[i+1], strlen (argv[i+1]));
}
else if (strcmp (argv[i], "-l") == 0)
{
if (i + 1 == argc)
- fatal ("argument to `-l' is missing");
+ fatal ("argument to '-l' is missing");
n_infiles++;
i++;
{
struct user_specs *user = xmalloc (sizeof (struct user_specs));
if (++i >= argc)
- fatal ("argument to `-specs' is missing");
+ fatal ("argument to '-specs' is missing");
user->next = (struct user_specs *) 0;
user->filename = argv[i];
{
struct user_specs *user = xmalloc (sizeof (struct user_specs));
if (strlen (argv[i]) == 7)
- fatal ("argument to `-specs=' is missing");
+ fatal ("argument to '-specs=' is missing");
user->next = (struct user_specs *) 0;
user->filename = argv[i] + 7;
{
case 'b':
case 'V':
- fatal ("`-%c' must come at the start of the command line", c);
+ fatal ("'-%c' must come at the start of the command line", c);
break;
case 'B':
int len;
if (p[1] == 0 && i + 1 == argc)
- fatal ("argument to `-B' is missing");
+ fatal ("argument to '-B' is missing");
if (p[1] == 0)
value = argv[++i];
else
{
if (len == 7)
add_prefix (&include_prefixes, "./", NULL,
- PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
+ PREFIX_PRIORITY_B_OPT, 0, 0);
else
{
char *string = xmalloc (len - 6);
memcpy (string, value, len - 7);
string[len - 7] = 0;
add_prefix (&include_prefixes, string, NULL,
- PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
+ PREFIX_PRIORITY_B_OPT, 0, 0);
}
}
add_prefix (&exec_prefixes, value, NULL,
- PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
+ PREFIX_PRIORITY_B_OPT, 0, 0);
add_prefix (&startfile_prefixes, value, NULL,
- PREFIX_PRIORITY_B_OPT, 0, &warn_B, 0);
+ PREFIX_PRIORITY_B_OPT, 0, 0);
add_prefix (&include_prefixes, value, NULL,
- PREFIX_PRIORITY_B_OPT, 0, NULL, 0);
+ PREFIX_PRIORITY_B_OPT, 0, 0);
n_switches++;
}
break;
as well as trying the machine and the version. */
#ifndef OS2
add_prefix (&exec_prefixes, standard_libexec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
+ PREFIX_PRIORITY_LAST, 1, 0);
add_prefix (&exec_prefixes, standard_libexec_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
+ PREFIX_PRIORITY_LAST, 2, 0);
add_prefix (&exec_prefixes, standard_exec_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
+ PREFIX_PRIORITY_LAST, 2, 0);
add_prefix (&exec_prefixes, standard_exec_prefix_1, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
+ PREFIX_PRIORITY_LAST, 2, 0);
add_prefix (&exec_prefixes, standard_exec_prefix_2, "BINUTILS",
- PREFIX_PRIORITY_LAST, 2, warn_std_ptr, 0);
+ PREFIX_PRIORITY_LAST, 2, 0);
#endif
add_prefix (&startfile_prefixes, standard_exec_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
+ PREFIX_PRIORITY_LAST, 1, 0);
add_prefix (&startfile_prefixes, standard_exec_prefix_2, "BINUTILS",
- PREFIX_PRIORITY_LAST, 1, warn_std_ptr, 0);
+ PREFIX_PRIORITY_LAST, 1, 0);
tooldir_prefix = concat (tooldir_base_prefix, spec_machine,
dir_separator_str, NULL);
add_prefix (&exec_prefixes,
concat (gcc_exec_tooldir_prefix, "bin",
dir_separator_str, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ NULL, PREFIX_PRIORITY_LAST, 0, 0);
add_prefix (&startfile_prefixes,
concat (gcc_exec_tooldir_prefix, "lib",
dir_separator_str, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ NULL, PREFIX_PRIORITY_LAST, 0, 1);
}
tooldir_prefix = concat (standard_exec_prefix, spec_machine,
add_prefix (&exec_prefixes,
concat (tooldir_prefix, "bin", dir_separator_str, NULL),
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, 0);
add_prefix (&startfile_prefixes,
concat (tooldir_prefix, "lib", dir_separator_str, NULL),
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ "BINUTILS", PREFIX_PRIORITY_LAST, 0, 1);
#if defined(TARGET_SYSTEM_ROOT_RELOCATABLE) && !defined(VMS)
/* If the normal TARGET_SYSTEM_ROOT is inside of $exec_prefix,
if (c == 'x')
{
if (p[1] == 0 && i + 1 == argc)
- fatal ("argument to `-x' is missing");
+ fatal ("argument to '-x' is missing");
if (p[1] == 0)
spec_lang = argv[++i];
else
n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
}
if (i + n_args >= argc)
- fatal ("argument to `-%s' is missing", p);
+ fatal ("argument to '-%s' is missing", p);
switches[n_switches].args
= xmalloc ((n_args + 1) * sizeof(const char *));
while (j < n_args)
}
if (n_infiles == last_language_n_infiles && spec_lang != 0)
- error ("warning: `-x %s' after last input file has no effect", spec_lang);
+ error ("warning: '-x %s' after last input file has no effect", spec_lang);
/* Ensure we only invoke each subprocess once. */
if (target_help_flag || print_help_list)
static int suffixed_basename_length;
static const char *input_basename;
static const char *input_suffix;
+#ifndef HOST_LACKS_INODE_NUMBERS
static struct stat input_stat;
+#endif
static int input_stat_set;
/* The compiler used to process the current input file. */
/* Each switch should start with '-'. */
if (argbuf[i][0] != '-')
- abort ();
+ fatal ("switch '%s' does not start with '-'", argbuf[i]);
sw = &switches[i + first];
sw->part1 = &argbuf[i][1];
switch (c = *p++)
{
case 0:
- fatal ("invalid specification! Bug in cc");
+ fatal ("spec '%s' invalid", spec);
case 'b':
obstack_grow (&obstack, input_basename, basename_length);
p += 2;
/* We don't support extra suffix characters after %O. */
if (*p == '.' || ISALPHA ((unsigned char) *p))
- abort ();
+ fatal ("spec '%s' has invalid '%%0%c'", spec, *p);
if (suffix_length == 0)
suffix = TARGET_OBJECT_SUFFIX;
else
*((char *) temp_filename + temp_filename_length) = '\0';
if (strcmp (temp_filename, input_filename) != 0)
{
+#ifndef HOST_LACKS_INODE_NUMBERS
struct stat st_temp;
/* Note, set_input() resets input_stat_set to 0. */
and we can do the stat for the temp_filename
then the they could still refer to the same
file if st_dev/st_ino's are the same. */
-
if (input_stat_set != 1
|| stat (temp_filename, &st_temp) < 0
|| input_stat.st_dev != st_temp.st_dev
|| input_stat.st_ino != st_temp.st_ino)
+#else
+ /* Just compare canonical pathnames. */
+ char* input_realname = lrealpath (input_filename);
+ char* temp_realname = lrealpath (temp_filename);
+ bool files_differ = strcmp (input_realname, temp_realname);
+ free (input_realname);
+ free (temp_realname);
+ if (files_differ)
+#endif
{
temp_filename = save_string (temp_filename,
temp_filename_length + 1);
int cur_index = argbuf_index;
/* Handle the {...} following the %W. */
if (*p != '{')
- abort ();
+ fatal ("spec '%s' has invalid '%%W%c", spec, *p);
p = handle_braces (p + 1);
if (p == 0)
return -1;
/* Skip past the option value and make a copy. */
if (*p != '{')
- abort ();
+ fatal ("spec '%s' has invalid '%%x%c'", spec, *p);
while (*p++ != '}')
;
string = save_string (p1 + 1, p - p1 - 2);
return value;
break;
- case 'M':
- if (multilib_dir && strcmp (multilib_dir, ".") != 0)
- {
- char *p;
- const char *q;
- size_t len;
-
- len = strlen (multilib_dir);
- obstack_blank (&obstack, len + 1);
- p = obstack_next_free (&obstack) - (len + 1);
-
- *p++ = '_';
- for (q = multilib_dir; *q ; ++q, ++p)
- *p = (IS_DIR_SEPARATOR (*q) ? '_' : *q);
- }
- break;
-
case 'R':
/* We assume there is a directory
separator at the end of this string. */
}
else
/* Catch the case where a spec string contains something like
- '%{foo:%*}'. ie there is no * in the pattern on the left
+ '%{foo:%*}'. i.e. there is no * in the pattern on the left
hand side of the :. */
error ("spec failure: '%%*' has not been initialized by pattern match");
break;
sf = lookup_spec_function (func);
if (sf == NULL)
- fatal ("unknown spec function `%s'", func);
+ fatal ("unknown spec function '%s'", func);
/* Push the spec processing context. */
save_argbuf_index = argbuf_index;
alloc_args ();
if (do_spec_2 (args) < 0)
- fatal ("error in args to spec function `%s'", func);
+ fatal ("error in args to spec function '%s'", func);
/* argbuf_index is an index for the next argument to be inserted, and
so contains the count of the args already inserted. */
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');
{
const char *atom, *end_atom;
const char *d_atom = NULL, *d_end_atom = NULL;
+ const char *orig = p;
bool a_is_suffix;
bool a_is_starred;
do
{
if (a_must_be_last)
- abort ();
+ goto invalid;
/* Scan one "atom" (S in the description above of %{}, possibly
with !, ., or * modifiers). */
p++, a_is_starred = 1;
SKIP_WHITE();
- if (*p == '&' || *p == '}')
+ switch (*p)
{
+ case '&': case '}':
/* 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)
- abort ();
+ goto invalid;
mark_matching_switches (atom, end_atom, a_is_starred);
if (*p == '}')
process_marked_switches ();
- }
- else if (*p == '|' || *p == ':')
- {
+ break;
+
+ case '|': case ':':
/* Substitute some text if the current atom appears as a switch
or suffix. */
disjunct_set = true;
if (ordered_set)
- abort ();
+ goto invalid;
if (atom == end_atom)
{
if (!n_way_choice || disj_matched || *p == '|'
|| a_is_negated || a_is_suffix || a_is_starred)
- abort ();
+ goto invalid;
/* An empty term may appear as the last choice of an
N-way choice set; it means "otherwise". */
else
{
if (a_is_suffix && a_is_starred)
- abort ();
+ goto invalid;
if (!a_is_starred)
disj_starred = false;
d_atom = d_end_atom = NULL;
}
}
+ break;
+
+ default:
+ goto invalid;
}
- else
- abort ();
}
while (*p++ != '}');
return p;
-
+
+ invalid:
+ fatal ("braced spec '%s' is invalid at '%c'", orig, *p);
+
#undef SKIP_WHITE
}
else if (*p == '%' && p[1] == '*' && nesting_level == 1)
have_subst = true;
else if (*p == '\0')
- abort ();
+ goto invalid;
p++;
}
end_body--;
if (have_subst && !starred)
- abort ();
+ goto invalid;
if (matched)
{
}
return p;
+
+ invalid:
+ fatal ("braced spec body '%s' is invalid", body);
}
\f
/* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
if (*md_exec_prefix)
{
add_prefix (&exec_prefixes, md_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL, 0);
+ PREFIX_PRIORITY_LAST, 0, 0);
}
}
int ndx;
for (ndx = 0; ndx < argbuf_index; ndx++)
add_sysrooted_prefix (&startfile_prefixes, argbuf[ndx], "BINUTILS",
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ PREFIX_PRIORITY_LAST, 0, 1);
}
/* We should eventually get rid of all these and stick to
startfile_prefix_spec exclusively. */
{
if (*md_exec_prefix)
add_sysrooted_prefix (&startfile_prefixes, md_exec_prefix, "GCC",
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ PREFIX_PRIORITY_LAST, 0, 1);
if (*md_startfile_prefix)
add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix,
- "GCC", PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ "GCC", PREFIX_PRIORITY_LAST, 0, 1);
if (*md_startfile_prefix_1)
add_sysrooted_prefix (&startfile_prefixes, md_startfile_prefix_1,
- "GCC", PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ "GCC", PREFIX_PRIORITY_LAST, 0, 1);
/* If standard_startfile_prefix is relative, base it on
standard_exec_prefix. This lets us move the installed tree
if (IS_ABSOLUTE_PATH (standard_startfile_prefix))
add_sysrooted_prefix (&startfile_prefixes,
standard_startfile_prefix, "BINUTILS",
- PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ PREFIX_PRIORITY_LAST, 0, 1);
else if (*cross_compile == '0')
{
if (gcc_exec_prefix)
add_prefix (&startfile_prefixes,
concat (gcc_exec_prefix, machine_suffix,
standard_startfile_prefix, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ NULL, PREFIX_PRIORITY_LAST, 0, 1);
add_prefix (&startfile_prefixes,
concat (standard_exec_prefix,
machine_suffix,
standard_startfile_prefix, NULL),
- NULL, PREFIX_PRIORITY_LAST, 0, NULL, 1);
+ NULL, PREFIX_PRIORITY_LAST, 0, 1);
}
- add_sysrooted_prefix (&startfile_prefixes, standard_startfile_prefix_1,
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
- add_sysrooted_prefix (&startfile_prefixes, standard_startfile_prefix_2,
- "BINUTILS", PREFIX_PRIORITY_LAST, 0, NULL, 1);
-#if 0 /* Can cause surprises, and one can use -B./ instead. */
- add_prefix (&startfile_prefixes, "./", NULL,
- PREFIX_PRIORITY_LAST, 1, NULL, 0);
-#endif
+ if (*standard_startfile_prefix_1)
+ add_sysrooted_prefix (&startfile_prefixes,
+ standard_startfile_prefix_1, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 0, 1);
+ if (*standard_startfile_prefix_2)
+ add_sysrooted_prefix (&startfile_prefixes,
+ standard_startfile_prefix_2, "BINUTILS",
+ PREFIX_PRIORITY_LAST, 0, 1);
}
/* Process any user specified specs in the order given on the command
for (i = 0; (int) i < n_switches; i++)
if (! switches[i].validated)
- error ("unrecognized option `-%s'", switches[i].part1);
+ error ("unrecognized option '-%s'", switches[i].part1);
/* Obey some of the options. */
int n;
const char *thrmod;
+ notice ("Target: %s\n", spec_machine);
notice ("Configured with: %s\n", configuration_arguments);
#ifdef THREAD_MODEL_SPEC
{
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 (!have_o_argbuf_index)
+ fatal ("spec '%s' is invalid", input_file_compiler->spec);
+ infiles[i].name = argbuf[have_o_argbuf_index];
+ infiles[i].incompiler
+ = lookup_compiler (infiles[i].name,
+ strlen (infiles[i].name),
+ infiles[i].language);
if (value < 0)
this_file_error = 1;
{
delete_failure_queue ();
error_count++;
- break;
}
/* If this compilation succeeded, don't delete those files later. */
clear_failure_queue ();
/* Output an error message and exit. */
void
-fancy_abort (void)
+fancy_abort (const char *file, int line, const char *func)
{
- fatal ("internal gcc abort");
+ fatal ("internal gcc abort in %s, at %s:%d", func, file, line);
}
\f
/* Output an error message and exit. */
while (*q != ' ')
{
if (*q == '\0')
- abort ();
+ {
+ invalid_matches:
+ fatal ("multilib spec '%s' is invalid", multilib_matches);
+ }
q++;
}
matches[i].len = q - matches[i].str;
while (*q != ';' && *q != '\0')
{
if (*q == ' ')
- abort ();
+ goto invalid_matches;
q++;
}
matches[i].rep_len = q - matches[i].replace;
while (*p != ';')
{
if (*p == '\0')
- abort ();
+ {
+ invalid_exclusions:
+ fatal ("multilib exclusions '%s' is invalid",
+ multilib_exclusions);
+ }
if (! ok)
{
while (*p != ' ' && *p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_exclusions;
++p;
}
while (*p != ' ')
{
if (*p == '\0')
- abort ();
+ {
+ invalid_select:
+ fatal ("multilib select '%s' is invalid",
+ multilib_select);
+ }
++p;
}
this_path_len = p - this_path;
while (*p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_select;
if (! ok)
{
while (*p != ' ' && *p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_select;
++p;
}
while (*p != ' ')
{
if (*p == '\0')
- abort ();
+ {
+ invalid_select:
+ fatal ("multilib select '%s' is invalid", multilib_select);
+ }
+
++p;
}
int mp = 0;
if (*e == '\0')
- abort ();
+ {
+ invalid_exclusion:
+ fatal ("multilib exclusion '%s' is invalid",
+ multilib_exclusions);
+ }
if (! m)
{
while (*e != ' ' && *e != ';')
{
if (*e == '\0')
- abort ();
+ goto invalid_exclusion;
++e;
}
int len = e - this_arg;
if (*q == '\0')
- abort ();
+ goto invalid_select;
arg = q;
while (*q != ' ' && *q != ';')
{
if (*q == '\0')
- abort ();
+ goto invalid_select;
++q;
}
- if (! strncmp (arg, this_arg, (len < q - arg) ? q - arg : len) ||
- default_arg (this_arg, e - this_arg))
+ if (! strncmp (arg, this_arg,
+ (len < q - arg) ? q - arg : len)
+ || default_arg (this_arg, e - this_arg))
{
mp = 1;
break;
if (! skip)
{
/* If this is a duplicate, skip it. */
- skip = (last_path != 0 && (unsigned int) (p - this_path) == last_path_len
+ skip = (last_path != 0
+ && (unsigned int) (p - this_path) == last_path_len
&& ! strncmp (last_path, this_path, last_path_len));
last_path = this_path;
const char *arg;
if (*q == '\0')
- abort ();
+ goto invalid_select;
if (*q == '!')
arg = NULL;
while (*q != ' ' && *q != ';')
{
if (*q == '\0')
- abort ();
+ goto invalid_select;
++q;
}
int use_arg;
if (*p == '\0')
- abort ();
+ goto invalid_select;
if (skip)
{
while (*p != ' ' && *p != ';')
{
if (*p == '\0')
- abort ();
+ goto invalid_select;
if (use_arg)
putchar (*p);
++p;
return argv[1];
}
+
+/* replace-outfile built-in spec function.
+ This looks for the first argument in the outfiles array's name and replaces it
+ with the second argument. */
+
+static const char *
+replace_outfile_spec_function (int argc, const char **argv)
+{
+ int i;
+ /* Must have exactly two arguments. */
+ if (argc != 2)
+ abort ();
+
+ for (i = 0; i < n_infiles; i++)
+ {
+ if (outfiles[i] && !strcmp (outfiles[i], argv[0]))
+ outfiles[i] = xstrdup (argv[1]);
+ }
+ return NULL;
+}
+