This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Reorganise cc command line parsing


Hi Guys,

  Here is the reworked version of my -pedantic patch.  This patch
  reorganises the command line parsing of toplev.c so that both the
  language dependent decoder and the language independent decoder are
  given a chance to see all options.  It streamlines the code, making
  it simpler and cleaner, and removes some hackery to cope with a bug
  in the vax c compiler.

  One thing that might be a problem with this patch is that
  lang_decode_option() is now called for every command line option, not
  just the ones that it has placed into documented_lang_options[].
  This solves the problem with -pedantic and cpplib, but it does rely
  upon lang_decode_option() not complaining if it sees an option that
  it was not expecting.  Is this guaranteed for all current language 
  front ends ?

  Another point is that code anticipates that in the future we might
  want to add a language independent option which should only be
  decoded if it has not been decoded by the language dependent
  decoder.  I am not sure if this is actually necessary, but the code
  for this support is very small, so I doubt if it matters.

  May I apply this patch ?

Cheers
	Nick

Tue Sep 14 10:53:19 1999  Nick Clifton  <nickc@cygnus.com>

	* toplev.c (progname): Make 'const char *'
	(flag_print_mem): Move out of main.
	(version_flag): Move out of main.
	(filename): Move out of main.
	(debug_args): Remove g prefix from options.
	(display_help): Add g prefix to debug options.
	(check_lang_option): Delete this function.
	(decode_d_option): New function: Decode -d... option.
	(decode_f_option): New function: Decode -f... option.
	(decode_W_option): New function: Decode -W... option.
	(decode_g_option): New function: Decode -g... option.
	(independent_decode_option): New function: Decode a language
	independent command line option.
	(main): Invoke lang_decode_option and then
	independent_decode_option on each command line option in
	turn. 


