summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/doc/tm.texi17
-rw-r--r--gcc/gcc.c52
3 files changed, 76 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 7bde8dd690e..4268d240a7a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2002-10-14 Richard Sandiford <rsandifo@redhat.com>
+
+ * doc/tm.texi (DRIVER_SELF_SPECS): Document.
+ * gcc.c (driver_self_specs): New variable.
+ (do_self_spec): New function.
+ (main): Use it to process driver_self_specs.
+
2002-10-13 Richard Henderson <rth@redhat.com>
* rtl.c (shallow_copy_rtx): Use memcpy for the entire node.
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index a0396bc6965..bf94d584a88 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -163,6 +163,23 @@ multilibs. Example nonsensical definition, where @code{-malt-abi},
@{ "-compat", "-EB -malign=4 -mspoo" @}
@end smallexample
+@findex DRIVER_SELF_SPECS
+@item DRIVER_SELF_SPECS
+A list of specs for the driver itself. It should be a suitable
+initializer for an array of strings, with no surrounding braces.
+
+The driver applies these specs to its own command line before choosing
+the multilib directory or running any subcommands. It applies them in
+the order given, so each spec can depend on the options added by
+earlier ones. It is also possible to remove options using
+@samp{%<@var{option}} in the usual way.
+
+This macro can be useful when a port has several interdependent target
+options. It provides a way of standardizing the command line so
+that the other specs are easier to write.
+
+Do not define this macro if it does not need to do anything.
+
@findex CPP_SPEC
@item CPP_SPEC
A C string constant that tells the GCC driver program options to
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 1018513f5c7..291712dcfa1 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -296,6 +296,7 @@ static char *save_string PARAMS ((const char *, int));
static void set_collect_gcc_options PARAMS ((void));
static int do_spec_1 PARAMS ((const char *, int, const char *));
static int do_spec_2 PARAMS ((const char *));
+static void do_self_spec PARAMS ((const char *));
static const char *find_file PARAMS ((const char *));
static int is_directory PARAMS ((const char *, const char *, int));
static void validate_switches PARAMS ((const char *));
@@ -738,6 +739,12 @@ static const char *multilib_exclusions;
static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
+#ifndef DRIVER_SELF_SPECS
+#define DRIVER_SELF_SPECS ""
+#endif
+
+static const char *const driver_self_specs[] = { DRIVER_SELF_SPECS };
+
struct user_specs
{
struct user_specs *next;
@@ -4268,6 +4275,45 @@ do_spec_2 (spec)
return do_spec_1 (spec, 0, NULL);
}
+
+/* Process the given spec string and add any new options to the end
+ of the switches/n_switches array. */
+
+static void
+do_self_spec (spec)
+ const char *spec;
+{
+ do_spec_2 (spec);
+ do_spec_1 (" ", 0, NULL);
+
+ if (argbuf_index > 0)
+ {
+ int i, first;
+
+ first = n_switches;
+ n_switches += argbuf_index;
+ switches = xrealloc (switches,
+ sizeof (struct switchstr) * (n_switches + 1));
+
+ switches[n_switches] = switches[first];
+ for (i = 0; i < argbuf_index; i++)
+ {
+ struct switchstr *sw;
+
+ /* Each switch should start with '-'. */
+ if (argbuf[i][0] != '-')
+ abort ();
+
+ sw = &switches[i + first];
+ sw->part1 = &argbuf[i][1];
+ sw->args = 0;
+ sw->live_cond = SWITCH_OK;
+ sw->validated = 0;
+ sw->ordering = 0;
+ }
+ }
+}
+
/* Process the sub-spec SPEC as a portion of a larger spec.
This is like processing a whole spec except that we do
not initialize at the beginning and we do not supply a
@@ -5917,6 +5963,12 @@ main (argc, argv)
process_command (argc, argv);
+ /* Process DRIVER_SELF_SPECS, adding any new options to the end
+ of the command line. */
+
+ for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
+ do_self_spec (driver_self_specs[i]);
+
/* Initialize the vector of specs to just the default.
This means one element containing 0s, as a terminator. */