Patchwork Make do_self_spec use common options machinery

login
register
mail settings
Submitter Joseph S. Myers
Date Oct. 23, 2010, 12:57 p.m.
Message ID <Pine.LNX.4.64.1010231256090.15708@digraph.polyomino.org.uk>
Download mbox | patch
Permalink /patch/69001/
State New
Headers show

Comments

Joseph S. Myers - Oct. 23, 2010, 12:57 p.m.
This patch makes driver options generated by specs pass through the
usual option handlers instead of special logic in do_self_spec to
parse them and identify option arguments.

This will mean that when multilib selection uses features set by
options, such options generated by driver specs are properly reflected
in the features set.  It also means that the only place now using
SWITCH_TAKES_ARG and WORD_SWITCH_TAKES_ARG is the core option
processing machinery when handling unknown options.  Thus there is no
longer any need for these macros to handle any option listed in the
.opt files, and a subsequent patch will remove such options from the
definitions of these macros (a step towards eliminating these target
macros completely, once every option they handle is in an appropriate
.opt file).

The changes in this patch to switch allocation during spec processing
in turn showed up that the code that swaps switch arrays to handle
-fcompare-debug needed to handle n_switches_alloc.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  OK to
commit?

2010-10-23  Joseph Myers  <joseph@codesourcery.com>

	* gcc.c (n_switches_alloc_debug_check): New.
	(set_option_handlers): New.
	(process_command): Use set_option_handlers.
	(do_self_spec): Pass spec-generated options through option
	handlers.
	(main): Also save and restore n_switches_alloc when swapping
	switch arrays.
Mark Mitchell - Oct. 23, 2010, 9:50 p.m.
On 10/23/2010 5:57 AM, Joseph S. Myers wrote:

> 2010-10-23  Joseph Myers  <joseph@codesourcery.com>
> 
> 	* gcc.c (n_switches_alloc_debug_check): New.
> 	(set_option_handlers): New.
> 	(process_command): Use set_option_handlers.
> 	(do_self_spec): Pass spec-generated options through option
> 	handlers.
> 	(main): Also save and restore n_switches_alloc when swapping
> 	switch arrays.

OK.

Patch

Index: gcc/gcc.c
===================================================================
--- gcc/gcc.c	(revision 165855)
+++ gcc/gcc.c	(working copy)
@@ -2810,6 +2810,8 @@  static struct switchstr *switches_debug_
 
 static int n_switches_debug_check[2];
 
+static int n_switches_alloc_debug_check[2];
+
 static char *debug_check_temp_file[2];
 
 /* Language is one of three things:
@@ -3506,6 +3508,19 @@  driver_handle_option (struct gcc_options
   return true;
 }
 
+/* Put the driver's standard set of option handlers in *HANDLERS.  */
+
+static void
+set_option_handlers (struct cl_option_handlers *handlers)
+{
+  handlers->unknown_option_callback = driver_unknown_option_callback;
+  handlers->wrong_lang_callback = driver_wrong_lang_callback;
+  handlers->post_handling_callback = driver_post_handling_callback;
+  handlers->num_handlers = 1;
+  handlers->handlers[0].handler = driver_handle_option;
+  handlers->handlers[0].mask = CL_DRIVER;
+}
+
 /* Create the vector `switches' and its contents.
    Store its length in `n_switches'.  */
 