Index: gcc/toplev.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/toplev.c,v
retrieving revision 1.219
diff -p -w -r1.219 toplev.c
*** toplev.c	1999/09/12 12:45:39	1.219
--- toplev.c	1999/09/14 09:52:02
*************** static void clean_dump_file PROTO((const
*** 217,222 ****
--- 217,228 ----
  static void compile_file PROTO((char *));
  static void display_help PROTO ((void));
  
+ static void decode_d_option PROTO ((const char *));
+ static int  decode_f_option PROTO ((const char *));
+ static int  decode_W_option PROTO ((const char *));
+ static int  decode_g_option PROTO ((const char *));
+ static unsigned independent_decode_option PROTO ((int, char **, unsigned));
+ 
  static void print_version PROTO((FILE *, const char *));
  static int print_single_switch PROTO((FILE *, int, int, const char *,
  				      const char *, const char *,
*************** void finish_graph_dump_file PROTO ((cons
*** 232,238 ****
  
  /* Name of program invoked, sans directories.  */
  
! char *progname;
  
  /* Copy of arguments to main.  */
  int save_argc;
--- 238,244 ----
  
  /* Name of program invoked, sans directories.  */
  
! const char *progname;
  
  /* Copy of arguments to main.  */
  int save_argc;
*************** int stack_reg_dump = 0;
*** 304,309 ****
--- 310,318 ----
  #ifdef MACHINE_DEPENDENT_REORG
  int mach_dep_reorg_dump = 0;
  #endif
+ static int flag_print_mem = 0;
+ static int version_flag = 0;
+ static char * filename = 0;
  enum graph_dump_types graph_dump_format;
  
  /* Name for output file of assembly code, specified with -o.  */
*************** static struct
*** 792,818 ****
  } *da,
  debug_args[] =
  {
!   { "g",    NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
      "Generate default debug format output" },
!   { "ggdb", NO_DEBUG, 1, "Generate default extended debug format output" },
  #ifdef DBX_DEBUGGING_INFO
!   { "gstabs",  DBX_DEBUG, 0, "Generate STABS format debug output" },
!   { "gstabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
  #endif
  #ifdef DWARF_DEBUGGING_INFO
!   { "gdwarf",  DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
!   { "gdwarf+", DWARF_DEBUG, 1,
      "Generated extended DWARF-1 format debug output" },
  #endif
  #ifdef DWARF2_DEBUGGING_INFO
!   { "gdwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
  #endif
  #ifdef XCOFF_DEBUGGING_INFO
!   { "gxcoff",  XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
!   { "gxcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
  #endif
  #ifdef SDB_DEBUGGING_INFO
!   { "gcoff", SDB_DEBUG, 0, "Generate COFF format debug output" },
  #endif
    { 0, 0, 0, 0 }
  };
--- 801,827 ----
  } *da,
  debug_args[] =
  {
!   { "",       NO_DEBUG, DEFAULT_GDB_EXTENSIONS,
      "Generate default debug format output" },
!   { "gdb",    NO_DEBUG, 1, "Generate default extended debug format output" },
  #ifdef DBX_DEBUGGING_INFO
!   { "stabs",  DBX_DEBUG, 0, "Generate STABS format debug output" },
!   { "stabs+", DBX_DEBUG, 1, "Generate extended STABS format debug output" },
  #endif
  #ifdef DWARF_DEBUGGING_INFO
!   { "dwarf",  DWARF_DEBUG, 0, "Generate DWARF-1 format debug output"},
!   { "dwarf+", DWARF_DEBUG, 1,
      "Generated extended DWARF-1 format debug output" },
  #endif
  #ifdef DWARF2_DEBUGGING_INFO
!   { "dwarf-2", DWARF2_DEBUG, 0, "Enable DWARF-2 debug output" },
  #endif
  #ifdef XCOFF_DEBUGGING_INFO
!   { "xcoff",  XCOFF_DEBUG, 0, "Generate XCOFF format debug output" },
!   { "xcoff+", XCOFF_DEBUG, 1, "Generate extended XCOFF format debug output" },
  #endif
  #ifdef SDB_DEBUGGING_INFO
!   { "coff", SDB_DEBUG, 0, "Generate COFF format debug output" },
  #endif
    { 0, 0, 0, 0 }
  };
*************** display_help ()
*** 4541,4547 ****
    for (i = NUM_ELEM (debug_args); i--;)
      {
        if (debug_args[i].description != NULL)
! 	printf ("  -%-22s %s\n", debug_args[i].arg, debug_args[i].description);
      }
    
    printf ("  -aux-info <file>        Emit declaration info into <file>.X\n");
--- 4550,4556 ----
    for (i = NUM_ELEM (debug_args); i--;)
      {
        if (debug_args[i].description != NULL)
! 	printf ("  -g%-21s %s\n", debug_args[i].arg, debug_args[i].description);
      }
    
    printf ("  -aux-info <file>        Emit declaration info into <file>.X\n");
*************** display_help ()
*** 4661,4942 ****
  	}
      }
  }
- 
- /* Compare the user specified 'option' with the language
-    specific 'lang_option'.  Return true if they match, or
-    if 'option' is a viable prefix of 'lang_option'.  */
- 
- static int
- check_lang_option (option, lang_option)
-      char * option;
-      char * lang_option;
- {
-   lang_independent_options * indep_options;
-   int    len;
-   long    k;
-   char * space;
-   
-   /* Ignore NULL entries.  */
-   if (option == NULL || lang_option == NULL)
-     return 0;
- 
-   if ((space = strchr (lang_option, ' ')) != NULL)
-     len = space - lang_option;
-   else
-     len = strlen (lang_option);
-   
-   /* If they do not match to the first n characters then fail.  */
-   if (strncmp (option, lang_option, len) != 0)
-     return 0;
-   
-   /* Do not accept a lang option, if it matches a normal -f or -W
-      option.  Chill defines a -fpack, but we want to support
-      -fpack-struct.  */
-   
-   /* An exact match is OK  */
-   if ((int) strlen (option) == len)
-     return 1;
-   
-   /* If it is not an -f or -W option allow the match */
-   if (option[0] != '-')
-     return 1;
-   
-   switch (option[1])
-     {
-     case 'f': indep_options = f_options; break;
-     case 'W': indep_options = W_options; break;
-     default:  return 1;
-     }
-   
-   /* The option is a -f or -W option.
-      Skip past the prefix and search for the remainder in the
-      appropriate table of options.  */
-   option += 2;
-   
-   if (option[0] == 'n' && option[1] == 'o' && option[2] == '-')
-     option += 3;
-   
-   for (k = NUM_ELEM (indep_options); k--;)
-     {
-       if (!strcmp (option, indep_options[k].string))
- 	{
- 	  /* The option matched a language independent option,
- 	     do not allow the language specific match.  */
- 	  
- 	  return 0;
- 	}
-     }
-   
-   /* The option matches the start of the langauge specific option
-      and it is not an exact match for a language independent option.  */
-   return 1;
- }
- 
- /* Entry point of cc1/c++.  Decode command args, then call compile_file.
-    Exit code is 35 if can't open files, 34 if fatal error,
-    33 if had nonfatal errors, else success.  */
- 
- int
- main (argc, argv)
-      int argc;
-      char **argv;
- {
-   register int i;
-   char *filename = 0;
-   int flag_print_mem = 0;
-   int version_flag = 0;
-   char *p;
- 
-   /* save in case md file wants to emit args as a comment.  */
-   save_argc = argc;
-   save_argv = argv;
- 
-   p = argv[0] + strlen (argv[0]);
-   while (p != argv[0] && p[-1] != '/'
- #ifdef DIR_SEPARATOR
- 	 && p[-1] != DIR_SEPARATOR
- #endif
- 	 )
-     --p;
-   progname = p;
- 
- #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
-   /* Get rid of any avoidable limit on stack size.  */
-   {
-     struct rlimit rlim;
- 
-     /* Set the stack limit huge so that alloca does not fail.  */
-     getrlimit (RLIMIT_STACK, &rlim);
-     rlim.rlim_cur = rlim.rlim_max;
-     setrlimit (RLIMIT_STACK, &rlim);
-   }
- #endif
- 
- #ifdef HAVE_LC_MESSAGES
-   setlocale (LC_MESSAGES, "");
- #endif
-   (void) bindtextdomain (PACKAGE, localedir);
-   (void) textdomain (PACKAGE);
- 
-   signal (SIGFPE, float_signal);
- 
- #ifdef SIGPIPE
-   signal (SIGPIPE, pipe_closed);
- #endif
- 
-   decl_printable_name = decl_name;
-   lang_expand_expr = (lang_expand_expr_t) do_abort;
- 
-   /* Initialize whether `char' is signed.  */
-   flag_signed_char = DEFAULT_SIGNED_CHAR;
- #ifdef DEFAULT_SHORT_ENUMS
-   /* Initialize how much space enums occupy, by default.  */
-   flag_short_enums = DEFAULT_SHORT_ENUMS;
- #endif
- 
-   /* Initialize the garbage-collector.  */
-   init_ggc ();
-   ggc_add_root (&input_file_stack, 1, sizeof input_file_stack,
- 		&mark_file_stack);
- 
-   /* Perform language-specific options intialization.  */
-   lang_init_options ();
- 
-   /* Scan to see what optimization level has been specified.  That will
-      determine the default value of many flags.  */
-   for (i = 1; i < argc; i++)
-     {
-       if (!strcmp (argv[i], "-O"))
- 	{
- 	  optimize = 1;
- 	  optimize_size = 0;
- 	}
-       else if (argv[i][0] == '-' && argv[i][1] == 'O')
- 	{
- 	  /* Handle -Os, -O2, -O3, -O69, ...  */
- 	  char *p = &argv[i][2];
- 	  
- 	  if ((p[0] == 's') && (p[1] == 0))
- 	    {
- 	      optimize_size = 1;
- 	      
- 	      /* Optimizing for size forces optimize to be 2. */
- 	      optimize = 2;
- 	    }
- 	  else
- 	    {	    
- 	      const int optimize_val = read_integral_parameter (p, p - 2, -1);
- 	      if (optimize_val != -1)
- 		{
- 		  optimize = optimize_val;
- 		  optimize_size = 0;
- 		}
- 	    }
- 	}
-     }
- 
-   obey_regdecls = (optimize == 0);
- 
-   if (optimize >= 1)
-     {
-       flag_defer_pop = 1;
-       flag_thread_jumps = 1;
- #ifdef DELAY_SLOTS
-       flag_delayed_branch = 1;
- #endif
- #ifdef CAN_DEBUG_WITHOUT_FP
-       flag_omit_frame_pointer = 1;
- #endif
-     }
- 
-   if (optimize >= 2)
-     {
-       flag_cse_follow_jumps = 1;
-       flag_cse_skip_blocks = 1;
-       flag_gcse = 1;
-       flag_expensive_optimizations = 1;
-       flag_strength_reduce = 1;
-       flag_rerun_cse_after_loop = 1;
-       flag_rerun_loop_opt = 1;
-       flag_caller_saves = 1;
-       flag_force_mem = 1;
-       flag_peephole2 = 1;
- #ifdef INSN_SCHEDULING
-       flag_schedule_insns = 1;
-       flag_schedule_insns_after_reload = 1;
- #endif
-       flag_regmove = 1;
-       flag_strict_aliasing = 1;
-     }
- 
-   if (optimize >= 3)
-     {
-       flag_inline_functions = 1;
-     }
- 
-   if (optimize < 2 || optimize_size)
-     {
-       align_loops = 1;
-       align_jumps = 1;
-       align_labels = 1;
-       align_functions = 1;
-     }
- 
-   /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
-      modify it.  */
-   target_flags = 0;
-   set_target_switch ("");
- 
- #ifdef OPTIMIZATION_OPTIONS
-   /* Allow default optimizations to be specified on a per-machine basis.  */
-   OPTIMIZATION_OPTIONS (optimize, optimize_size);
- #endif
- 
-   /* Initialize register usage now so switches may override.  */
-   init_reg_sets ();
- 
-   for (i = 1; i < argc; i++)
-     {
-       size_t j;
-       
-       /* If this is a language-specific option,
- 	 decode it in a language-specific way.  */
-       for (j = NUM_ELEM (documented_lang_options); j--;)
- 	if (check_lang_option (argv[i], documented_lang_options[j].option))
- 	  break;
-       
-       if (j != (size_t)-1)
- 	{
- 	  /* If the option is valid for *some* language,
- 	     treat it as valid even if this language doesn't understand it.  */
- 	  int strings_processed = lang_decode_option (argc - i, argv + i);
- 	  
- 	  if (!strcmp (argv[i], "--help"))
- 	    {
- 	      display_help ();
- 	      exit (0);
- 	    }
  	  
! 	  if (strings_processed != 0)
! 	    i += strings_processed - 1;
! 	}
!       else if (argv[i][0] == '-' && argv[i][1] != 0)
! 	{
! 	  register char *str = argv[i] + 1;
! 	  if (str[0] == 'Y')
! 	    str++;
  
! 	  if (str[0] == 'm')
! 	    set_target_switch (&str[1]);
! 	  else if (!strcmp (str, "dumpbase"))
! 	    {
! 	      dump_base_name = argv[++i];
! 	    }
! 	  else if (str[0] == 'd')
  	    {
! 	      register char *p = &str[1];
! 	      while (*p)
! 		switch (*p++)
  		  {
   		  case 'a':
  		    branch_prob_dump = 1;
--- 4670,4684 ----
  	}
      }
  }
  
! /* Parse a -d... comand line switch.  */
  
! static void
! decode_d_option (arg)
!      const char * arg;
  {
!   while (* arg)
!     switch (* arg ++)
        {
        case 'a':
  	branch_prob_dump = 1;
*************** main (argc, argv)
*** 4954,4960 ****
   		    loop_dump = 1;
  		    regmove_dump = 1;
   		    rtl_dump = 1;
!  		    cse_dump = 1, cse2_dump = 1;
  		    gcse_dump = 1;
   		    sched_dump = 1;
   		    sched2_dump = 1;
--- 4696,4703 ----
  	loop_dump = 1;
  	regmove_dump = 1;
  	rtl_dump = 1;
! 	cse_dump = 1;
! 	cse2_dump = 1;
  	gcse_dump = 1;
  	sched_dump = 1;
  	sched2_dump = 1;
*************** main (argc, argv)
*** 5053,5192 ****
  		  case 'z':
  		    peephole2_dump = 1;
  		    break;
! 		  case 'D':	/* these are handled by the preprocessor */
  		  case 'I':
  		    break;
  		  default:
! 		    warning ("unrecognised gcc debugging option: %c", p[-1]);
  		    break;
  		  }
  	    }
- 	  else if (str[0] == 'f')
- 	    {
- 	      register char *p = &str[1];
- 	      int found = 0;
  
! 	      /* Some kind of -f option.
! 		 P's value is the option sans `-f'.
! 		 Search for it in the table of options.  */
  
! 	      for (j = 0;
! 		   !found && j < sizeof (f_options) / sizeof (f_options[0]);
! 		   j++)
  		{
! 		  if (!strcmp (p, f_options[j].string))
  		    {
  		      *f_options[j].variable = f_options[j].on_value;
! 		      /* A goto here would be cleaner,
! 			 but breaks the vax pcc.  */
! 		      found = 1;
  		    }
! 		  if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
! 		      && ! strcmp (p+3, f_options[j].string))
  		    {
  		      *f_options[j].variable = ! f_options[j].on_value;
! 		      found = 1;
  		    }
  		}
  
! 	      if (found)
! 		;
! 	      else if (!strncmp (p, "inline-limit-", 13)
! 		       || !strncmp (p, "inline-limit=", 13))
  	        inline_max_insns =
! 		  read_integral_parameter (p + 13, p - 2, inline_max_insns);
  #ifdef INSN_SCHEDULING
! 	      else if (!strncmp (p, "sched-verbose=",14))
! 		fix_sched_param("verbose",&p[14]);
  #endif
! 	      else if (!strncmp (p, "fixed-", 6))
! 		fix_register (&p[6], 1, 1);
! 	      else if (!strncmp (p, "call-used-", 10))
! 		fix_register (&p[10], 0, 1);
! 	      else if (!strncmp (p, "call-saved-", 11))
! 		fix_register (&p[11], 0, 0);
! 	      else if (!strncmp (p, "align-loops=", 12))
! 		align_loops = read_integral_parameter (p + 12, p - 2,
! 						       align_loops);
! 	      else if (!strncmp (p, "align-functions=", 16))
! 		align_functions = read_integral_parameter (p + 16, p - 2,
! 						       align_functions);
! 	      else if (!strncmp (p, "align-jumps=", 12))
! 		align_jumps = read_integral_parameter (p + 12, p - 2,
! 						       align_jumps);
! 	      else if (!strncmp (p, "align-labels=", 13))
! 		align_labels = read_integral_parameter (p + 13, p - 2,
! 							align_labels);
  	      else
! 		error ("Invalid option `%s'", argv[i]);
! 	    }
! 	  else if (str[0] == 'O')
! 	    {
! 	      /* Already been treated above. Do nothing.  */
! 	    }
! 	  else if (!strcmp (str, "pedantic"))
! 	    pedantic = 1;
! 	  else if (!strcmp (str, "pedantic-errors"))
! 	    flag_pedantic_errors = pedantic = 1;
! 	  else if (!strcmp (str, "quiet"))
! 	    quiet_flag = 1;
! 	  else if (!strcmp (str, "version"))
! 	    version_flag = 1;
! 	  else if (!strcmp (str, "w"))
! 	    inhibit_warnings = 1;
! 	  else if (!strcmp (str, "W"))
! 	    {
! 	      extra_warnings = 1;
! 	      /* We save the value of warn_uninitialized, since if they put
! 		 -Wuninitialized on the command line, we need to generate a
! 		 warning about not using it without also specifying -O.  */
! 	      if (warn_uninitialized != 1)
! 		warn_uninitialized = 2;
  	    }
! 	  else if (str[0] == 'W')
  	    {
! 	      register char *p = &str[1];
! 	      int found = 0;
  
! 	      /* Some kind of -W option.
! 		 P's value is the option sans `-W'.
! 		 Search for it in the table of options.  */
  
! 	      for (j = 0;
! 		   !found && j < sizeof (W_options) / sizeof (W_options[0]);
! 		   j++)
  		{
! 		  if (!strcmp (p, W_options[j].string))
  		    {
  		      *W_options[j].variable = W_options[j].on_value;
! 		      /* A goto here would be cleaner,
! 			 but breaks the vax pcc.  */
! 		      found = 1;
  		    }
! 		  if (p[0] == 'n' && p[1] == 'o' && p[2] == '-'
! 		      && ! strcmp (p+3, W_options[j].string))
  		    {
  		      *W_options[j].variable = ! W_options[j].on_value;
! 		      found = 1;
  		    }
  		}
  
! 	      if (found)
! 		;
! 	      else if (!strncmp (p, "id-clash-", 9))
  		{
! 		  const int id_clash_val
! 		    = read_integral_parameter (p + 9, p - 2, -1);
  		  if (id_clash_val != -1)
  		    {
  		      id_clash_len = id_clash_val;
  		      warn_id_clash = 1;
  		    }
  		}
! 	      else if (!strncmp (p, "larger-than-", 12))
  		{
! 		  const int larger_than_val
! 		    = read_integral_parameter (p + 12, p - 2, -1);
  		  if (larger_than_val != -1)
  		    {
  		      larger_than_size = larger_than_val;
--- 4796,4907 ----
        case 'z':
  	peephole2_dump = 1;
  	break;
!       case 'D':	/* These are handled by the preprocessor.  */
        case 'I':
  	break;
        default:
! 	warning ("unrecognised gcc debugging option: %c", arg[-1]);
  	break;
        }
  }
  
! /* Parse a -f... comand line switch.  ARG is the value after the -f.
!    It is safe to access 'ARG - 2' to generate the full switch name.
!    Return the number of strings consumed.  */
! 
! static int
! decode_f_option (arg)
!      const char * arg;
! {
!   int j;
  
!   /* Search for the option in the table of binary f options.  */
!   for (j = sizeof (f_options) / sizeof (f_options[0]); j--;)
      {
!       if (!strcmp (arg, f_options[j].string))
  	{
  	  *f_options[j].variable = f_options[j].on_value;
! 	  return 1;
  	}
!     
!       if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
! 	  && ! strcmp (arg + 3, f_options[j].string))
  	{
  	  *f_options[j].variable = ! f_options[j].on_value;
! 	  return 1;
  	}
      }
  
!   if (!strncmp (arg, "inline-limit-", 13)
!       || !strncmp (arg, "inline-limit=", 13))
      inline_max_insns =
!       read_integral_parameter (arg + 13, arg - 2, inline_max_insns);
  #ifdef INSN_SCHEDULING
!   else if (!strncmp (arg, "sched-verbose=", 14))
!     fix_sched_param ("verbose", (char *)(arg + 14));
  #endif
!   else if (!strncmp (arg, "fixed-", 6))
!     fix_register ((char *)(arg + 6), 1, 1);
!   else if (!strncmp (arg, "call-used-", 10))
!     fix_register ((char *)(arg + 10), 0, 1);
!   else if (!strncmp (arg, "call-saved-", 11))
!     fix_register ((char *)(arg + 11), 0, 0);
!   else if (!strncmp (arg, "align-loops=", 12))
!     align_loops = read_integral_parameter (arg + 12, arg - 2, align_loops);
!   else if (!strncmp (arg, "align-functions=", 16))
!     align_functions =
!       read_integral_parameter (arg + 16, arg - 2, align_functions);
!   else if (!strncmp (arg, "align-jumps=", 12))
!     align_jumps = read_integral_parameter (arg + 12, arg - 2, align_jumps);
!   else if (!strncmp (arg, "align-labels=", 13))
!     align_labels = read_integral_parameter (arg + 13, arg - 2, align_labels);
    else
!     return 0;
! 
!   return 1;
  }
! 
! /* Parse a -W... comand line switch.  ARG is the value after the -W.
!    It is safe to access 'ARG - 2' to generate the full switch name.
!    Return the number of strings consumed.  */
! static int
! decode_W_option (arg)
!      const char * arg;
  {
!   int j;
    
!   /* Search for the option in the table of binary W options.  */
  
!   for (j = sizeof (W_options) / sizeof (W_options[0]); j--;)
      {
!       if (!strcmp (arg, W_options[j].string))
  	{
  	  *W_options[j].variable = W_options[j].on_value;
! 	  return 1;
  	}
! 
!       if (arg[0] == 'n' && arg[1] == 'o' && arg[2] == '-'
! 	  && ! strcmp (arg + 3, W_options[j].string))
  	{
  	  *W_options[j].variable = ! W_options[j].on_value;
! 	  return 1;
  	}
      }
  
!   if (!strncmp (arg, "id-clash-", 9))
      {
!       const int id_clash_val = read_integral_parameter (arg + 9, arg - 2, -1);
!       
        if (id_clash_val != -1)
  	{
  	  id_clash_len = id_clash_val;
  	  warn_id_clash = 1;
  	}
      }
!   else if (!strncmp (arg, "larger-than-", 12))
      {
!       const int larger_than_val =
! 	read_integral_parameter (arg + 12, arg - 2, -1);
        if (larger_than_val != -1)
  	{
  	  larger_than_size = larger_than_val;
*************** main (argc, argv)
*** 5194,5224 ****
  		    }
  		}
  	      else
! 		error ("Invalid option `%s'", argv[i]);
  	    }
! 	  else if (!strcmp (str, "p"))
  	    {
- 	      profile_flag = 1;
- 	    }
- 	  else if (!strcmp (str, "a"))
- 	    {
- #if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
- 	      warning ("`-a' option (basic block profile) not supported");
- #else
-               profile_block_flag = (profile_block_flag < 2) ? 1 : 3;
- #endif
- 	    }
- 	  else if (!strcmp (str, "ax"))
- 	    {
- #if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
- 	      warning ("`-ax' option (jump profiling) not supported");
- #else
- 	      profile_block_flag = (!profile_block_flag 
- 	                               || profile_block_flag == 2) ? 2 : 3;
- #endif
- 	    }
- 	  else if (str[0] == 'g')
- 	    {
  	      unsigned level;
  	      /* A lot of code assumes write_symbols == NO_DEBUG if the
  		 debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
--- 4909,4926 ----
  	}
      }
    else
!     return 0;
! 
!   return 1;
  }
! 
! /* Parse a -g... comand line switch.  ARG is the value after the -g.
!    It is safe to access 'ARG - 2' to generate the full switch name.
!    Return the number of strings consumed.  */
! static int
! decode_g_option (arg)
!      const char * arg;
  {
    unsigned level;
    /* A lot of code assumes write_symbols == NO_DEBUG if the
       debugging level is 0 (thus -gstabs1 -gstabs0 would lose track
*************** main (argc, argv)
*** 5239,5253 ****
  	      /* The maximum admissible debug level value.  */
  	      static const unsigned max_debug_level = 3;
  
! 	      /* Look up STR in the table.  */
  	      for (da = debug_args; da->arg; da++)
  		{
  		  const int da_len = strlen (da->arg);
  
! 		  if (! strncmp (str, da->arg, da_len))
  		    {
  		      enum debug_info_type type = da->debug_type;
! 		      const char *p = str + da_len;
  
  		      if (*p && (*p < '0' || *p > '9'))
  			continue;
--- 4941,4955 ----
    /* The maximum admissible debug level value.  */
    static const unsigned max_debug_level = 3;
    
!   /* Look up ARG in the table.  */
    for (da = debug_args; da->arg; da++)
      {
        const int da_len = strlen (da->arg);
  
!       if (da_len == 0 || ! strncmp (arg, da->arg, da_len))
  	{
  	  enum debug_info_type type = da->debug_type;
! 	  const char * p = arg + da_len;
  	  
  	  if (*p && (*p < '0' || *p > '9'))
  	    continue;
*************** main (argc, argv)
*** 5261,5272 ****
  			 read_integral_parameter to better handle this case
  			 if this case shows up often.  */
  		      if (*p)
! 			level = read_integral_parameter (p, 0,
! 							 max_debug_level + 1);
  		      else
  			level = 2;
  
! 		      if (da_len > 1 && *p && !strncmp (str, "gdwarf", da_len))
  			{
  			  error ("use -gdwarf -g%d for DWARF v1, level %d",
  				 level, level);
--- 4963,4973 ----
  	     read_integral_parameter to better handle this case
  	     if this case shows up often.  */
  	  if (*p)
! 	    level = read_integral_parameter (p, 0, max_debug_level + 1);
  	  else
  	    level = 2;
  	  
! 	  if (da_len > 1 && *p && !strncmp (arg, "dwarf", da_len))
  	    {
  	      error ("use -gdwarf -g%d for DWARF v1, level %d",
  		     level, level);
*************** main (argc, argv)
*** 5276,5290 ****
  
  		      if (level > max_debug_level)
  			{
! 			  warning ("ignoring option `%s' due to invalid debug level specification",
! 				   str - 1);
  			  level = debug_info_level;
  			}
  
  		      if (type == NO_DEBUG)
  			{
  			  type = PREFERRED_DEBUGGING_TYPE;
! 			  if (da_len > 1 && strncmp (str, "ggdb", da_len) == 0)
  			    {
  #if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
  			      type = DWARF2_DEBUG;
--- 4977,4993 ----
  	  
  	  if (level > max_debug_level)
  	    {
! 	      warning ("\
! ignoring option `%s' due to invalid debug level specification",
! 		       arg - 2);
  	      level = debug_info_level;
  	    }
  
  	  if (type == NO_DEBUG)
  	    {
  	      type = PREFERRED_DEBUGGING_TYPE;
! 	      
! 	      if (da_len > 1 && strncmp (arg, "gdb", da_len) == 0)
  		{
  #if defined (DWARF2_DEBUGGING_INFO) && !defined (LINKER_DOES_NOT_WORK_WITH_DWARF2)
  		  type = DWARF2_DEBUG;
*************** main (argc, argv)
*** 5297,5374 ****
  			}
  
  		      if (type == NO_DEBUG)
! 			warning ("`-%s' not supported by this configuration of GCC",
! 				 str);
  
  		      /* Does it conflict with an already selected type?  */
  		      if (type_explicitly_set_p
  			  /* -g/-ggdb don't conflict with anything */
  			  && da->debug_type != NO_DEBUG
  			  && type != selected_debug_type)
! 			warning ("`-%s' ignored, conflicts with `-g%s'",
! 				 str, debug_type_names[(int) selected_debug_type]);
  		      else
  			{
  			  /* If the format has already been set, -g/-ggdb
  			     only change the debug level.  */
! 			  if (type_explicitly_set_p
! 			      && da->debug_type == NO_DEBUG)
  			    ; /* don't change debugging type */
  			  else
  			    {
  			      selected_debug_type = type;
  			      type_explicitly_set_p = da->debug_type != NO_DEBUG;
  			    }
  			  write_symbols = (level == 0
  					   ? NO_DEBUG
  					   : selected_debug_type);
  			  use_gnu_debug_info_extensions = da->use_extensions_p;
  			  debug_info_level = (enum debug_info_level) level;
  			}
  		      break;
  		    }
  		}
  	      if (! da->arg)
! 		warning ("`-%s' not supported by this configuration of GCC",
! 			 str);
  	    }
! 	  else if (!strcmp (str, "o"))
  	    {
! 	      asm_file_name = argv[++i];
  	    }
! 	  else if (str[0] == 'G')
  	    {
! 	      const int g_switch_val = (str[1] != '\0') ?
! 	                               read_integral_parameter(str + 1, 0, -1) :
! 			               read_integral_parameter(argv[++i], 0, -1);
  	      
! 	      if (g_switch_val != -1)
  	        {
  		  g_switch_set = TRUE;
  		  g_switch_value = g_switch_val;
  		}
  	      else
  	        {
! 		  error("Invalid option `-%s'",str);
  		}
  	    }
! 	  else if (!strncmp (str, "aux-info", 8))
  	    {
! 	      flag_gen_aux_info = 1;
! 	      aux_info_file_name = (str[8] != '\0' ? str+8 : argv[++i]);
  	    }
! 	  else if (!strcmp (str, "-help"))
  	    {
! 	      display_help ();
! 	      exit (0);
  	    }
  	  else
  	    error ("Invalid option `%s'", argv[i]);
  	}
-       else if (argv[i][0] == '+')
- 	error ("Invalid option `%s'", argv[i]);
-       else
- 	filename = argv[i];
      }
  
    /* Checker uses the frame pointer.  */
--- 5000,5422 ----
  	    }
  	  
  	  if (type == NO_DEBUG)
! 	    warning ("`%s' not supported by this configuration of GCC",
! 		     arg - 2);
  
  	  /* Does it conflict with an already selected type?  */
  	  if (type_explicitly_set_p
  	      /* -g/-ggdb don't conflict with anything */
  	      && da->debug_type != NO_DEBUG
  	      && type != selected_debug_type)
! 	    warning ("`%s' ignored, conflicts with `-g%s'",
! 		     arg - 2, debug_type_names[(int) selected_debug_type]);
  	  else
  	    {
  	      /* If the format has already been set, -g/-ggdb
  		 only change the debug level.  */
! 	      if (type_explicitly_set_p && da->debug_type == NO_DEBUG)
  		; /* don't change debugging type */
  	      else
  		{
  		  selected_debug_type = type;
  		  type_explicitly_set_p = da->debug_type != NO_DEBUG;
  		}
+ 	      
  	      write_symbols = (level == 0
  			       ? NO_DEBUG
  			       : selected_debug_type);
  	      use_gnu_debug_info_extensions = da->use_extensions_p;
  	      debug_info_level = (enum debug_info_level) level;
  	    }
+ 	  
  	  break;
  	}
      }
+   
    if (! da->arg)
!     warning ("`%s' not supported by this configuration of GCC", arg - 2);
! 
!   return 1;
! }
! 
! /* Decode the first argument in the argv as a language-independent option.
!    Return the number of strings consumed.  'strings_processed' is the
!    number of strings that have already been decoded in a language
!    specific fashion before this function was invoked.  */
!    
! static unsigned
! independent_decode_option (argc, argv, strings_processed)
!      int argc;
!      char ** argv;
!      unsigned strings_processed ATTRIBUTE_UNUSED;
! {
!   char * arg = argv[0];
!   
!   if (arg[0] != '-' || arg[1] == 0)
!     {
!       if (arg[0] == '+')
! 	return 0;
!       
!       filename = arg;
! 
!       return 1;
!     }
! 
!   arg ++;
!   
!   if (!strcmp (arg, "-help"))
!     {
!       display_help ();
!       exit (0);
!     }
! 
!   if (* arg == 'Y')
!     arg ++;
!   
!   switch (* arg)
!     {
!     default:
!       return 0;
!       
!     case 'O':
!       /* Already been treated in main (). Do nothing.  */
!       break;
! 	  
!     case 'm':
!       set_target_switch (arg + 1);
!       break;
! 
!     case 'f':
!       return decode_f_option (arg + 1);
! 	    
!     case 'g':
!       return decode_g_option (arg + 1);
! 
!     case 'd':
!       if (!strcmp (arg, "dumpbase"))
! 	{
! 	  if (argc == 1)
! 	    return 0;
! 	  
! 	  dump_base_name = argv[1];
! 	  return 2;
! 	}
!       else
! 	decode_d_option (arg + 1);
!       break;
! 
!     case 'p':
!       if (!strcmp (arg, "pedantic"))
! 	pedantic = 1;
!       else if (!strcmp (arg, "pedantic-errors"))
! 	flag_pedantic_errors = pedantic = 1;
!       else if (arg[1] == 0)
! 	profile_flag = 1;
!       else
! 	return 0;
!       break;
! 
!     case 'q':
!       if (!strcmp (arg, "quiet"))
! 	quiet_flag = 1;
!       else
! 	return 0;
!       break;
! 
!     case 'v':
!       if (!strcmp (arg, "version"))
! 	version_flag = 1;
!       else
! 	return 0;
!       break;
! 
!     case 'w':
!       if (arg[1] == 0)
! 	inhibit_warnings = 1;
!       else
! 	return 0;
!       break;
! 
!     case 'W':
!       if (arg[1] == 0)
! 	{
! 	  extra_warnings = 1;
! 	  /* We save the value of warn_uninitialized, since if they put
! 	     -Wuninitialized on the command line, we need to generate a
! 	     warning about not using it without also specifying -O.  */
! 	  if (warn_uninitialized != 1)
! 	    warn_uninitialized = 2;
! 	}
!       else
! 	return decode_W_option (arg + 1);
!       break;
! 	  
!     case 'a':
!       if (arg[1] == 0)
! 	{
! #if !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
! 	  warning ("`-a' option (basic block profile) not supported");
! #else
! 	  profile_block_flag = (profile_block_flag < 2) ? 1 : 3;
! #endif
! 	}
!       else if (!strcmp (arg, "ax"))
! 	{
! #if !defined (FUNCTION_BLOCK_PROFILER_EXIT) || !defined (BLOCK_PROFILER) || !defined (FUNCTION_BLOCK_PROFILER)
! 	  warning ("`-ax' option (jump profiling) not supported");
! #else
! 	  profile_block_flag = (!profile_block_flag 
! 				|| profile_block_flag == 2) ? 2 : 3;
! #endif
! 	}
!       else if (!strncmp (arg, "aux-info", 8))
! 	{
! 	  flag_gen_aux_info = 1;
! 	  if (arg[8] == '\0')
! 	    {
! 	      if (argc == 1)
! 		return 0;
! 	      
! 	      aux_info_file_name = argv[1];
! 	      return 2;
  	    }
! 	  else
! 	    aux_info_file_name = arg + 8;
! 	}
!       else
! 	return 0;
!       break;
! 
!     case 'o':
!       if (arg[1] == 0)
  	{
! 	  if (argc == 1)
! 	    return 0;
! 	  
! 	  asm_file_name = argv[1];
! 	  return 2;
  	}
!       return 0;
! 
!     case 'G':
        {
! 	int g_switch_val;
! 	int return_val;
  	    
! 	if (arg[1] == 0)
  	  {
+ 	    if (argc == 1)
+ 	      return 0;
+ 	    
+ 	    g_switch_val = read_integral_parameter (argv[1], 0, -1);
+ 	    return_val = 2;
+ 	  }
+ 	else
+ 	  {
+ 	    g_switch_val = read_integral_parameter (arg + 1, 0, -1);
+ 	    return_val = 1;
+ 	  }
+ 	    
+ 	if (g_switch_val == -1)
+ 	  return_val = 0;
+ 	else
+ 	  {
  	    g_switch_set = TRUE;
  	    g_switch_value = g_switch_val;
  	  }
+ 	    
+ 	return return_val;
+       }
+     }
+   
+   return 1;
+ }
+ 
+ /* Entry point of cc1/c++.  Decode command args, then call compile_file.
+    Exit code is 35 if can't open files, 34 if fatal error,
+    33 if had nonfatal errors, else success.  */
+ 
+ int
+ main (argc, argv)
+      int argc;
+      char **argv;
+ {
+   register int i;
+   char *p;
+ 
+   /* save in case md file wants to emit args as a comment.  */
+   save_argc = argc;
+   save_argv = argv;
+ 
+   p = argv[0] + strlen (argv[0]);
+   while (p != argv[0] && p[-1] != '/'
+ #ifdef DIR_SEPARATOR
+ 	 && p[-1] != DIR_SEPARATOR
+ #endif
+ 	 )
+     --p;
+   progname = p;
+ 
+ #if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT)
+   /* Get rid of any avoidable limit on stack size.  */
+   {
+     struct rlimit rlim;
+ 
+     /* Set the stack limit huge so that alloca does not fail.  */
+     getrlimit (RLIMIT_STACK, &rlim);
+     rlim.rlim_cur = rlim.rlim_max;
+     setrlimit (RLIMIT_STACK, &rlim);
+   }
+ #endif
+ 
+ #ifdef HAVE_LC_MESSAGES
+   setlocale (LC_MESSAGES, "");
+ #endif
+   (void) bindtextdomain (PACKAGE, localedir);
+   (void) textdomain (PACKAGE);
+ 
+   signal (SIGFPE, float_signal);
+ 
+ #ifdef SIGPIPE
+   signal (SIGPIPE, pipe_closed);
+ #endif
+ 
+   decl_printable_name = decl_name;
+   lang_expand_expr = (lang_expand_expr_t) do_abort;
+ 
+   /* Initialize whether `char' is signed.  */
+   flag_signed_char = DEFAULT_SIGNED_CHAR;
+ #ifdef DEFAULT_SHORT_ENUMS
+   /* Initialize how much space enums occupy, by default.  */
+   flag_short_enums = DEFAULT_SHORT_ENUMS;
+ #endif
+ 
+   /* Initialize the garbage-collector.  */
+   init_ggc ();
+   ggc_add_root (&input_file_stack, 1, sizeof input_file_stack,
+ 		&mark_file_stack);
+ 
+   /* Perform language-specific options intialization.  */
+   lang_init_options ();
+ 
+   /* Scan to see what optimization level has been specified.  That will
+      determine the default value of many flags.  */
+   for (i = 1; i < argc; i++)
+     {
+       if (!strcmp (argv[i], "-O"))
+ 	{
+ 	  optimize = 1;
+ 	  optimize_size = 0;
+ 	}
+       else if (argv[i][0] == '-' && argv[i][1] == 'O')
+ 	{
+ 	  /* Handle -Os, -O2, -O3, -O69, ...  */
+ 	  char *p = &argv[i][2];
+ 	  
+ 	  if ((p[0] == 's') && (p[1] == 0))
+ 	    {
+ 	      optimize_size = 1;
+ 	      
+ 	      /* Optimizing for size forces optimize to be 2. */
+ 	      optimize = 2;
+ 	    }
  	  else
+ 	    {	    
+ 	      const int optimize_val = read_integral_parameter (p, p - 2, -1);
+ 	      if (optimize_val != -1)
  		{
! 		  optimize = optimize_val;
! 		  optimize_size = 0;
! 		}
! 	    }
  	}
      }
! 
!   obey_regdecls = (optimize == 0);
! 
!   if (optimize >= 1)
      {
!       flag_defer_pop = 1;
!       flag_thread_jumps = 1;
! #ifdef DELAY_SLOTS
!       flag_delayed_branch = 1;
! #endif
! #ifdef CAN_DEBUG_WITHOUT_FP
!       flag_omit_frame_pointer = 1;
! #endif
      }
! 
!   if (optimize >= 2)
      {
!       flag_cse_follow_jumps = 1;
!       flag_cse_skip_blocks = 1;
!       flag_gcse = 1;
!       flag_expensive_optimizations = 1;
!       flag_strength_reduce = 1;
!       flag_rerun_cse_after_loop = 1;
!       flag_rerun_loop_opt = 1;
!       flag_caller_saves = 1;
!       flag_force_mem = 1;
!       flag_peephole2 = 1;
! #ifdef INSN_SCHEDULING
!       flag_schedule_insns = 1;
!       flag_schedule_insns_after_reload = 1;
! #endif
!       flag_regmove = 1;
!       flag_strict_aliasing = 1;
!     }
! 
!   if (optimize >= 3)
!     {
!       flag_inline_functions = 1;
!     }
! 
!   if (optimize < 2 || optimize_size)
!     {
!       align_loops = 1;
!       align_jumps = 1;
!       align_labels = 1;
!       align_functions = 1;
      }
+ 
+   /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
+      modify it.  */
+   target_flags = 0;
+   set_target_switch ("");
+ 
+ #ifdef OPTIMIZATION_OPTIONS
+   /* Allow default optimizations to be specified on a per-machine basis.  */
+   OPTIMIZATION_OPTIONS (optimize, optimize_size);
+ #endif
+ 
+   /* Initialize register usage now so switches may override.  */
+   init_reg_sets ();
+ 
+   /* Perform normal command line switch decoding.  */
+   for (i = 1; i < argc;)
+     {
+       unsigned lang_processed;
+       unsigned indep_processed;
+       
+       /* Give the language a chance to decode the option for itself.  */
+       lang_processed = lang_decode_option (argc - i, argv + i);
+  
+       /* Now see if the option also has a language independent meaning.
+ 	 Some options are both language specific and language independent,
+ 	 eg --help.  It is possible that there might be options that should
+ 	 only be decoded in a language independent way if the were not
+ 	 decoded in a langauge specific way, which is why 'lang_processed'
+ 	 is passed in.  */
+ 
+       indep_processed = independent_decode_option (argc - i, argv + i, lang_processed);
+ 
+       if (lang_processed || indep_processed)
+ 	i += lang_processed > indep_processed ? lang_processed : indep_processed;
        else
+ 	{
  	  error ("Invalid option `%s'", argv[i]);
+ 	  i++;
  	}
      }
  
    /* Checker uses the frame pointer.  */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]