aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto-wrapper.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2011-10-26 09:30:29 +0000
committerRichard Guenther <rguenther@suse.de>2011-10-26 09:30:29 +0000
commit43c014ea4ca5e06b3b68b8aea36a446f1484b594 (patch)
treecb359c0379cd06029ee75ba612f48fea9252bcc3 /gcc/lto-wrapper.c
parent1ac72a2f642e30bbfee00582b43764fcb0c6ac2a (diff)
2011-10-26 Richard Guenther <rguenther@suse.de>
PR lto/41844 * Makefile.in (lto-wrapper): Depend on and link against opts-common.o. (lto-wrapper.o): Depend on $(OPTS_H) and $(OPTIONS_H). * lto-wrapper.c (get_options_from_collect_gcc_options): New function. (run_gcc): Use it. Filter out language specific options. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@180517 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lto-wrapper.c')
-rw-r--r--gcc/lto-wrapper.c178
1 files changed, 108 insertions, 70 deletions
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index f26b3aca510..f5f3dd24b45 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -43,6 +43,8 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h"
#include "diagnostic.h"
#include "obstack.h"
+#include "opts.h"
+#include "options.h"
int debug; /* true if -save-temps. */
int verbose; /* true if -v. */
@@ -280,6 +282,52 @@ fork_execute (char **argv)
/* Template of LTRANS dumpbase suffix. */
#define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
+/* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
+ environment according to LANG_MASK. */
+
+static void
+get_options_from_collect_gcc_options (const char *collect_gcc,
+ const char *collect_gcc_options,
+ unsigned int lang_mask,
+ struct cl_decoded_option **decoded_options,
+ unsigned int *decoded_options_count)
+{
+ char *argv_storage;
+ const char **argv;
+ int i, j, argc;
+
+ /* Count arguments. */
+ argc = 0;
+ for (j = 0; collect_gcc_options[j] != '\0'; ++j)
+ if (collect_gcc_options[j] == '\'')
+ ++argc;
+ if (argc % 2 != 0)
+ fatal ("malformed COLLECT_GCC_OPTIONS");
+
+ /* Copy the options to a argv-like array. */
+ argc /= 2;
+ argv = (const char **) xmalloc ((argc + 2) * sizeof (char *));
+ argv[0] = collect_gcc;
+ argv_storage = xstrdup (collect_gcc_options);
+ for (i = 1, j = 0; argv_storage[j] != '\0'; ++j)
+ {
+ if (argv_storage[j] == '\'')
+ {
+ argv[i++] = &argv_storage[++j];
+ while (argv_storage[j] != '\'')
+ ++j;
+ argv_storage[j] = '\0';
+ }
+ }
+ argv[i] = NULL;
+
+ decode_cmdline_options_to_array (argc, (const char **)argv,
+ lang_mask,
+ decoded_options, decoded_options_count);
+ free (argv);
+}
+
+
/* Execute gcc. ARGC is the number of arguments. ARGV contains the arguments. */
static void
@@ -290,99 +338,88 @@ run_gcc (unsigned argc, char *argv[])
const char **argv_ptr;
char *list_option_full = NULL;
const char *linker_output = NULL;
- const char *collect_gcc_options, *collect_gcc;
+ const char *collect_gcc, *collect_gcc_options;
struct obstack env_obstack;
- bool seen_o = false;
int parallel = 0;
int jobserver = 0;
bool no_partition = false;
+ struct cl_decoded_option *decoded_options;
+ unsigned int decoded_options_count;
/* Get the driver and options. */
collect_gcc = getenv ("COLLECT_GCC");
if (!collect_gcc)
fatal ("environment variable COLLECT_GCC must be set");
-
- /* Set the CFLAGS environment variable. */
collect_gcc_options = getenv ("COLLECT_GCC_OPTIONS");
if (!collect_gcc_options)
fatal ("environment variable COLLECT_GCC_OPTIONS must be set");
-
- /* Count arguments. */
- i = 0;
- for (j = 0; collect_gcc_options[j] != '\0'; ++j)
- if (collect_gcc_options[j] == '\'')
- ++i;
-
- if (i % 2 != 0)
- fatal ("malformed COLLECT_GCC_OPTIONS");
+ get_options_from_collect_gcc_options (collect_gcc, collect_gcc_options,
+ CL_LANG_ALL,
+ &decoded_options,
+ &decoded_options_count);
/* Initalize the common arguments for the driver. */
- new_argv = (const char **) xmalloc ((15 + i / 2 + argc) * sizeof (char *));
+ new_argv = (const char **) xmalloc ((15 + decoded_options_count + argc)
+ * sizeof (char *));
argv_ptr = new_argv;
*argv_ptr++ = collect_gcc;
*argv_ptr++ = "-xlto";
*argv_ptr++ = "-c";
- for (j = 0; collect_gcc_options[j] != '\0'; ++j)
- if (collect_gcc_options[j] == '\'')
- {
- char *option;
-
- ++j;
- i = j;
- while (collect_gcc_options[j] != '\'')
- ++j;
-
- obstack_init (&env_obstack);
- obstack_grow (&env_obstack, &collect_gcc_options[i], j - i);
- obstack_1grow (&env_obstack, 0);
- option = XOBFINISH (&env_obstack, char *);
- if (seen_o)
- {
- linker_output = option;
- seen_o = false;
- continue;
- }
-
- /* If we see -o, skip it and skip and record its argument. */
- if (option[0] == '-' && option[1] == 'o')
- {
- if (option[2] == '\0')
- seen_o = true;
- else
- linker_output = &option[2];
- continue;
- }
+ for (j = 1; j < decoded_options_count; ++j)
+ {
+ struct cl_decoded_option *option = &decoded_options[j];
- if (strcmp (option, "-save-temps") == 0)
+ /* Do not pass on frontend specific flags. */
+ if (!(cl_options[option->opt_index].flags
+ & (CL_COMMON|CL_TARGET|CL_DRIVER)))
+ continue;
+
+ switch (option->opt_index)
+ {
+ case OPT_o:
+ linker_output = option->arg;
+ /* We generate new intermediate output, drop this arg. */
+ continue;
+
+ case OPT_save_temps:
debug = 1;
- if (strcmp (option, "-v") == 0)
+ break;
+
+ case OPT_v:
verbose = 1;
+ break;
- if (strcmp (option, "-flto-partition=none") == 0)
+ case OPT_flto_partition_none:
no_partition = true;
- /* We've handled these LTO options, do not pass them on. */
- if (strncmp (option, "-flto=", 6) == 0
- || !strcmp (option, "-flto"))
- {
- lto_mode = LTO_MODE_WHOPR;
- if (option[5] == '=')
- {
- if (!strcmp (option + 6, "jobserver"))
- {
- jobserver = 1;
- parallel = 1;
- }
- else
- {
- parallel = atoi (option + 6);
- if (parallel <= 1)
- parallel = 0;
- }
- }
- }
- else
- *argv_ptr++ = option;
- }
+ break;
+
+ case OPT_flto_:
+ if (strcmp (option->arg, "jobserver") == 0)
+ {
+ jobserver = 1;
+ parallel = 1;
+ }
+ else
+ {
+ parallel = atoi (option->arg);
+ if (parallel <= 1)
+ parallel = 0;
+ }
+ /* Fallthru. */
+
+ case OPT_flto:
+ lto_mode = LTO_MODE_WHOPR;
+ /* We've handled these LTO options, do not pass them on. */
+ continue;
+
+ default:
+ break;
+ }
+
+ /* Pass the option on. */
+ *argv_ptr++ = option->orig_option_with_args_text;
+ }
+
if (no_partition)
{
lto_mode = LTO_MODE_LTO;
@@ -662,6 +699,7 @@ main (int argc, char *argv[])
/* We may be called with all the arguments stored in some file and
passed with @file. Expand them into argv before processing. */
expandargv (&argc, &argv);
+
run_gcc (argc, argv);
return 0;