@@ -3730,12 +3745,7 @@  process_command (unsigned int decoded_op
 
   last_language_n_infiles = -1;
 
-  handlers.unknown_option_callback = driver_unknown_option_callback;
-  handlers.wrong_lang_callback = driver_wrong_lang_callback;
-  handlers.post_handling_callback = driver_post_handling_callback;
-  handlers.num_handlers = 1;
-  handlers.handlers[0].handler = driver_handle_option;
-  handlers.handlers[0].mask = CL_DRIVER;
+  set_option_handlers (&handlers);
 
   for (j = 1; j < decoded_options_count; j++)
     {
@@ -4250,66 +4260,59 @@  do_self_spec (const char *spec)
 
   if (argbuf_index > 0)
     {
-      switches = XRESIZEVEC (struct switchstr, switches,
-			     n_switches + argbuf_index + 1);
-
-      for (i = 0; i < argbuf_index; i++)
-	{
-	  struct switchstr *sw;
-	  const char *p = argbuf[i];
-	  int c = *p;
-
-	  /* Each switch should start with '-'.  */
-	  if (c != '-')
-	    fatal_error ("switch %qs does not start with %<-%>", argbuf[i]);
-
-	  p++;
-	  c = *p;
-
-	  sw = &switches[n_switches++];
-	  sw->part1 = p;
-	  sw->live_cond = 0;
-	  sw->validated = 0;
-	  sw->ordering = 0;
+      const char **argbuf_copy;
+      struct cl_decoded_option *decoded_options;
+      struct cl_option_handlers handlers;
+      unsigned int decoded_options_count;
+      unsigned int j;
+
+      /* Create a copy of argbuf with a dummy argv[0] entry for
+	 decode_cmdline_options_to_array.  */
+      argbuf_copy = XNEWVEC (const char *, argbuf_index + 1);
+      argbuf_copy[0] = "";
+      memcpy (argbuf_copy + 1, argbuf, argbuf_index * sizeof (const char *));
+
+      decode_cmdline_options_to_array (argbuf_index + 1, argbuf_copy,
+				       CL_DRIVER, &decoded_options,
+				       &decoded_options_count);
+
+      set_option_handlers (&handlers);
+
+      for (j = 1; j < decoded_options_count; j++)
+	{
+	  switch (decoded_options[j].opt_index)
+	    {
+	    case OPT_SPECIAL_input_file:
+	      /* Specs should only generate options, not input
+		 files.  */
+	      if (strcmp (decoded_options[j].arg, "-") != 0)
+		fatal_error ("switch %qs does not start with %<-%>",
+			     decoded_options[j].arg);
+	      else
+		fatal_error ("spec-generated switch is just %<-%>");
+	      break;
 
-	  /* Deal with option arguments in separate argv elements.  */
-	  if ((SWITCH_TAKES_ARG (c) > (p[1] != 0))
-	      || WORD_SWITCH_TAKES_ARG (p))
-	    {
-	      int j = 0;
-	      int n_args = WORD_SWITCH_TAKES_ARG (p);
+	    case OPT_fcompare_debug_second:
+	    case OPT_fcompare_debug:
+	    case OPT_fcompare_debug_:
+	    case OPT_o:
+	      /* Avoid duplicate processing of some options from
+		 compare-debug specs; just save them here.  */
+	      save_switch (decoded_options[j].canonical_option[0],
+			   (decoded_options[j].canonical_option_num_elements
+			    - 1),
+			   &decoded_options[j].canonical_option[1], false);
+	      break;
 
-	      if (n_args == 0)
-		{
-		  /* Count only the option arguments in separate argv elements.  */
-		  n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
-		}
-	      if (i + n_args >= argbuf_index)
-		fatal_error ("argument to %<-%s%> is missing", p);
-	      sw->args
-		= XNEWVEC (const char *, n_args + 1);
-	      while (j < n_args)
-		sw->args[j++] = argbuf[++i];
-	      /* Null-terminate the vector.  */
-	      sw->args[j] = 0;
-	    }
-	  else if (c == 'o')
-	    {
-	      /* On some systems, ld cannot handle "-o" without
-		 a space.  So split the option from its argument.  */
-	      char *part1 = XNEWVEC (char, 2);
-	      part1[0] = c;
-	      part1[1] = '\0';
-
-	      sw->part1 = part1;
-	      sw->args = XNEWVEC (const char *, 2);
-	      sw->args[0] = xstrdup (p+1);
-	      sw->args[1] = 0;
+	    default:
+	      read_cmdline_option (&global_options, &global_options_set,
+				   decoded_options + j, CL_DRIVER, &handlers,
+				   global_dc);
+	      break;
 	    }
-	  else
-	    sw->args = 0;
 	}
 
+      alloc_switch ();
       switches[n_switches].part1 = 0;
     }
 }
@@ -6271,14 +6274,17 @@  main (int argc, char **argv)
       if (!compare_debug_second)
 	{
 	  n_switches_debug_check[1] = n_switches;
+	  n_switches_alloc_debug_check[1] = n_switches_alloc;
 	  switches_debug_check[1] = XDUPVEC (struct switchstr, switches,
-					     n_switches + 1);
+					     n_switches_alloc);
 
 	  do_self_spec ("%:compare-debug-self-opt()");
 	  n_switches_debug_check[0] = n_switches;
+	  n_switches_alloc_debug_check[0] = n_switches_alloc;
 	  switches_debug_check[0] = switches;
 
 	  n_switches = n_switches_debug_check[1];
+	  n_switches_alloc = n_switches_alloc_debug_check[1];
 	  switches = switches_debug_check[1];
 	}
 
@@ -6294,9 +6300,11 @@  main (int argc, char **argv)
       if (!compare_debug_second)
 	{
 	  n_switches_debug_check[1] = n_switches;
+	  n_switches_alloc_debug_check[1] = n_switches_alloc;
 	  switches_debug_check[1] = switches;
 	  compare_debug = -compare_debug;
 	  n_switches = n_switches_debug_check[0];
+	  n_switches_alloc = n_switches_debug_check[0];
 	  switches = switches_debug_check[0];
 	}
     }
@@ -6712,12 +6720,14 @@  warranty; not even for MERCHANTABILITY o
 
 		  compare_debug = -compare_debug;
 		  n_switches = n_switches_debug_check[1];
+		  n_switches_alloc = n_switches_alloc_debug_check[1];
 		  switches = switches_debug_check[1];
 
 		  value = do_spec (input_file_compiler->spec);
 
 		  compare_debug = -compare_debug;
 		  n_switches = n_switches_debug_check[0];
+		  n_switches_alloc = n_switches_alloc_debug_check[0];
 		  switches = switches_debug_check[0];
 
 		  if (value < 0)