diff mbox

Move various option-handling functions between opts.c, opts-global.c etc.

Message ID Pine.LNX.4.64.1011231817000.9671@digraph.polyomino.org.uk
State New
Headers show

Commit Message

Joseph Myers Nov. 23, 2010, 6:18 p.m. UTC
This patch moves various option-handling functions (and a few
variables and one structure) to bring things closer to the desired
arrangements described in
<http://gcc.gnu.org/ml/gcc-patches/2010-11/msg01778.html> where opts.c
avoids global state as far as possible and can be linked into the
driver.

Various functions using global state or langhooks (that do not need to
go in the driver) move to opts-global.c.  Some functions move from
toplev.c to opts.c; some from opts.c to opts-common.c where that seems
to be a better place.  "struct visibility_flags" was only actually
used in C-family front ends, so moves into c-common.h and the
associated variable visibility_options moves into c-common.c.

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

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

	* flag-types.h (struct visibility_flags): Don't declare here.
	* flags.h (strip_off_ending, fast_math_flags_set_p,
	fast_math_flags_struct_set_p): Declare here.
	(visibility_options): Don't declare here.
	* opts-common.c (option_enabled, get_option_state): Move from
	opts.c.
	* opts-global.c: Include diagnostic.h instead of
	diagnostic-core.h.  Include tree.h, langhooks.h, lto-streamer.h
	and toplev.h.
	(const_char_p, ignored_options, in_fnames, num_in_fnames,
	write_langs, complain_wrong_lang, postpone_unknown_option_warning,
	print_ignored_options, unknown_option_callback,
	post_handling_callback, lang_handle_option, add_input_filename,
	read_cmdline_options, initial_lang_mask, init_options_once,
	decode_cmdline_options_to_array_default_mask,
	set_default_handlers, decode_options): Move from opts.c.
	(print_ignored_options): Use warning_at instead of saving and
	restoring input_location.
	* opts.c: Include <signal.h> and <sys/resource.h>.  Include rtl.h
	instead of expr.h.  Don't include langhooks.h, except.h or
	lto-streamer.h.  Add more comments on includes.
	(strip_off_ending, setup_core_dumping, decode_d_option): Move from
	toplev.c.
	(visibility_options): Move to c-family/c-common.c.
	(const_char_p, ignored_options, in_fnames, num_in_fnames,
	write_langs, complain_wrong_lang, postpone_unknown_option_warning,
	print_ignored_options, unknown_option_callback,
	post_handling_callback, lang_handle_option, add_input_filename,
	read_cmdline_options, initial_lang_mask, init_options_once,
	decode_cmdline_options_to_array_default_mask,
	set_default_handlers, decode_options): Move to opts-global.c.
	(target_handle_option, default_options_optimization,
	finish_options, common_handle_option): Remove static.
	(option_enabled, get_option_state): Move to opts-common.c.
	* opts.h (common_handle_option, target_handle_option,
	finish_options, default_options_optimization): Declare.
	* toplev.c: Don't include <signal.h> or <sys/resource.h>.
	(setup_core_dumping, strip_off_ending, decode_d_option): Move to
	opts.c.
	* toplev.h (strip_off_ending, decode_d_option,
	fast_math_flags_set_p, fast_math_flags_struct_set_p): Don't
	declare here.
	* Makefile.in (opts.o, opts-global.o): Update dependencies.

c-family:
2010-11-23  Joseph Myers  <joseph@codesourcery.com>

	* c-common.c (visibility_options): Move from ../opts.c.
	* c-common.h (struct visibility_flags, visibility_options):
	Declare here.
	* c-opts.c (finish_options): Rename to c_finish_options.
	(c_common_init): Update call to finish_options.

Comments

Richard Biener Nov. 24, 2010, 11:42 a.m. UTC | #1
On Tue, Nov 23, 2010 at 7:18 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> This patch moves various option-handling functions (and a few
> variables and one structure) to bring things closer to the desired
> arrangements described in
> <http://gcc.gnu.org/ml/gcc-patches/2010-11/msg01778.html> where opts.c
> avoids global state as far as possible and can be linked into the
> driver.
>
> Various functions using global state or langhooks (that do not need to
> go in the driver) move to opts-global.c.  Some functions move from
> toplev.c to opts.c; some from opts.c to opts-common.c where that seems
> to be a better place.  "struct visibility_flags" was only actually
> used in C-family front ends, so moves into c-common.h and the
> associated variable visibility_options moves into c-common.c.
>
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  OK to
> commit?

Ok.

Thanks,
Richard.

> 2010-11-23  Joseph Myers  <joseph@codesourcery.com>
>
>        * flag-types.h (struct visibility_flags): Don't declare here.
>        * flags.h (strip_off_ending, fast_math_flags_set_p,
>        fast_math_flags_struct_set_p): Declare here.
>        (visibility_options): Don't declare here.
>        * opts-common.c (option_enabled, get_option_state): Move from
>        opts.c.
>        * opts-global.c: Include diagnostic.h instead of
>        diagnostic-core.h.  Include tree.h, langhooks.h, lto-streamer.h
>        and toplev.h.
>        (const_char_p, ignored_options, in_fnames, num_in_fnames,
>        write_langs, complain_wrong_lang, postpone_unknown_option_warning,
>        print_ignored_options, unknown_option_callback,
>        post_handling_callback, lang_handle_option, add_input_filename,
>        read_cmdline_options, initial_lang_mask, init_options_once,
>        decode_cmdline_options_to_array_default_mask,
>        set_default_handlers, decode_options): Move from opts.c.
>        (print_ignored_options): Use warning_at instead of saving and
>        restoring input_location.
>        * opts.c: Include <signal.h> and <sys/resource.h>.  Include rtl.h
>        instead of expr.h.  Don't include langhooks.h, except.h or
>        lto-streamer.h.  Add more comments on includes.
>        (strip_off_ending, setup_core_dumping, decode_d_option): Move from
>        toplev.c.
>        (visibility_options): Move to c-family/c-common.c.
>        (const_char_p, ignored_options, in_fnames, num_in_fnames,
>        write_langs, complain_wrong_lang, postpone_unknown_option_warning,
>        print_ignored_options, unknown_option_callback,
>        post_handling_callback, lang_handle_option, add_input_filename,
>        read_cmdline_options, initial_lang_mask, init_options_once,
>        decode_cmdline_options_to_array_default_mask,
>        set_default_handlers, decode_options): Move to opts-global.c.
>        (target_handle_option, default_options_optimization,
>        finish_options, common_handle_option): Remove static.
>        (option_enabled, get_option_state): Move to opts-common.c.
>        * opts.h (common_handle_option, target_handle_option,
>        finish_options, default_options_optimization): Declare.
>        * toplev.c: Don't include <signal.h> or <sys/resource.h>.
>        (setup_core_dumping, strip_off_ending, decode_d_option): Move to
>        opts.c.
>        * toplev.h (strip_off_ending, decode_d_option,
>        fast_math_flags_set_p, fast_math_flags_struct_set_p): Don't
>        declare here.
>        * Makefile.in (opts.o, opts-global.o): Update dependencies.
>
> c-family:
> 2010-11-23  Joseph Myers  <joseph@codesourcery.com>
>
>        * c-common.c (visibility_options): Move from ../opts.c.
>        * c-common.h (struct visibility_flags, visibility_options):
>        Declare here.
>        * c-opts.c (finish_options): Rename to c_finish_options.
>        (c_common_init): Update call to finish_options.
>
> Index: gcc/flags.h
> ===================================================================
> --- gcc/flags.h (revision 167073)
> +++ gcc/flags.h (working copy)
> @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3.
>  /* Names of debug_info_type, for error messages.  */
>  extern const char *const debug_type_names[];
>
> +extern void strip_off_ending (char *, int);
>  extern int base_of_path (const char *path, const char **base_out);
>  extern void set_struct_debug_option (struct gcc_options *opts,
>                                     const char *value);
> @@ -40,9 +41,6 @@ extern void set_struct_debug_option (str
>    an actual variable not a macro.  */
>  extern int flag_compare_debug;
>
> -/* Global visibility options.  */
> -extern struct visibility_flags visibility_options;
> -
>  /* True if this is the LTO front end (lto1).  This is used to disable
>    gimple generation and lowering passes that are normally run on the
>    output of a front end.  These passes must be bypassed for lto since
> @@ -50,6 +48,10 @@ extern struct visibility_flags visibilit
>
>  extern bool in_lto_p;
>
> +/* Return true iff flags are set as if -ffast-math.  */
> +extern bool fast_math_flags_set_p (const struct gcc_options *);
> +extern bool fast_math_flags_struct_set_p (struct cl_optimization *);
> +
>  /* Used to set the level of -Wstrict-aliasing in OPTS, when no level
>    is specified.  The external way to set the default level is to use
>    -Wstrict-aliasing=level.
> Index: gcc/opts-common.c
> ===================================================================
> --- gcc/opts-common.c   (revision 167073)
> +++ gcc/opts-common.c   (working copy)
> @@ -994,6 +994,78 @@ option_flag_var (int opt_index, struct g
>   return (void *)(((char *) opts) + option->flag_var_offset);
>  }
>
> +/* Return 1 if option OPT_IDX is enabled in OPTS, 0 if it is disabled,
> +   or -1 if it isn't a simple on-off switch.  */
> +
> +int
> +option_enabled (int opt_idx, void *opts)
> +{
> +  const struct cl_option *option = &(cl_options[opt_idx]);
> +  struct gcc_options *optsg = (struct gcc_options *) opts;
> +  void *flag_var = option_flag_var (opt_idx, optsg);
> +
> +  if (flag_var)
> +    switch (option->var_type)
> +      {
> +      case CLVC_BOOLEAN:
> +       return *(int *) flag_var != 0;
> +
> +      case CLVC_EQUAL:
> +       return *(int *) flag_var == option->var_value;
> +
> +      case CLVC_BIT_CLEAR:
> +       return (*(int *) flag_var & option->var_value) == 0;
> +
> +      case CLVC_BIT_SET:
> +       return (*(int *) flag_var & option->var_value) != 0;
> +
> +      case CLVC_STRING:
> +      case CLVC_DEFER:
> +       break;
> +      }
> +  return -1;
> +}
> +
> +/* Fill STATE with the current state of option OPTION in OPTS.  Return
> +   true if there is some state to store.  */
> +
> +bool
> +get_option_state (struct gcc_options *opts, int option,
> +                 struct cl_option_state *state)
> +{
> +  void *flag_var = option_flag_var (option, opts);
> +
> +  if (flag_var == 0)
> +    return false;
> +
> +  switch (cl_options[option].var_type)
> +    {
> +    case CLVC_BOOLEAN:
> +    case CLVC_EQUAL:
> +      state->data = flag_var;
> +      state->size = sizeof (int);
> +      break;
> +
> +    case CLVC_BIT_CLEAR:
> +    case CLVC_BIT_SET:
> +      state->ch = option_enabled (option, opts);
> +      state->data = &state->ch;
> +      state->size = 1;
> +      break;
> +
> +    case CLVC_STRING:
> +      state->data = *(const char **) flag_var;
> +      if (state->data == 0)
> +       state->data = "";
> +      state->size = strlen ((const char *) state->data) + 1;
> +      break;
> +
> +    case CLVC_DEFER:
> +      return false;
> +    }
> +  return true;
> +}
> +
>  /* Set a warning option OPT_INDEX (language mask LANG_MASK, option
>    handlers HANDLERS) to have diagnostic kind KIND for option
>    structures OPTS and OPTS_SET and diagnostic context DC (possibly
> Index: gcc/c-family/c-opts.c
> ===================================================================
> --- gcc/c-family/c-opts.c       (revision 167073)
> +++ gcc/c-family/c-opts.c       (working copy)
> @@ -116,7 +116,7 @@ static void add_prefixed_path (const cha
>  static void push_command_line_include (void);
>  static void cb_file_change (cpp_reader *, const struct line_map *);
>  static void cb_dir_change (cpp_reader *, const char *);
> -static void finish_options (void);
> +static void c_finish_options (void);
>
>  #ifndef STDC_0_IN_SYSTEM_HEADERS
>  #define STDC_0_IN_SYSTEM_HEADERS 0
> @@ -1047,7 +1047,7 @@ c_common_init (void)
>
>   if (flag_preprocess_only)
>     {
> -      finish_options ();
> +      c_finish_options ();
>       preprocess_file (parse_in);
>       return false;
>     }
> @@ -1065,7 +1065,7 @@ c_common_parse_file (void)
>   i = 0;
>   for (;;)
>     {
> -      finish_options ();
> +      c_finish_options ();
>       pch_init ();
>       push_file_scope ();
>       c_parse_file ();
> @@ -1277,7 +1277,7 @@ add_prefixed_path (const char *suffix, s
>
>  /* Handle -D, -U, -A, -imacros, and the first -include.  */
>  static void
> -finish_options (void)
> +c_finish_options (void)
>  {
>   if (!cpp_opts->preprocessed)
>     {
> Index: gcc/c-family/c-common.c
> ===================================================================
> --- gcc/c-family/c-common.c     (revision 167073)
> +++ gcc/c-family/c-common.c     (working copy)
> @@ -304,6 +304,9 @@ const struct fname_var_t fname_vars[] =
>   {NULL, 0, 0},
>  };
>
> +/* Global visibility options.  */
> +struct visibility_flags visibility_options;
> +
>  static tree c_fully_fold_internal (tree expr, bool, bool *, bool *);
>  static tree check_case_value (tree);
>  static bool check_case_bounds (tree, tree, tree *, tree *);
> Index: gcc/c-family/c-common.h
> ===================================================================
> --- gcc/c-family/c-common.h     (revision 167073)
> +++ gcc/c-family/c-common.h     (working copy)
> @@ -660,6 +660,15 @@ extern bool done_lexing;
>  #define C_TYPE_OBJECT_OR_INCOMPLETE_P(type) \
>   (!C_TYPE_FUNCTION_P (type))
>
> +struct visibility_flags
> +{
> +  unsigned inpragma : 1;       /* True when in #pragma GCC visibility.  */
> +  unsigned inlines_hidden : 1; /* True when -finlineshidden in effect.  */
> +};
> +
> +/* Global visibility options.  */
> +extern struct visibility_flags visibility_options;
> +
>  /* Attribute table common to the C front ends.  */
>  extern const struct attribute_spec c_common_attribute_table[];
>  extern const struct attribute_spec c_common_format_attribute_table[];
> Index: gcc/toplev.c
> ===================================================================
> --- gcc/toplev.c        (revision 167073)
> +++ gcc/toplev.c        (working copy)
> @@ -28,11 +28,6 @@ along with GCC; see the file COPYING3.
>  #include "system.h"
>  #include "coretypes.h"
>  #include "tm.h"
> -#include <signal.h>
> -
> -#ifdef HAVE_SYS_RESOURCE_H
> -# include <sys/resource.h>
> -#endif
>
>  #ifdef HAVE_SYS_TIMES_H
>  # include <sys/times.h>
> @@ -114,7 +109,6 @@ static void init_asm_output (const char
>  static void finalize (void);
>
>  static void crash_signal (int) ATTRIBUTE_NORETURN;
> -static void setup_core_dumping (void);
>  static void compile_file (void);
>
>  /* True if we don't need a backend (e.g. preprocessing only).  */
> @@ -480,48 +474,6 @@ crash_signal (int signo)
>   internal_error ("%s", strsignal (signo));
>  }
>
> -/* Arrange to dump core on error.  (The regular error message is still
> -   printed first, except in the case of abort().)  */
> -
> -static void
> -setup_core_dumping (void)
> -{
> -#ifdef SIGABRT
> -  signal (SIGABRT, SIG_DFL);
> -#endif
> -#if defined(HAVE_SETRLIMIT)
> -  {
> -    struct rlimit rlim;
> -    if (getrlimit (RLIMIT_CORE, &rlim) != 0)
> -      fatal_error ("getting core file size maximum limit: %m");
> -    rlim.rlim_cur = rlim.rlim_max;
> -    if (setrlimit (RLIMIT_CORE, &rlim) != 0)
> -      fatal_error ("setting core file size limit to maximum: %m");
> -  }
> -#endif
> -  diagnostic_abort_on_error (global_dc);
> -}
> -
> -
> -/* Strip off a legitimate source ending from the input string NAME of
> -   length LEN.  Rather than having to know the names used by all of
> -   our front ends, we strip off an ending of a period followed by
> -   up to five characters.  (Java uses ".class".)  */
> -
> -void
> -strip_off_ending (char *name, int len)
> -{
> -  int i;
> -  for (i = 2; i < 6 && len > i; i++)
> -    {
> -      if (name[len - i] == '.')
> -       {
> -         name[len - i] = '\0';
> -         break;
> -       }
> -    }
> -}
> -
>  /* Output a quoted string.  */
>
>  void
> @@ -967,51 +919,6 @@ compile_file (void)
>   targetm.asm_out.file_end ();
>  }
>
> -/* Parse a -d... command line switch.  */
> -
> -void
> -decode_d_option (const char *arg)
> -{
> -  int c;
> -
> -  while (*arg)
> -    switch (c = *arg++)
> -      {
> -      case 'A':
> -       flag_debug_asm = 1;
> -       break;
> -      case 'p':
> -       flag_print_asm_name = 1;
> -       break;
> -      case 'P':
> -       flag_dump_rtl_in_asm = 1;
> -       flag_print_asm_name = 1;
> -       break;
> -      case 'v':
> -       graph_dump_format = vcg;
> -       break;
> -      case 'x':
> -       rtl_dump_and_exit = 1;
> -       break;
> -      case 'D':        /* These are handled by the preprocessor.  */
> -      case 'I':
> -      case 'M':
> -      case 'N':
> -      case 'U':
> -       break;
> -      case 'H':
> -       setup_core_dumping();
> -       break;
> -      case 'a':
> -       enable_rtl_dump_file ();
> -       break;
> -
> -      default:
> -         warning (0, "unrecognized gcc debugging option: %c", c);
> -       break;
> -      }
> -}
> -
>  /* Indexed by enum debug_info_type.  */
>  const char *const debug_type_names[] =
>  {
> Index: gcc/toplev.h
> ===================================================================
> --- gcc/toplev.h        (revision 167073)
> +++ gcc/toplev.h        (working copy)
> @@ -34,7 +34,6 @@ extern struct cl_decoded_option *save_de
>  extern unsigned int save_decoded_options_count;
>
>  extern int toplev_main (int, char **);
> -extern void strip_off_ending (char *, int);
>  extern void rest_of_decl_compilation (tree, int, int);
>  extern void rest_of_type_compilation (tree, int);
>  extern void tree_rest_of_compilation (tree);
> @@ -92,13 +91,6 @@ extern const char * default_pch_valid_p
>  /* The hashtable, so that the C front ends can pass it to cpplib.  */
>  extern struct ht *ident_hash;
>
> -/* Handle -d switch.  */
> -extern void decode_d_option            (const char *);
> -
> -/* Return true iff flags are set as if -ffast-math.  */
> -extern bool fast_math_flags_set_p      (const struct gcc_options *);
> -extern bool fast_math_flags_struct_set_p (struct cl_optimization *);
> -
>  /* Inline versions of the above for speed.  */
>  #if GCC_VERSION < 3004
>
> Index: gcc/opts.c
> ===================================================================
> --- gcc/opts.c  (revision 167073)
> +++ gcc/opts.c  (working copy)
> @@ -21,25 +21,30 @@ along with GCC; see the file COPYING3.
>
>  #include "config.h"
>  #include "system.h"
> +
> +#include <signal.h>
> +
> +#ifdef HAVE_SYS_RESOURCE_H
> +# include <sys/resource.h>
> +#endif
> +
>  #include "intl.h"
>  #include "coretypes.h"
> -#include "tm.h"
> -#include "tree.h"
> -#include "expr.h"
> -#include "langhooks.h"
> +#include "tm.h" /* Needed by rtl.h and used for DWARF2_DEBUGGING_INFO
> +                  and DBX_DEBUGGING_INFO.  */
> +#include "tree.h" /* For vect_set_verbosity_level.  */
> +#include "rtl.h" /* Needed by insn-attr.h.  */
>  #include "opts.h"
>  #include "options.h"
>  #include "flags.h"
> -#include "toplev.h"
> +#include "toplev.h" /* For set_random_seed and enable_rtl_dump_file.  */
>  #include "params.h"
>  #include "diagnostic.h"
>  #include "opts-diagnostic.h"
> -#include "insn-attr.h"         /* For INSN_SCHEDULING.  */
> +#include "insn-attr.h"         /* For INSN_SCHEDULING and DELAY_SLOTS.  */
>  #include "target.h"
>  #include "dbgcnt.h"
>  #include "debug.h"
> -#include "except.h"
> -#include "lto-streamer.h"
>
>  /* Run the second compilation of -fcompare-debug.  Not defined using
>    Var in common.opt because this is used in Ada code and so must be
> @@ -136,6 +141,25 @@ set_struct_debug_option (struct gcc_opti
>     }
>  }
>
> +/* Strip off a legitimate source ending from the input string NAME of
> +   length LEN.  Rather than having to know the names used by all of
> +   our front ends, we strip off an ending of a period followed by
> +   up to five characters.  (Java uses ".class".)  */
> +
> +void
> +strip_off_ending (char *name, int len)
> +{
> +  int i;
> +  for (i = 2; i < 6 && len > i; i++)
> +    {
> +      if (name[len - i] == '.')
> +       {
> +         name[len - i] = '\0';
> +         break;
> +       }
> +    }
> +}
> +
>  /* Find the base name of a path, stripping off both directories and
>    a single final extension. */
>  int
> @@ -162,9 +186,6 @@ base_of_path (const char *path, const ch
>   return dot - base;
>  }
>
> -/* Global visibility options.  */
> -struct visibility_flags visibility_options;
> -
>  /* What to print when a switch has no documentation.  */
>  static const char undocumented_msg[] = N_("This switch lacks documentation");
>
> @@ -172,32 +193,13 @@ typedef char *char_p; /* For DEF_VEC_P.
>  DEF_VEC_P(char_p);
>  DEF_VEC_ALLOC_P(char_p,heap);
>
> -typedef const char *const_char_p; /* For DEF_VEC_P.  */
> -DEF_VEC_P(const_char_p);
> -DEF_VEC_ALLOC_P(const_char_p,heap);
> -
> -static VEC(const_char_p,heap) *ignored_options;
> -
> -/* Input file names.  */
> -const char **in_fnames;
> -unsigned num_in_fnames;
> -
> -static bool common_handle_option (struct gcc_options *opts,
> -                                 struct gcc_options *opts_set,
> -                                 const struct cl_decoded_option *decoded,
> -                                 unsigned int lang_mask, int kind,
> -                                 location_t loc,
> -                                 const struct cl_option_handlers *handlers,
> -                                 diagnostic_context *dc);
>  static void handle_param (struct gcc_options *opts,
>                          struct gcc_options *opts_set, const char *carg);
> -static char *write_langs (unsigned int lang_mask);
> -static void complain_wrong_lang (const struct cl_decoded_option *,
> -                                unsigned int lang_mask);
>  static void set_debug_level (enum debug_info_type type, int extended,
>                             const char *arg, struct gcc_options *opts,
>                             struct gcc_options *opts_set);
>  static void set_fast_math_flags (struct gcc_options *opts, int set);
> +static void decode_d_option (const char *arg);
>  static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
>                                                 int set);
>  static void enable_warning_as_error (const char *arg, int value,
> @@ -208,155 +210,10 @@ static void enable_warning_as_error (con
>                                     location_t loc,
>                                     diagnostic_context *dc);
>
> -/* Return a malloced slash-separated list of languages in MASK.  */
> -static char *
> -write_langs (unsigned int mask)
> -{
> -  unsigned int n = 0, len = 0;
> -  const char *lang_name;
> -  char *result;
> -
> -  for (n = 0; (lang_name = lang_names[n]) != 0; n++)
> -    if (mask & (1U << n))
> -      len += strlen (lang_name) + 1;
> -
> -  result = XNEWVEC (char, len);
> -  len = 0;
> -  for (n = 0; (lang_name = lang_names[n]) != 0; n++)
> -    if (mask & (1U << n))
> -      {
> -       if (len)
> -         result[len++] = '/';
> -       strcpy (result + len, lang_name);
> -       len += strlen (lang_name);
> -      }
> -
> -  result[len] = 0;
> -
> -  return result;
> -}
> -
> -/* Complain that switch DECODED does not apply to this front end (mask
> -   LANG_MASK).  */
> -static void
> -complain_wrong_lang (const struct cl_decoded_option *decoded,
> -                    unsigned int lang_mask)
> -{
> -  const struct cl_option *option = &cl_options[decoded->opt_index];
> -  const char *text = decoded->orig_option_with_args_text;
> -  char *ok_langs = NULL, *bad_lang = NULL;
> -  unsigned int opt_flags = option->flags;
> -
> -  if (!lang_hooks.complain_wrong_lang_p (option))
> -    return;
> -
> -  opt_flags &= ((1U << cl_lang_count) - 1) | CL_DRIVER;
> -  if (opt_flags != CL_DRIVER)
> -    ok_langs = write_langs (opt_flags);
> -  if (lang_mask != CL_DRIVER)
> -    bad_lang = write_langs (lang_mask);
> -
> -  if (opt_flags == CL_DRIVER)
> -    error ("command line option %qs is valid for the driver but not for %s",
> -          text, bad_lang);
> -  else if (lang_mask == CL_DRIVER)
> -    gcc_unreachable ();
> -  else
> -    /* Eventually this should become a hard error IMO.  */
> -    warning (0, "command line option %qs is valid for %s but not for %s",
> -            text, ok_langs, bad_lang);
> -
> -  free (ok_langs);
> -  free (bad_lang);
> -}
> -
> -/* Buffer the unknown option described by the string OPT.  Currently,
> -   we only complain about unknown -Wno-* options if they may have
> -   prevented a diagnostic. Otherwise, we just ignore them.
> -   Note that if we do complain, it is only as a warning, not an error;
> -   passing the compiler an unrecognised -Wno-* option should never
> -   change whether the compilation succeeds or fails.  */
> -
> -static void postpone_unknown_option_warning(const char *opt)
> -{
> -  VEC_safe_push (const_char_p, heap, ignored_options, opt);
> -}
> -
> -/* Produce a warning for each option previously buffered.  */
> -
> -void print_ignored_options (void)
> -{
> -  location_t saved_loc = input_location;
> -
> -  input_location = 0;
> -
> -  while (!VEC_empty (const_char_p, ignored_options))
> -    {
> -      const char *opt;
> -      opt = VEC_pop (const_char_p, ignored_options);
> -      warning (0, "unrecognized command line option \"%s\"", opt);
> -    }
> -
> -  input_location = saved_loc;
> -}
> -
> -/* Handle an unknown option DECODED, returning true if an error should be
> -   given.  */
> -
> -static bool
> -unknown_option_callback (const struct cl_decoded_option *decoded)
> -{
> -  const char *opt = decoded->arg;
> -
> -  if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-'
> -      && !(decoded->errors & CL_ERR_NEGATIVE))
> -    {
> -      /* We don't generate warnings for unknown -Wno-* options unless
> -        we issue diagnostics.  */
> -      postpone_unknown_option_warning (opt);
> -      return false;
> -    }
> -  else
> -    return true;
> -}
> -
> -/* Note that an option DECODED has been successfully handled with a
> -   handler for mask MASK.  */
> -
> -static void
> -post_handling_callback (const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED,
> -                       unsigned int mask ATTRIBUTE_UNUSED)
> -{
> -#ifdef ENABLE_LTO
> -  lto_register_user_option (decoded->opt_index, decoded->arg,
> -                           decoded->value, mask);
> -#endif
> -}
> -
> -/* Handle a front-end option; arguments and return value as for
> -   handle_option.  */
> -
> -static bool
> -lang_handle_option (struct gcc_options *opts,
> -                   struct gcc_options *opts_set,
> -                   const struct cl_decoded_option *decoded,
> -                   unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
> -                   location_t loc,
> -                   const struct cl_option_handlers *handlers,
> -                   diagnostic_context *dc)
> -{
> -  gcc_assert (opts == &global_options);
> -  gcc_assert (opts_set == &global_options_set);
> -  gcc_assert (dc == global_dc);
> -  gcc_assert (decoded->canonical_option_num_elements <= 2);
> -  return lang_hooks.handle_option (decoded->opt_index, decoded->arg,
> -                                  decoded->value, kind, loc, handlers);
> -}
> -
>  /* Handle a back-end option; arguments and return value as for
>    handle_option.  */
>
> -static bool
> +bool
>  target_handle_option (struct gcc_options *opts,
>                      struct gcc_options *opts_set,
>                      const struct cl_decoded_option *decoded,
> @@ -378,15 +235,6 @@ target_handle_option (struct gcc_options
>                                decoded->value);
>  }
>
> -/* Handle FILENAME from the command line.  */
> -static void
> -add_input_filename (const char *filename)
> -{
> -  num_in_fnames++;
> -  in_fnames = XRESIZEVEC (const char *, in_fnames, num_in_fnames);
> -  in_fnames[num_in_fnames - 1] = filename;
> -}
> -
>  /* Add comma-separated strings to a char_p vector.  */
>
>  static void
> @@ -428,61 +276,6 @@ add_comma_separated_to_vector (void **pv
>   *pvec = vec;
>  }
>
> -/* Handle the vector of command line options (located at LOC), storing
> -   the results of processing DECODED_OPTIONS and DECODED_OPTIONS_COUNT
> -   in OPTS and OPTS_SET and using DC for diagnostic state.  LANG_MASK
> -   contains has a single bit set representing the current language.
> -   HANDLERS describes what functions to call for the options.  */
> -static void
> -read_cmdline_options (struct gcc_options *opts, struct gcc_options *opts_set,
> -                     struct cl_decoded_option *decoded_options,
> -                     unsigned int decoded_options_count,
> -                     location_t loc,
> -                     unsigned int lang_mask,
> -                     const struct cl_option_handlers *handlers,
> -                     diagnostic_context *dc)
> -{
> -  unsigned int i;
> -
> -  for (i = 1; i < decoded_options_count; i++)
> -    {
> -      if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
> -       {
> -         /* Input files should only ever appear on the main command
> -            line.  */
> -         gcc_assert (opts == &global_options);
> -         gcc_assert (opts_set == &global_options_set);
> -
> -         if (main_input_filename == NULL)
> -           {
> -             main_input_filename = decoded_options[i].arg;
> -             main_input_baselength
> -               = base_of_path (main_input_filename, &main_input_basename);
> -           }
> -         add_input_filename (decoded_options[i].arg);
> -         continue;
> -       }
> -
> -      read_cmdline_option (opts, opts_set,
> -                          decoded_options + i, loc, lang_mask, handlers,
> -                          dc);
> -    }
> -}
> -
> -/* Language mask determined at initialization.  */
> -static unsigned int initial_lang_mask;
> -
> -/* Initialize global options-related settings at start-up.  */
> -
> -void
> -init_options_once (void)
> -{
> -  /* Perform language-specific options initialization.  */
> -  initial_lang_mask = lang_hooks.option_lang_mask ();
> -
> -  lang_hooks.initialize_diagnostics (global_dc);
> -}
> -
>  /* Initialize OPTS and OPTS_SET before using them in parsing options.  */
>
>  void
> @@ -519,21 +312,6 @@ init_options_struct (struct gcc_options
>   targetm.target_option.init_struct (opts);
>  }
>
> -/* Decode command-line options to an array, like
> -   decode_cmdline_options_to_array and with the same arguments but
> -   using the default lang_mask.  */
> -
> -void
> -decode_cmdline_options_to_array_default_mask (unsigned int argc,
> -                                             const char **argv,
> -                                             struct cl_decoded_option **decoded_options,
> -                                             unsigned int *decoded_options_count)
> -{
> -  decode_cmdline_options_to_array (argc, argv,
> -                                  initial_lang_mask | CL_COMMON | CL_TARGET,
> -                                  decoded_options, decoded_options_count);
> -}
> -
>  /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
>    -Ofast if FAST is set), apply the option DEFAULT_OPT to OPTS and
>    OPTS_SET, diagnostic context DC, location LOC, with language mask
> @@ -725,7 +503,7 @@ static const struct default_options defa
>
>  /* Default the options in OPTS and OPTS_SET based on the optimization
>    settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT.  */
> -static void
> +void
>  default_options_optimization (struct gcc_options *opts,
>                              struct gcc_options *opts_set,
>                              struct cl_decoded_option *decoded_options,
> @@ -826,69 +604,10 @@ default_options_optimization (struct gcc
>                         ofast, lang_mask, handlers, loc, dc);
>  }
>
> -static void finish_options (struct gcc_options *, struct gcc_options *);
> -
> -/* Set *HANDLERS to the default set of option handlers for use in the
> -   compilers proper (not the driver).  */
> -void
> -set_default_handlers (struct cl_option_handlers *handlers)
> -{
> -  handlers->unknown_option_callback = unknown_option_callback;
> -  handlers->wrong_lang_callback = complain_wrong_lang;
> -  handlers->post_handling_callback = post_handling_callback;
> -  handlers->num_handlers = 3;
> -  handlers->handlers[0].handler = lang_handle_option;
> -  handlers->handlers[0].mask = initial_lang_mask;
> -  handlers->handlers[1].handler = common_handle_option;
> -  handlers->handlers[1].mask = CL_COMMON;
> -  handlers->handlers[2].handler = target_handle_option;
> -  handlers->handlers[2].mask = CL_TARGET;
> -}
> -
> -/* Parse command line options and set default flag values.  Do minimal
> -   options processing.  The decoded options are in *DECODED_OPTIONS
> -   and *DECODED_OPTIONS_COUNT; settings go in OPTS, OPTS_SET and DC;
> -   the options are located at LOC.  */
> -void
> -decode_options (struct gcc_options *opts, struct gcc_options *opts_set,
> -               struct cl_decoded_option *decoded_options,
> -               unsigned int decoded_options_count,
> -               location_t loc, diagnostic_context *dc)
> -{
> -  struct cl_option_handlers handlers;
> -
> -  unsigned int lang_mask;
> -
> -  lang_mask = initial_lang_mask;
> -
> -  set_default_handlers (&handlers);
> -
> -  /* Enable -Werror=coverage-mismatch by default.  */
> -  control_warning_option (OPT_Wcoverage_mismatch, (int) DK_ERROR, true,
> -                         loc, lang_mask,
> -                         &handlers, opts, opts_set, dc);
> -
> -  default_options_optimization (opts, opts_set,
> -                               decoded_options, decoded_options_count,
> -                               loc, lang_mask, &handlers, dc);
> -
> -#ifdef ENABLE_LTO
> -  /* Clear any options currently held for LTO.  */
> -  lto_clear_user_options ();
> -#endif
> -
> -  read_cmdline_options (opts, opts_set,
> -                       decoded_options, decoded_options_count,
> -                       loc, lang_mask,
> -                       &handlers, dc);
> -
> -  finish_options (opts, opts_set);
> -}
> -
>  /* After all options have been read into OPTS and OPTS_SET, finalize
>    settings of those options and diagnose incompatible
>    combinations.  */
> -static void
> +void
>  finish_options (struct gcc_options *opts, struct gcc_options *opts_set)
>  {
>   static bool first_time_p = true;
> @@ -1419,7 +1138,7 @@ print_specific_help (unsigned int includ
>    extra handling need to be listed here; if you simply want
>    DECODED->value assigned to a variable, it happens automatically.  */
>
> -static bool
> +bool
>  common_handle_option (struct gcc_options *opts,
>                      struct gcc_options *opts_set,
>                      const struct cl_decoded_option *decoded,
> @@ -2145,76 +1864,71 @@ set_debug_level (enum debug_info_type ty
>     }
>  }
>
> -/* Return 1 if option OPT_IDX is enabled in OPTS, 0 if it is disabled,
> -   or -1 if it isn't a simple on-off switch.  */
> +/* Arrange to dump core on error.  (The regular error message is still
> +   printed first, except in the case of abort ().)  */
>
> -int
> -option_enabled (int opt_idx, void *opts)
> +static void
> +setup_core_dumping (void)
>  {
> -  const struct cl_option *option = &(cl_options[opt_idx]);
> -  struct gcc_options *optsg = (struct gcc_options *) opts;
> -  void *flag_var = option_flag_var (opt_idx, optsg);
> -
> -  if (flag_var)
> -    switch (option->var_type)
> -      {
> -      case CLVC_BOOLEAN:
> -       return *(int *) flag_var != 0;
> -
> -      case CLVC_EQUAL:
> -       return *(int *) flag_var == option->var_value;
> -
> -      case CLVC_BIT_CLEAR:
> -       return (*(int *) flag_var & option->var_value) == 0;
> -
> -      case CLVC_BIT_SET:
> -       return (*(int *) flag_var & option->var_value) != 0;
> -
> -      case CLVC_STRING:
> -      case CLVC_DEFER:
> -       break;
> -      }
> -  return -1;
> +#ifdef SIGABRT
> +  signal (SIGABRT, SIG_DFL);
> +#endif
> +#if defined(HAVE_SETRLIMIT)
> +  {
> +    struct rlimit rlim;
> +    if (getrlimit (RLIMIT_CORE, &rlim) != 0)
> +      fatal_error ("getting core file size maximum limit: %m");
> +    rlim.rlim_cur = rlim.rlim_max;
> +    if (setrlimit (RLIMIT_CORE, &rlim) != 0)
> +      fatal_error ("setting core file size limit to maximum: %m");
> +  }
> +#endif
> +  diagnostic_abort_on_error (global_dc);
>  }
>
> -/* Fill STATE with the current state of option OPTION in OPTS.  Return
> -   true if there is some state to store.  */
> +/* Parse a -d<ARG> command line switch.  */
>
> -bool
> -get_option_state (struct gcc_options *opts, int option,
> -                 struct cl_option_state *state)
> +static void
> +decode_d_option (const char *arg)
>  {
> -  void *flag_var = option_flag_var (option, opts);
> +  int c;
>
> -  if (flag_var == 0)
> -    return false;
> -
> -  switch (cl_options[option].var_type)
> -    {
> -    case CLVC_BOOLEAN:
> -    case CLVC_EQUAL:
> -      state->data = flag_var;
> -      state->size = sizeof (int);
> -      break;
> -
> -    case CLVC_BIT_CLEAR:
> -    case CLVC_BIT_SET:
> -      state->ch = option_enabled (option, opts);
> -      state->data = &state->ch;
> -      state->size = 1;
> -      break;
> -
> -    case CLVC_STRING:
> -      state->data = *(const char **) flag_var;
> -      if (state->data == 0)
> -       state->data = "";
> -      state->size = strlen ((const char *) state->data) + 1;
> -      break;
> +  while (*arg)
> +    switch (c = *arg++)
> +      {
> +      case 'A':
> +       flag_debug_asm = 1;
> +       break;
> +      case 'p':
> +       flag_print_asm_name = 1;
> +       break;
> +      case 'P':
> +       flag_dump_rtl_in_asm = 1;
> +       flag_print_asm_name = 1;
> +       break;
> +      case 'v':
> +       graph_dump_format = vcg;
> +       break;
> +      case 'x':
> +       rtl_dump_and_exit = 1;
> +       break;
> +      case 'D':        /* These are handled by the preprocessor.  */
> +      case 'I':
> +      case 'M':
> +      case 'N':
> +      case 'U':
> +       break;
> +      case 'H':
> +       setup_core_dumping ();
> +       break;
> +      case 'a':
> +       enable_rtl_dump_file ();
> +       break;
>
> -    case CLVC_DEFER:
> -      return false;
> -    }
> -  return true;
> +      default:
> +         warning (0, "unrecognized gcc debugging option: %c", c);
> +       break;
> +      }
>  }
>
>  /* Enable (or disable if VALUE is 0) a warning option ARG (language
> Index: gcc/opts.h
> ===================================================================
> --- gcc/opts.h  (revision 167073)
> +++ gcc/opts.h  (working copy)
> @@ -284,4 +284,28 @@ extern void control_warning_option (unsi
>                                    diagnostic_context *dc);
>  extern void print_ignored_options (void);
>  extern void handle_common_deferred_options (void);
> +extern bool common_handle_option (struct gcc_options *opts,
> +                                 struct gcc_options *opts_set,
> +                                 const struct cl_decoded_option *decoded,
> +                                 unsigned int lang_mask, int kind,
> +                                 location_t loc,
> +                                 const struct cl_option_handlers *handlers,
> +                                 diagnostic_context *dc);
> +extern bool target_handle_option (struct gcc_options *opts,
> +                                 struct gcc_options *opts_set,
> +                                 const struct cl_decoded_option *decoded,
> +                                 unsigned int lang_mask, int kind,
> +                                 location_t loc,
> +                                 const struct cl_option_handlers *handlers,
> +                                 diagnostic_context *dc);
> +extern void finish_options (struct gcc_options *opts,
> +                           struct gcc_options *opts_set);
> +extern void default_options_optimization (struct gcc_options *opts,
> +                                         struct gcc_options *opts_set,
> +                                         struct cl_decoded_option *decoded_options,
> +                                         unsigned int decoded_options_count,
> +                                         location_t loc,
> +                                         unsigned int lang_mask,
> +                                         const struct cl_option_handlers *handlers,
> +                                         diagnostic_context *dc);
>  #endif
> Index: gcc/flag-types.h
> ===================================================================
> --- gcc/flag-types.h    (revision 167073)
> +++ gcc/flag-types.h    (working copy)
> @@ -106,12 +106,6 @@ enum symbol_visibility
>  };
>  #endif
>
> -struct visibility_flags
> -{
> -  unsigned inpragma : 1;       /* True when in #pragma GCC visibility.  */
> -  unsigned inlines_hidden : 1; /* True when -finlineshidden in effect.  */
> -};
> -
>  /* The algorithm used for the integrated register allocator (IRA).  */
>  enum ira_algorithm
>  {
> Index: gcc/opts-global.c
> ===================================================================
> --- gcc/opts-global.c   (revision 167073)
> +++ gcc/opts-global.c   (working copy)
> @@ -22,16 +22,316 @@ along with GCC; see the file COPYING3.
>  #include "config.h"
>  #include "system.h"
>  #include "coretypes.h"
> -#include "diagnostic-core.h"
> +#include "diagnostic.h"
>  #include "opts.h"
>  #include "flags.h"
>  #include "ggc.h"
> +#include "tree.h" /* Required by langhooks.h.  */
> +#include "langhooks.h"
>  #include "tm.h" /* Required by rtl.h.  */
>  #include "rtl.h"
> +#include "lto-streamer.h"
>  #include "output.h"
>  #include "plugin.h"
> +#include "toplev.h"
>  #include "tree-pass.h"
>
> +typedef const char *const_char_p; /* For DEF_VEC_P.  */
> +DEF_VEC_P(const_char_p);
> +DEF_VEC_ALLOC_P(const_char_p,heap);
> +
> +static VEC(const_char_p,heap) *ignored_options;
> +
> +/* Input file names.  */
> +const char **in_fnames;
> +unsigned num_in_fnames;
> +
> +/* Return a malloced slash-separated list of languages in MASK.  */
> +
> +static char *
> +write_langs (unsigned int mask)
> +{
> +  unsigned int n = 0, len = 0;
> +  const char *lang_name;
> +  char *result;
> +
> +  for (n = 0; (lang_name = lang_names[n]) != 0; n++)
> +    if (mask & (1U << n))
> +      len += strlen (lang_name) + 1;
> +
> +  result = XNEWVEC (char, len);
> +  len = 0;
> +  for (n = 0; (lang_name = lang_names[n]) != 0; n++)
> +    if (mask & (1U << n))
> +      {
> +       if (len)
> +         result[len++] = '/';
> +       strcpy (result + len, lang_name);
> +       len += strlen (lang_name);
> +      }
> +
> +  result[len] = 0;
> +
> +  return result;
> +}
> +
> +/* Complain that switch DECODED does not apply to this front end (mask
> +   LANG_MASK).  */
> +
> +static void
> +complain_wrong_lang (const struct cl_decoded_option *decoded,
> +                    unsigned int lang_mask)
> +{
> +  const struct cl_option *option = &cl_options[decoded->opt_index];
> +  const char *text = decoded->orig_option_with_args_text;
> +  char *ok_langs = NULL, *bad_lang = NULL;
> +  unsigned int opt_flags = option->flags;
> +
> +  if (!lang_hooks.complain_wrong_lang_p (option))
> +    return;
> +
> +  opt_flags &= ((1U << cl_lang_count) - 1) | CL_DRIVER;
> +  if (opt_flags != CL_DRIVER)
> +    ok_langs = write_langs (opt_flags);
> +  if (lang_mask != CL_DRIVER)
> +    bad_lang = write_langs (lang_mask);
> +
> +  if (opt_flags == CL_DRIVER)
> +    error ("command line option %qs is valid for the driver but not for %s",
> +          text, bad_lang);
> +  else if (lang_mask == CL_DRIVER)
> +    gcc_unreachable ();
> +  else
> +    /* Eventually this should become a hard error IMO.  */
> +    warning (0, "command line option %qs is valid for %s but not for %s",
> +            text, ok_langs, bad_lang);
> +
> +  free (ok_langs);
> +  free (bad_lang);
> +}
> +
> +/* Buffer the unknown option described by the string OPT.  Currently,
> +   we only complain about unknown -Wno-* options if they may have
> +   prevented a diagnostic. Otherwise, we just ignore them.  Note that
> +   if we do complain, it is only as a warning, not an error; passing
> +   the compiler an unrecognised -Wno-* option should never change
> +   whether the compilation succeeds or fails.  */
> +
> +static void
> +postpone_unknown_option_warning (const char *opt)
> +{
> +  VEC_safe_push (const_char_p, heap, ignored_options, opt);
> +}
> +
> +/* Produce a warning for each option previously buffered.  */
> +
> +void
> +print_ignored_options (void)
> +{
> +  while (!VEC_empty (const_char_p, ignored_options))
> +    {
> +      const char *opt;
> +
> +      opt = VEC_pop (const_char_p, ignored_options);
> +      warning_at (UNKNOWN_LOCATION, 0,
> +                 "unrecognized command line option \"%s\"", opt);
> +    }
> +}
> +
> +/* Handle an unknown option DECODED, returning true if an error should
> +   be given.  */
> +
> +static bool
> +unknown_option_callback (const struct cl_decoded_option *decoded)
> +{
> +  const char *opt = decoded->arg;
> +
> +  if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-'
> +      && !(decoded->errors & CL_ERR_NEGATIVE))
> +    {
> +      /* We don't generate warnings for unknown -Wno-* options unless
> +        we issue diagnostics.  */
> +      postpone_unknown_option_warning (opt);
> +      return false;
> +    }
> +  else
> +    return true;
> +}
> +
> +/* Note that an option DECODED has been successfully handled with a
> +   handler for mask MASK.  */
> +
> +static void
> +post_handling_callback (const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED,
> +                       unsigned int mask ATTRIBUTE_UNUSED)
> +{
> +#ifdef ENABLE_LTO
> +  lto_register_user_option (decoded->opt_index, decoded->arg,
> +                           decoded->value, mask);
> +#endif
> +}
> +
> +/* Handle a front-end option; arguments and return value as for
> +   handle_option.  */
> +
> +static bool
> +lang_handle_option (struct gcc_options *opts,
> +                   struct gcc_options *opts_set,
> +                   const struct cl_decoded_option *decoded,
> +                   unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
> +                   location_t loc,
> +                   const struct cl_option_handlers *handlers,
> +                   diagnostic_context *dc)
> +{
> +  gcc_assert (opts == &global_options);
> +  gcc_assert (opts_set == &global_options_set);
> +  gcc_assert (dc == global_dc);
> +  gcc_assert (decoded->canonical_option_num_elements <= 2);
> +  return lang_hooks.handle_option (decoded->opt_index, decoded->arg,
> +                                  decoded->value, kind, loc, handlers);
> +}
> +
> +/* Handle FILENAME from the command line.  */
> +
> +static void
> +add_input_filename (const char *filename)
> +{
> +  num_in_fnames++;
> +  in_fnames = XRESIZEVEC (const char *, in_fnames, num_in_fnames);
> +  in_fnames[num_in_fnames - 1] = filename;
> +}
> +
> +/* Handle the vector of command line options (located at LOC), storing
> +   the results of processing DECODED_OPTIONS and DECODED_OPTIONS_COUNT
> +   in OPTS and OPTS_SET and using DC for diagnostic state.  LANG_MASK
> +   contains has a single bit set representing the current language.
> +   HANDLERS describes what functions to call for the options.  */
> +
> +static void
> +read_cmdline_options (struct gcc_options *opts, struct gcc_options *opts_set,
> +                     struct cl_decoded_option *decoded_options,
> +                     unsigned int decoded_options_count,
> +                     location_t loc,
> +                     unsigned int lang_mask,
> +                     const struct cl_option_handlers *handlers,
> +                     diagnostic_context *dc)
> +{
> +  unsigned int i;
> +
> +  for (i = 1; i < decoded_options_count; i++)
> +    {
> +      if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
> +       {
> +         /* Input files should only ever appear on the main command
> +            line.  */
> +         gcc_assert (opts == &global_options);
> +         gcc_assert (opts_set == &global_options_set);
> +
> +         if (main_input_filename == NULL)
> +           {
> +             main_input_filename = decoded_options[i].arg;
> +             main_input_baselength
> +               = base_of_path (main_input_filename, &main_input_basename);
> +           }
> +         add_input_filename (decoded_options[i].arg);
> +         continue;
> +       }
> +
> +      read_cmdline_option (opts, opts_set,
> +                          decoded_options + i, loc, lang_mask, handlers,
> +                          dc);
> +    }
> +}
> +
> +/* Language mask determined at initialization.  */
> +static unsigned int initial_lang_mask;
> +
> +/* Initialize global options-related settings at start-up.  */
> +
> +void
> +init_options_once (void)
> +{
> +  /* Perform language-specific options initialization.  */
> +  initial_lang_mask = lang_hooks.option_lang_mask ();
> +
> +  lang_hooks.initialize_diagnostics (global_dc);
> +}
> +
> +/* Decode command-line options to an array, like
> +   decode_cmdline_options_to_array and with the same arguments but
> +   using the default lang_mask.  */
> +
> +void
> +decode_cmdline_options_to_array_default_mask (unsigned int argc,
> +                                             const char **argv,
> +                                             struct cl_decoded_option **decoded_options,
> +                                             unsigned int *decoded_options_count)
> +{
> +  decode_cmdline_options_to_array (argc, argv,
> +                                  initial_lang_mask | CL_COMMON | CL_TARGET,
> +                                  decoded_options, decoded_options_count);
> +}
> +
> +/* Set *HANDLERS to the default set of option handlers for use in the
> +   compilers proper (not the driver).  */
> +void
> +set_default_handlers (struct cl_option_handlers *handlers)
> +{
> +  handlers->unknown_option_callback = unknown_option_callback;
> +  handlers->wrong_lang_callback = complain_wrong_lang;
> +  handlers->post_handling_callback = post_handling_callback;
> +  handlers->num_handlers = 3;
> +  handlers->handlers[0].handler = lang_handle_option;
> +  handlers->handlers[0].mask = initial_lang_mask;
> +  handlers->handlers[1].handler = common_handle_option;
> +  handlers->handlers[1].mask = CL_COMMON;
> +  handlers->handlers[2].handler = target_handle_option;
> +  handlers->handlers[2].mask = CL_TARGET;
> +}
> +
> +/* Parse command line options and set default flag values.  Do minimal
> +   options processing.  The decoded options are in *DECODED_OPTIONS
> +   and *DECODED_OPTIONS_COUNT; settings go in OPTS, OPTS_SET and DC;
> +   the options are located at LOC.  */
> +void
> +decode_options (struct gcc_options *opts, struct gcc_options *opts_set,
> +               struct cl_decoded_option *decoded_options,
> +               unsigned int decoded_options_count,
> +               location_t loc, diagnostic_context *dc)
> +{
> +  struct cl_option_handlers handlers;
> +
> +  unsigned int lang_mask;
> +
> +  lang_mask = initial_lang_mask;
> +
> +  set_default_handlers (&handlers);
> +
> +  /* Enable -Werror=coverage-mismatch by default.  */
> +  control_warning_option (OPT_Wcoverage_mismatch, (int) DK_ERROR, true,
> +                         loc, lang_mask,
> +                         &handlers, opts, opts_set, dc);
> +
> +  default_options_optimization (opts, opts_set,
> +                               decoded_options, decoded_options_count,
> +                               loc, lang_mask, &handlers, dc);
> +
> +#ifdef ENABLE_LTO
> +  /* Clear any options currently held for LTO.  */
> +  lto_clear_user_options ();
> +#endif
> +
> +  read_cmdline_options (opts, opts_set,
> +                       decoded_options, decoded_options_count,
> +                       loc, lang_mask,
> +                       &handlers, dc);
> +
> +  finish_options (opts, opts_set);
> +}
> +
> +/* Process common options that have been deferred until after the
> +   handlers have been called for all options.  */
> +
>  void
>  handle_common_deferred_options (void)
>  {
> Index: gcc/Makefile.in
> ===================================================================
> --- gcc/Makefile.in     (revision 167073)
> +++ gcc/Makefile.in     (working copy)
> @@ -2824,13 +2824,14 @@ fold-const.o : fold-const.c $(CONFIG_H)
>  diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
>    version.h $(INPUT_H) intl.h $(DIAGNOSTIC_H) diagnostic.def
>  opts.o : opts.c $(OPTS_H) $(OPTIONS_H) $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) $(CONFIG_H) $(SYSTEM_H) \
> -   coretypes.h $(TREE_H) $(TM_H) langhooks.h $(EXPR_H) \
> -   $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \
> +   coretypes.h $(TREE_H) $(TM_H) $(RTL_H) \
> +   $(DIAGNOSTIC_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \
>    $(FLAGS_H) $(PARAMS_H) $(DBGCNT_H) debug.h \
> -   $(EXCEPT_H) $(LTO_STREAMER_H) opts-diagnostic.h
> +   opts-diagnostic.h
>  opts-global.o : opts-global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
> -   $(DIAGNOSTIC_CORE_H) $(OPTS_H) $(FLAGS_H) $(GGC_H) $(TM_H) $(RTL_H) \
> -   output.h $(PLUGIN_H) $(TREE_PASS_H)
> +   $(DIAGNOSTIC_H) $(OPTS_H) $(FLAGS_H) $(GGC_H) $(TREE_H) langhooks.h \
> +   $(TM_H) $(RTL_H) $(LTO_STREAMER_H) output.h $(PLUGIN_H) $(TOPLEV_H) \
> +   $(TREE_PASS_H)
>  opts-common.o : opts-common.c $(OPTS_H) $(FLAGS_H) $(CONFIG_H) $(SYSTEM_H) \
>    coretypes.h intl.h $(DIAGNOSTIC_H) $(TM_H)
>  targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
>
diff mbox

Patch

Index: gcc/flags.h
===================================================================
--- gcc/flags.h	(revision 167073)
+++ gcc/flags.h	(working copy)
@@ -31,6 +31,7 @@  along with GCC; see the file COPYING3.  
 /* Names of debug_info_type, for error messages.  */
 extern const char *const debug_type_names[];
 
+extern void strip_off_ending (char *, int);
 extern int base_of_path (const char *path, const char **base_out);
 extern void set_struct_debug_option (struct gcc_options *opts,
 				     const char *value);
@@ -40,9 +41,6 @@  extern void set_struct_debug_option (str
    an actual variable not a macro.  */
 extern int flag_compare_debug;
 
-/* Global visibility options.  */
-extern struct visibility_flags visibility_options;
-
 /* True if this is the LTO front end (lto1).  This is used to disable
    gimple generation and lowering passes that are normally run on the
    output of a front end.  These passes must be bypassed for lto since
@@ -50,6 +48,10 @@  extern struct visibility_flags visibilit
 
 extern bool in_lto_p;
 
+/* Return true iff flags are set as if -ffast-math.  */
+extern bool fast_math_flags_set_p (const struct gcc_options *);
+extern bool fast_math_flags_struct_set_p (struct cl_optimization *);
+
 /* Used to set the level of -Wstrict-aliasing in OPTS, when no level
    is specified.  The external way to set the default level is to use
    -Wstrict-aliasing=level.
Index: gcc/opts-common.c
===================================================================
--- gcc/opts-common.c	(revision 167073)
+++ gcc/opts-common.c	(working copy)
@@ -994,6 +994,78 @@  option_flag_var (int opt_index, struct g
   return (void *)(((char *) opts) + option->flag_var_offset);
 }
 
+/* Return 1 if option OPT_IDX is enabled in OPTS, 0 if it is disabled,
+   or -1 if it isn't a simple on-off switch.  */
+
+int
+option_enabled (int opt_idx, void *opts)
+{
+  const struct cl_option *option = &(cl_options[opt_idx]);
+  struct gcc_options *optsg = (struct gcc_options *) opts;
+  void *flag_var = option_flag_var (opt_idx, optsg);
+
+  if (flag_var)
+    switch (option->var_type)
+      {
+      case CLVC_BOOLEAN:
+	return *(int *) flag_var != 0;
+
+      case CLVC_EQUAL:
+	return *(int *) flag_var == option->var_value;
+
+      case CLVC_BIT_CLEAR:
+	return (*(int *) flag_var & option->var_value) == 0;
+
+      case CLVC_BIT_SET:
+	return (*(int *) flag_var & option->var_value) != 0;
+
+      case CLVC_STRING:
+      case CLVC_DEFER:
+	break;
+      }
+  return -1;
+}
+
+/* Fill STATE with the current state of option OPTION in OPTS.  Return
+   true if there is some state to store.  */
+
+bool
+get_option_state (struct gcc_options *opts, int option,
+		  struct cl_option_state *state)
+{
+  void *flag_var = option_flag_var (option, opts);
+
+  if (flag_var == 0)
+    return false;
+
+  switch (cl_options[option].var_type)
+    {
+    case CLVC_BOOLEAN:
+    case CLVC_EQUAL:
+      state->data = flag_var;
+      state->size = sizeof (int);
+      break;
+
+    case CLVC_BIT_CLEAR:
+    case CLVC_BIT_SET:
+      state->ch = option_enabled (option, opts);
+      state->data = &state->ch;
+      state->size = 1;
+      break;
+
+    case CLVC_STRING:
+      state->data = *(const char **) flag_var;
+      if (state->data == 0)
+	state->data = "";
+      state->size = strlen ((const char *) state->data) + 1;
+      break;
+
+    case CLVC_DEFER:
+      return false;
+    }
+  return true;
+}
+
 /* Set a warning option OPT_INDEX (language mask LANG_MASK, option
    handlers HANDLERS) to have diagnostic kind KIND for option
    structures OPTS and OPTS_SET and diagnostic context DC (possibly
Index: gcc/c-family/c-opts.c
===================================================================
--- gcc/c-family/c-opts.c	(revision 167073)
+++ gcc/c-family/c-opts.c	(working copy)
@@ -116,7 +116,7 @@  static void add_prefixed_path (const cha
 static void push_command_line_include (void);
 static void cb_file_change (cpp_reader *, const struct line_map *);
 static void cb_dir_change (cpp_reader *, const char *);
-static void finish_options (void);
+static void c_finish_options (void);
 
 #ifndef STDC_0_IN_SYSTEM_HEADERS
 #define STDC_0_IN_SYSTEM_HEADERS 0
@@ -1047,7 +1047,7 @@  c_common_init (void)
 
   if (flag_preprocess_only)
     {
-      finish_options ();
+      c_finish_options ();
       preprocess_file (parse_in);
       return false;
     }
@@ -1065,7 +1065,7 @@  c_common_parse_file (void)
   i = 0;
   for (;;)
     {
-      finish_options ();
+      c_finish_options ();
       pch_init ();
       push_file_scope ();
       c_parse_file ();
@@ -1277,7 +1277,7 @@  add_prefixed_path (const char *suffix, s
 
 /* Handle -D, -U, -A, -imacros, and the first -include.  */
 static void
-finish_options (void)
+c_finish_options (void)
 {
   if (!cpp_opts->preprocessed)
     {
Index: gcc/c-family/c-common.c
===================================================================
--- gcc/c-family/c-common.c	(revision 167073)
+++ gcc/c-family/c-common.c	(working copy)
@@ -304,6 +304,9 @@  const struct fname_var_t fname_vars[] =
   {NULL, 0, 0},
 };
 
+/* Global visibility options.  */
+struct visibility_flags visibility_options;
+
 static tree c_fully_fold_internal (tree expr, bool, bool *, bool *);
 static tree check_case_value (tree);
 static bool check_case_bounds (tree, tree, tree *, tree *);
Index: gcc/c-family/c-common.h
===================================================================
--- gcc/c-family/c-common.h	(revision 167073)
+++ gcc/c-family/c-common.h	(working copy)
@@ -660,6 +660,15 @@  extern bool done_lexing;
 #define C_TYPE_OBJECT_OR_INCOMPLETE_P(type) \
   (!C_TYPE_FUNCTION_P (type))
 
+struct visibility_flags
+{
+  unsigned inpragma : 1;	/* True when in #pragma GCC visibility.  */
+  unsigned inlines_hidden : 1;	/* True when -finlineshidden in effect.  */
+};
+
+/* Global visibility options.  */
+extern struct visibility_flags visibility_options;
+
 /* Attribute table common to the C front ends.  */
 extern const struct attribute_spec c_common_attribute_table[];
 extern const struct attribute_spec c_common_format_attribute_table[];
Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 167073)
+++ gcc/toplev.c	(working copy)
@@ -28,11 +28,6 @@  along with GCC; see the file COPYING3.  
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
-#include <signal.h>
-
-#ifdef HAVE_SYS_RESOURCE_H
-# include <sys/resource.h>
-#endif
 
 #ifdef HAVE_SYS_TIMES_H
 # include <sys/times.h>
@@ -114,7 +109,6 @@  static void init_asm_output (const char 
 static void finalize (void);
 
 static void crash_signal (int) ATTRIBUTE_NORETURN;
-static void setup_core_dumping (void);
 static void compile_file (void);
 
 /* True if we don't need a backend (e.g. preprocessing only).  */
@@ -480,48 +474,6 @@  crash_signal (int signo)
   internal_error ("%s", strsignal (signo));
 }
 
-/* Arrange to dump core on error.  (The regular error message is still
-   printed first, except in the case of abort().)  */
-
-static void
-setup_core_dumping (void)
-{
-#ifdef SIGABRT
-  signal (SIGABRT, SIG_DFL);
-#endif
-#if defined(HAVE_SETRLIMIT)
-  {
-    struct rlimit rlim;
-    if (getrlimit (RLIMIT_CORE, &rlim) != 0)
-      fatal_error ("getting core file size maximum limit: %m");
-    rlim.rlim_cur = rlim.rlim_max;
-    if (setrlimit (RLIMIT_CORE, &rlim) != 0)
-      fatal_error ("setting core file size limit to maximum: %m");
-  }
-#endif
-  diagnostic_abort_on_error (global_dc);
-}
-
-
-/* Strip off a legitimate source ending from the input string NAME of
-   length LEN.  Rather than having to know the names used by all of
-   our front ends, we strip off an ending of a period followed by
-   up to five characters.  (Java uses ".class".)  */
-
-void
-strip_off_ending (char *name, int len)
-{
-  int i;
-  for (i = 2; i < 6 && len > i; i++)
-    {
-      if (name[len - i] == '.')
-	{
-	  name[len - i] = '\0';
-	  break;
-	}
-    }
-}
-
 /* Output a quoted string.  */
 
 void
@@ -967,51 +919,6 @@  compile_file (void)
   targetm.asm_out.file_end ();
 }
 
-/* Parse a -d... command line switch.  */
-
-void
-decode_d_option (const char *arg)
-{
-  int c;
-
-  while (*arg)
-    switch (c = *arg++)
-      {
-      case 'A':
-	flag_debug_asm = 1;
-	break;
-      case 'p':
-	flag_print_asm_name = 1;
-	break;
-      case 'P':
-	flag_dump_rtl_in_asm = 1;
-	flag_print_asm_name = 1;
-	break;
-      case 'v':
-	graph_dump_format = vcg;
-	break;
-      case 'x':
-	rtl_dump_and_exit = 1;
-	break;
-      case 'D':	/* These are handled by the preprocessor.  */
-      case 'I':
-      case 'M':
-      case 'N':
-      case 'U':
-	break;
-      case 'H':
-	setup_core_dumping();
-	break;
-      case 'a':
-	enable_rtl_dump_file ();
-	break;
-
-      default:
-	  warning (0, "unrecognized gcc debugging option: %c", c);
-	break;
-      }
-}
-
 /* Indexed by enum debug_info_type.  */
 const char *const debug_type_names[] =
 {
Index: gcc/toplev.h
===================================================================
--- gcc/toplev.h	(revision 167073)
+++ gcc/toplev.h	(working copy)
@@ -34,7 +34,6 @@  extern struct cl_decoded_option *save_de
 extern unsigned int save_decoded_options_count;
 
 extern int toplev_main (int, char **);
-extern void strip_off_ending (char *, int);
 extern void rest_of_decl_compilation (tree, int, int);
 extern void rest_of_type_compilation (tree, int);
 extern void tree_rest_of_compilation (tree);
@@ -92,13 +91,6 @@  extern const char * default_pch_valid_p 
 /* The hashtable, so that the C front ends can pass it to cpplib.  */
 extern struct ht *ident_hash;
 
-/* Handle -d switch.  */
-extern void decode_d_option		(const char *);
-
-/* Return true iff flags are set as if -ffast-math.  */
-extern bool fast_math_flags_set_p	(const struct gcc_options *);
-extern bool fast_math_flags_struct_set_p (struct cl_optimization *);
-
 /* Inline versions of the above for speed.  */
 #if GCC_VERSION < 3004
 
Index: gcc/opts.c
===================================================================
--- gcc/opts.c	(revision 167073)
+++ gcc/opts.c	(working copy)
@@ -21,25 +21,30 @@  along with GCC; see the file COPYING3.  
 
 #include "config.h"
 #include "system.h"
+
+#include <signal.h>
+
+#ifdef HAVE_SYS_RESOURCE_H
+# include <sys/resource.h>
+#endif
+
 #include "intl.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "tree.h"
-#include "expr.h"
-#include "langhooks.h"
+#include "tm.h" /* Needed by rtl.h and used for DWARF2_DEBUGGING_INFO
+		   and DBX_DEBUGGING_INFO.  */
+#include "tree.h" /* For vect_set_verbosity_level.  */
+#include "rtl.h" /* Needed by insn-attr.h.  */
 #include "opts.h"
 #include "options.h"
 #include "flags.h"
-#include "toplev.h"
+#include "toplev.h" /* For set_random_seed and enable_rtl_dump_file.  */
 #include "params.h"
 #include "diagnostic.h"
 #include "opts-diagnostic.h"
-#include "insn-attr.h"		/* For INSN_SCHEDULING.  */
+#include "insn-attr.h"		/* For INSN_SCHEDULING and DELAY_SLOTS.  */
 #include "target.h"
 #include "dbgcnt.h"
 #include "debug.h"
-#include "except.h"
-#include "lto-streamer.h"
 
 /* Run the second compilation of -fcompare-debug.  Not defined using
    Var in common.opt because this is used in Ada code and so must be
@@ -136,6 +141,25 @@  set_struct_debug_option (struct gcc_opti
     }
 }
 
+/* Strip off a legitimate source ending from the input string NAME of
+   length LEN.  Rather than having to know the names used by all of
+   our front ends, we strip off an ending of a period followed by
+   up to five characters.  (Java uses ".class".)  */
+
+void
+strip_off_ending (char *name, int len)
+{
+  int i;
+  for (i = 2; i < 6 && len > i; i++)
+    {
+      if (name[len - i] == '.')
+	{
+	  name[len - i] = '\0';
+	  break;
+	}
+    }
+}
+
 /* Find the base name of a path, stripping off both directories and
    a single final extension. */
 int
@@ -162,9 +186,6 @@  base_of_path (const char *path, const ch
   return dot - base;
 }
 
-/* Global visibility options.  */
-struct visibility_flags visibility_options;
-
 /* What to print when a switch has no documentation.  */
 static const char undocumented_msg[] = N_("This switch lacks documentation");
 
@@ -172,32 +193,13 @@  typedef char *char_p; /* For DEF_VEC_P. 
 DEF_VEC_P(char_p);
 DEF_VEC_ALLOC_P(char_p,heap);
 
-typedef const char *const_char_p; /* For DEF_VEC_P.  */
-DEF_VEC_P(const_char_p);
-DEF_VEC_ALLOC_P(const_char_p,heap);
-
-static VEC(const_char_p,heap) *ignored_options;
-
-/* Input file names.  */
-const char **in_fnames;
-unsigned num_in_fnames;
-
-static bool common_handle_option (struct gcc_options *opts,
-				  struct gcc_options *opts_set,
-				  const struct cl_decoded_option *decoded,
-				  unsigned int lang_mask, int kind,
-				  location_t loc,
-				  const struct cl_option_handlers *handlers,
-				  diagnostic_context *dc);
 static void handle_param (struct gcc_options *opts,
 			  struct gcc_options *opts_set, const char *carg);
-static char *write_langs (unsigned int lang_mask);
-static void complain_wrong_lang (const struct cl_decoded_option *,
-				 unsigned int lang_mask);
 static void set_debug_level (enum debug_info_type type, int extended,
 			     const char *arg, struct gcc_options *opts,
 			     struct gcc_options *opts_set);
 static void set_fast_math_flags (struct gcc_options *opts, int set);
+static void decode_d_option (const char *arg);
 static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
 						 int set);
 static void enable_warning_as_error (const char *arg, int value,
@@ -208,155 +210,10 @@  static void enable_warning_as_error (con
 				     location_t loc,
 				     diagnostic_context *dc);
 
-/* Return a malloced slash-separated list of languages in MASK.  */
-static char *
-write_langs (unsigned int mask)
-{
-  unsigned int n = 0, len = 0;
-  const char *lang_name;
-  char *result;
-
-  for (n = 0; (lang_name = lang_names[n]) != 0; n++)
-    if (mask & (1U << n))
-      len += strlen (lang_name) + 1;
-
-  result = XNEWVEC (char, len);
-  len = 0;
-  for (n = 0; (lang_name = lang_names[n]) != 0; n++)
-    if (mask & (1U << n))
-      {
-	if (len)
-	  result[len++] = '/';
-	strcpy (result + len, lang_name);
-	len += strlen (lang_name);
-      }
-
-  result[len] = 0;
-
-  return result;
-}
-
-/* Complain that switch DECODED does not apply to this front end (mask
-   LANG_MASK).  */
-static void
-complain_wrong_lang (const struct cl_decoded_option *decoded,
-		     unsigned int lang_mask)
-{
-  const struct cl_option *option = &cl_options[decoded->opt_index];
-  const char *text = decoded->orig_option_with_args_text;
-  char *ok_langs = NULL, *bad_lang = NULL;
-  unsigned int opt_flags = option->flags;
-
-  if (!lang_hooks.complain_wrong_lang_p (option))
-    return;
-
-  opt_flags &= ((1U << cl_lang_count) - 1) | CL_DRIVER;
-  if (opt_flags != CL_DRIVER)
-    ok_langs = write_langs (opt_flags);
-  if (lang_mask != CL_DRIVER)
-    bad_lang = write_langs (lang_mask);
-
-  if (opt_flags == CL_DRIVER)
-    error ("command line option %qs is valid for the driver but not for %s",
-	   text, bad_lang);
-  else if (lang_mask == CL_DRIVER)
-    gcc_unreachable ();
-  else
-    /* Eventually this should become a hard error IMO.  */
-    warning (0, "command line option %qs is valid for %s but not for %s",
-	     text, ok_langs, bad_lang);
-
-  free (ok_langs);
-  free (bad_lang);
-}
-
-/* Buffer the unknown option described by the string OPT.  Currently,
-   we only complain about unknown -Wno-* options if they may have
-   prevented a diagnostic. Otherwise, we just ignore them.
-   Note that if we do complain, it is only as a warning, not an error;
-   passing the compiler an unrecognised -Wno-* option should never
-   change whether the compilation succeeds or fails.  */
-
-static void postpone_unknown_option_warning(const char *opt)
-{
-  VEC_safe_push (const_char_p, heap, ignored_options, opt);
-}
-
-/* Produce a warning for each option previously buffered.  */
-
-void print_ignored_options (void)
-{
-  location_t saved_loc = input_location;
-
-  input_location = 0;
-
-  while (!VEC_empty (const_char_p, ignored_options))
-    {
-      const char *opt;
-      opt = VEC_pop (const_char_p, ignored_options);
-      warning (0, "unrecognized command line option \"%s\"", opt);
-    }
-
-  input_location = saved_loc;
-}
-
-/* Handle an unknown option DECODED, returning true if an error should be
-   given.  */
-
-static bool
-unknown_option_callback (const struct cl_decoded_option *decoded)
-{
-  const char *opt = decoded->arg;
-
-  if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-'
-      && !(decoded->errors & CL_ERR_NEGATIVE))
-    {
-      /* We don't generate warnings for unknown -Wno-* options unless
-	 we issue diagnostics.  */
-      postpone_unknown_option_warning (opt);
-      return false;
-    }
-  else
-    return true;
-}
-
-/* Note that an option DECODED has been successfully handled with a
-   handler for mask MASK.  */
-
-static void
-post_handling_callback (const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED,
-			unsigned int mask ATTRIBUTE_UNUSED)
-{
-#ifdef ENABLE_LTO
-  lto_register_user_option (decoded->opt_index, decoded->arg,
-			    decoded->value, mask);
-#endif
-}
-
-/* Handle a front-end option; arguments and return value as for
-   handle_option.  */
-
-static bool
-lang_handle_option (struct gcc_options *opts,
-		    struct gcc_options *opts_set,
-		    const struct cl_decoded_option *decoded,
-		    unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
-		    location_t loc,
-		    const struct cl_option_handlers *handlers,
-		    diagnostic_context *dc)
-{
-  gcc_assert (opts == &global_options);
-  gcc_assert (opts_set == &global_options_set);
-  gcc_assert (dc == global_dc);
-  gcc_assert (decoded->canonical_option_num_elements <= 2);
-  return lang_hooks.handle_option (decoded->opt_index, decoded->arg,
-				   decoded->value, kind, loc, handlers);
-}
-
 /* Handle a back-end option; arguments and return value as for
    handle_option.  */
 
-static bool
+bool
 target_handle_option (struct gcc_options *opts,
 		      struct gcc_options *opts_set,
 		      const struct cl_decoded_option *decoded,
@@ -378,15 +235,6 @@  target_handle_option (struct gcc_options
 				decoded->value);
 }
 
-/* Handle FILENAME from the command line.  */
-static void
-add_input_filename (const char *filename)
-{
-  num_in_fnames++;
-  in_fnames = XRESIZEVEC (const char *, in_fnames, num_in_fnames);
-  in_fnames[num_in_fnames - 1] = filename;
-}
-
 /* Add comma-separated strings to a char_p vector.  */
 
 static void
@@ -428,61 +276,6 @@  add_comma_separated_to_vector (void **pv
   *pvec = vec;
 }
 
-/* Handle the vector of command line options (located at LOC), storing
-   the results of processing DECODED_OPTIONS and DECODED_OPTIONS_COUNT
-   in OPTS and OPTS_SET and using DC for diagnostic state.  LANG_MASK
-   contains has a single bit set representing the current language.
-   HANDLERS describes what functions to call for the options.  */
-static void
-read_cmdline_options (struct gcc_options *opts, struct gcc_options *opts_set,
-		      struct cl_decoded_option *decoded_options,
-		      unsigned int decoded_options_count,
-		      location_t loc,
-		      unsigned int lang_mask,
-		      const struct cl_option_handlers *handlers,
-		      diagnostic_context *dc)
-{
-  unsigned int i;
-
-  for (i = 1; i < decoded_options_count; i++)
-    {
-      if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
-	{
-	  /* Input files should only ever appear on the main command
-	     line.  */
-	  gcc_assert (opts == &global_options);
-	  gcc_assert (opts_set == &global_options_set);
-
-	  if (main_input_filename == NULL)
-	    {
-	      main_input_filename = decoded_options[i].arg;
-	      main_input_baselength
-		= base_of_path (main_input_filename, &main_input_basename);
-	    }
-	  add_input_filename (decoded_options[i].arg);
-	  continue;
-	}
-
-      read_cmdline_option (opts, opts_set,
-			   decoded_options + i, loc, lang_mask, handlers,
-			   dc);
-    }
-}
-
-/* Language mask determined at initialization.  */
-static unsigned int initial_lang_mask;
-
-/* Initialize global options-related settings at start-up.  */
-
-void
-init_options_once (void)
-{
-  /* Perform language-specific options initialization.  */
-  initial_lang_mask = lang_hooks.option_lang_mask ();
-
-  lang_hooks.initialize_diagnostics (global_dc);
-}
-
 /* Initialize OPTS and OPTS_SET before using them in parsing options.  */
 
 void
@@ -519,21 +312,6 @@  init_options_struct (struct gcc_options 
   targetm.target_option.init_struct (opts);
 }
 
-/* Decode command-line options to an array, like
-   decode_cmdline_options_to_array and with the same arguments but
-   using the default lang_mask.  */
-
-void
-decode_cmdline_options_to_array_default_mask (unsigned int argc,
-					      const char **argv, 
-					      struct cl_decoded_option **decoded_options,
-					      unsigned int *decoded_options_count)
-{
-  decode_cmdline_options_to_array (argc, argv,
-				   initial_lang_mask | CL_COMMON | CL_TARGET,
-				   decoded_options, decoded_options_count);
-}
-
 /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
    -Ofast if FAST is set), apply the option DEFAULT_OPT to OPTS and
    OPTS_SET, diagnostic context DC, location LOC, with language mask
@@ -725,7 +503,7 @@  static const struct default_options defa
 
 /* Default the options in OPTS and OPTS_SET based on the optimization
    settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT.  */
-static void
+void
 default_options_optimization (struct gcc_options *opts,
 			      struct gcc_options *opts_set,
 			      struct cl_decoded_option *decoded_options,
@@ -826,69 +604,10 @@  default_options_optimization (struct gcc
 			 ofast, lang_mask, handlers, loc, dc);
 }
 
-static void finish_options (struct gcc_options *, struct gcc_options *);
-
-/* Set *HANDLERS to the default set of option handlers for use in the
-   compilers proper (not the driver).  */
-void
-set_default_handlers (struct cl_option_handlers *handlers)
-{
-  handlers->unknown_option_callback = unknown_option_callback;
-  handlers->wrong_lang_callback = complain_wrong_lang;
-  handlers->post_handling_callback = post_handling_callback;
-  handlers->num_handlers = 3;
-  handlers->handlers[0].handler = lang_handle_option;
-  handlers->handlers[0].mask = initial_lang_mask;
-  handlers->handlers[1].handler = common_handle_option;
-  handlers->handlers[1].mask = CL_COMMON;
-  handlers->handlers[2].handler = target_handle_option;
-  handlers->handlers[2].mask = CL_TARGET;
-}
-
-/* Parse command line options and set default flag values.  Do minimal
-   options processing.  The decoded options are in *DECODED_OPTIONS
-   and *DECODED_OPTIONS_COUNT; settings go in OPTS, OPTS_SET and DC;
-   the options are located at LOC.  */
-void
-decode_options (struct gcc_options *opts, struct gcc_options *opts_set,
-		struct cl_decoded_option *decoded_options,
-		unsigned int decoded_options_count,
-		location_t loc, diagnostic_context *dc)
-{
-  struct cl_option_handlers handlers;
-
-  unsigned int lang_mask;
-
-  lang_mask = initial_lang_mask;
-
-  set_default_handlers (&handlers);
-
-  /* Enable -Werror=coverage-mismatch by default.  */
-  control_warning_option (OPT_Wcoverage_mismatch, (int) DK_ERROR, true,
-			  loc, lang_mask,
-			  &handlers, opts, opts_set, dc);
-
-  default_options_optimization (opts, opts_set,
-				decoded_options, decoded_options_count,
-				loc, lang_mask, &handlers, dc);
-
-#ifdef ENABLE_LTO
-  /* Clear any options currently held for LTO.  */
-  lto_clear_user_options ();
-#endif
-
-  read_cmdline_options (opts, opts_set,
-			decoded_options, decoded_options_count,
-			loc, lang_mask,
-			&handlers, dc);
-
-  finish_options (opts, opts_set);
-}
-
 /* After all options have been read into OPTS and OPTS_SET, finalize
    settings of those options and diagnose incompatible
    combinations.  */
-static void
+void
 finish_options (struct gcc_options *opts, struct gcc_options *opts_set)
 {
   static bool first_time_p = true;
@@ -1419,7 +1138,7 @@  print_specific_help (unsigned int includ
    extra handling need to be listed here; if you simply want
    DECODED->value assigned to a variable, it happens automatically.  */
 
-static bool
+bool
 common_handle_option (struct gcc_options *opts,
 		      struct gcc_options *opts_set,
 		      const struct cl_decoded_option *decoded,
@@ -2145,76 +1864,71 @@  set_debug_level (enum debug_info_type ty
     }
 }
 
-/* Return 1 if option OPT_IDX is enabled in OPTS, 0 if it is disabled,
-   or -1 if it isn't a simple on-off switch.  */
+/* Arrange to dump core on error.  (The regular error message is still
+   printed first, except in the case of abort ().)  */
 
-int
-option_enabled (int opt_idx, void *opts)
+static void
+setup_core_dumping (void)
 {
-  const struct cl_option *option = &(cl_options[opt_idx]);
-  struct gcc_options *optsg = (struct gcc_options *) opts;
-  void *flag_var = option_flag_var (opt_idx, optsg);
-
-  if (flag_var)
-    switch (option->var_type)
-      {
-      case CLVC_BOOLEAN:
-	return *(int *) flag_var != 0;
-
-      case CLVC_EQUAL:
-	return *(int *) flag_var == option->var_value;
-
-      case CLVC_BIT_CLEAR:
-	return (*(int *) flag_var & option->var_value) == 0;
-
-      case CLVC_BIT_SET:
-	return (*(int *) flag_var & option->var_value) != 0;
-
-      case CLVC_STRING:
-      case CLVC_DEFER:
-	break;
-      }
-  return -1;
+#ifdef SIGABRT
+  signal (SIGABRT, SIG_DFL);
+#endif
+#if defined(HAVE_SETRLIMIT)
+  {
+    struct rlimit rlim;
+    if (getrlimit (RLIMIT_CORE, &rlim) != 0)
+      fatal_error ("getting core file size maximum limit: %m");
+    rlim.rlim_cur = rlim.rlim_max;
+    if (setrlimit (RLIMIT_CORE, &rlim) != 0)
+      fatal_error ("setting core file size limit to maximum: %m");
+  }
+#endif
+  diagnostic_abort_on_error (global_dc);
 }
 
-/* Fill STATE with the current state of option OPTION in OPTS.  Return
-   true if there is some state to store.  */
+/* Parse a -d<ARG> command line switch.  */
 
-bool
-get_option_state (struct gcc_options *opts, int option,
-		  struct cl_option_state *state)
+static void
+decode_d_option (const char *arg)
 {
-  void *flag_var = option_flag_var (option, opts);
+  int c;
 
-  if (flag_var == 0)
-    return false;
-
-  switch (cl_options[option].var_type)
-    {
-    case CLVC_BOOLEAN:
-    case CLVC_EQUAL:
-      state->data = flag_var;
-      state->size = sizeof (int);
-      break;
-
-    case CLVC_BIT_CLEAR:
-    case CLVC_BIT_SET:
-      state->ch = option_enabled (option, opts);
-      state->data = &state->ch;
-      state->size = 1;
-      break;
-
-    case CLVC_STRING:
-      state->data = *(const char **) flag_var;
-      if (state->data == 0)
-	state->data = "";
-      state->size = strlen ((const char *) state->data) + 1;
-      break;
+  while (*arg)
+    switch (c = *arg++)
+      {
+      case 'A':
+	flag_debug_asm = 1;
+	break;
+      case 'p':
+	flag_print_asm_name = 1;
+	break;
+      case 'P':
+	flag_dump_rtl_in_asm = 1;
+	flag_print_asm_name = 1;
+	break;
+      case 'v':
+	graph_dump_format = vcg;
+	break;
+      case 'x':
+	rtl_dump_and_exit = 1;
+	break;
+      case 'D':	/* These are handled by the preprocessor.  */
+      case 'I':
+      case 'M':
+      case 'N':
+      case 'U':
+	break;
+      case 'H':
+	setup_core_dumping ();
+	break;
+      case 'a':
+	enable_rtl_dump_file ();
+	break;
 
-    case CLVC_DEFER:
-      return false;
-    }
-  return true;
+      default:
+	  warning (0, "unrecognized gcc debugging option: %c", c);
+	break;
+      }
 }
 
 /* Enable (or disable if VALUE is 0) a warning option ARG (language
Index: gcc/opts.h
===================================================================
--- gcc/opts.h	(revision 167073)
+++ gcc/opts.h	(working copy)
@@ -284,4 +284,28 @@  extern void control_warning_option (unsi
 				    diagnostic_context *dc);
 extern void print_ignored_options (void);
 extern void handle_common_deferred_options (void);
+extern bool common_handle_option (struct gcc_options *opts,
+				  struct gcc_options *opts_set,
+				  const struct cl_decoded_option *decoded,
+				  unsigned int lang_mask, int kind,
+				  location_t loc,
+				  const struct cl_option_handlers *handlers,
+				  diagnostic_context *dc);
+extern bool target_handle_option (struct gcc_options *opts,
+				  struct gcc_options *opts_set,
+				  const struct cl_decoded_option *decoded,
+				  unsigned int lang_mask, int kind,
+				  location_t loc,
+				  const struct cl_option_handlers *handlers,
+				  diagnostic_context *dc);
+extern void finish_options (struct gcc_options *opts,
+			    struct gcc_options *opts_set);
+extern void default_options_optimization (struct gcc_options *opts,
+					  struct gcc_options *opts_set,
+					  struct cl_decoded_option *decoded_options,
+					  unsigned int decoded_options_count,
+					  location_t loc,
+					  unsigned int lang_mask,
+					  const struct cl_option_handlers *handlers,
+					  diagnostic_context *dc);
 #endif
Index: gcc/flag-types.h
===================================================================
--- gcc/flag-types.h	(revision 167073)
+++ gcc/flag-types.h	(working copy)
@@ -106,12 +106,6 @@  enum symbol_visibility
 };
 #endif
 
-struct visibility_flags
-{
-  unsigned inpragma : 1;	/* True when in #pragma GCC visibility.  */
-  unsigned inlines_hidden : 1;	/* True when -finlineshidden in effect.  */
-};
-
 /* The algorithm used for the integrated register allocator (IRA).  */
 enum ira_algorithm
 {
Index: gcc/opts-global.c
===================================================================
--- gcc/opts-global.c	(revision 167073)
+++ gcc/opts-global.c	(working copy)
@@ -22,16 +22,316 @@  along with GCC; see the file COPYING3.  
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "diagnostic-core.h"
+#include "diagnostic.h"
 #include "opts.h"
 #include "flags.h"
 #include "ggc.h"
+#include "tree.h" /* Required by langhooks.h.  */
+#include "langhooks.h"
 #include "tm.h" /* Required by rtl.h.  */
 #include "rtl.h"
+#include "lto-streamer.h"
 #include "output.h"
 #include "plugin.h"
+#include "toplev.h"
 #include "tree-pass.h"
 
+typedef const char *const_char_p; /* For DEF_VEC_P.  */
+DEF_VEC_P(const_char_p);
+DEF_VEC_ALLOC_P(const_char_p,heap);
+
+static VEC(const_char_p,heap) *ignored_options;
+
+/* Input file names.  */
+const char **in_fnames;
+unsigned num_in_fnames;
+
+/* Return a malloced slash-separated list of languages in MASK.  */
+
+static char *
+write_langs (unsigned int mask)
+{
+  unsigned int n = 0, len = 0;
+  const char *lang_name;
+  char *result;
+
+  for (n = 0; (lang_name = lang_names[n]) != 0; n++)
+    if (mask & (1U << n))
+      len += strlen (lang_name) + 1;
+
+  result = XNEWVEC (char, len);
+  len = 0;
+  for (n = 0; (lang_name = lang_names[n]) != 0; n++)
+    if (mask & (1U << n))
+      {
+	if (len)
+	  result[len++] = '/';
+	strcpy (result + len, lang_name);
+	len += strlen (lang_name);
+      }
+
+  result[len] = 0;
+
+  return result;
+}
+
+/* Complain that switch DECODED does not apply to this front end (mask
+   LANG_MASK).  */
+
+static void
+complain_wrong_lang (const struct cl_decoded_option *decoded,
+		     unsigned int lang_mask)
+{
+  const struct cl_option *option = &cl_options[decoded->opt_index];
+  const char *text = decoded->orig_option_with_args_text;
+  char *ok_langs = NULL, *bad_lang = NULL;
+  unsigned int opt_flags = option->flags;
+
+  if (!lang_hooks.complain_wrong_lang_p (option))
+    return;
+
+  opt_flags &= ((1U << cl_lang_count) - 1) | CL_DRIVER;
+  if (opt_flags != CL_DRIVER)
+    ok_langs = write_langs (opt_flags);
+  if (lang_mask != CL_DRIVER)
+    bad_lang = write_langs (lang_mask);
+
+  if (opt_flags == CL_DRIVER)
+    error ("command line option %qs is valid for the driver but not for %s",
+	   text, bad_lang);
+  else if (lang_mask == CL_DRIVER)
+    gcc_unreachable ();
+  else
+    /* Eventually this should become a hard error IMO.  */
+    warning (0, "command line option %qs is valid for %s but not for %s",
+	     text, ok_langs, bad_lang);
+
+  free (ok_langs);
+  free (bad_lang);
+}
+
+/* Buffer the unknown option described by the string OPT.  Currently,
+   we only complain about unknown -Wno-* options if they may have
+   prevented a diagnostic. Otherwise, we just ignore them.  Note that
+   if we do complain, it is only as a warning, not an error; passing
+   the compiler an unrecognised -Wno-* option should never change
+   whether the compilation succeeds or fails.  */
+
+static void
+postpone_unknown_option_warning (const char *opt)
+{
+  VEC_safe_push (const_char_p, heap, ignored_options, opt);
+}
+
+/* Produce a warning for each option previously buffered.  */
+
+void
+print_ignored_options (void)
+{
+  while (!VEC_empty (const_char_p, ignored_options))
+    {
+      const char *opt;
+
+      opt = VEC_pop (const_char_p, ignored_options);
+      warning_at (UNKNOWN_LOCATION, 0,
+		  "unrecognized command line option \"%s\"", opt);
+    }
+}
+
+/* Handle an unknown option DECODED, returning true if an error should
+   be given.  */
+
+static bool
+unknown_option_callback (const struct cl_decoded_option *decoded)
+{
+  const char *opt = decoded->arg;
+
+  if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-'
+      && !(decoded->errors & CL_ERR_NEGATIVE))
+    {
+      /* We don't generate warnings for unknown -Wno-* options unless
+	 we issue diagnostics.  */
+      postpone_unknown_option_warning (opt);
+      return false;
+    }
+  else
+    return true;
+}
+
+/* Note that an option DECODED has been successfully handled with a
+   handler for mask MASK.  */
+
+static void
+post_handling_callback (const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED,
+			unsigned int mask ATTRIBUTE_UNUSED)
+{
+#ifdef ENABLE_LTO
+  lto_register_user_option (decoded->opt_index, decoded->arg,
+			    decoded->value, mask);
+#endif
+}
+
+/* Handle a front-end option; arguments and return value as for
+   handle_option.  */
+
+static bool
+lang_handle_option (struct gcc_options *opts,
+		    struct gcc_options *opts_set,
+		    const struct cl_decoded_option *decoded,
+		    unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
+		    location_t loc,
+		    const struct cl_option_handlers *handlers,
+		    diagnostic_context *dc)
+{
+  gcc_assert (opts == &global_options);
+  gcc_assert (opts_set == &global_options_set);
+  gcc_assert (dc == global_dc);
+  gcc_assert (decoded->canonical_option_num_elements <= 2);
+  return lang_hooks.handle_option (decoded->opt_index, decoded->arg,
+				   decoded->value, kind, loc, handlers);
+}
+
+/* Handle FILENAME from the command line.  */
+
+static void
+add_input_filename (const char *filename)
+{
+  num_in_fnames++;
+  in_fnames = XRESIZEVEC (const char *, in_fnames, num_in_fnames);
+  in_fnames[num_in_fnames - 1] = filename;
+}
+
+/* Handle the vector of command line options (located at LOC), storing
+   the results of processing DECODED_OPTIONS and DECODED_OPTIONS_COUNT
+   in OPTS and OPTS_SET and using DC for diagnostic state.  LANG_MASK
+   contains has a single bit set representing the current language.
+   HANDLERS describes what functions to call for the options.  */
+
+static void
+read_cmdline_options (struct gcc_options *opts, struct gcc_options *opts_set,
+		      struct cl_decoded_option *decoded_options,
+		      unsigned int decoded_options_count,
+		      location_t loc,
+		      unsigned int lang_mask,
+		      const struct cl_option_handlers *handlers,
+		      diagnostic_context *dc)
+{
+  unsigned int i;
+
+  for (i = 1; i < decoded_options_count; i++)
+    {
+      if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
+	{
+	  /* Input files should only ever appear on the main command
+	     line.  */
+	  gcc_assert (opts == &global_options);
+	  gcc_assert (opts_set == &global_options_set);
+
+	  if (main_input_filename == NULL)
+	    {
+	      main_input_filename = decoded_options[i].arg;
+	      main_input_baselength
+		= base_of_path (main_input_filename, &main_input_basename);
+	    }
+	  add_input_filename (decoded_options[i].arg);
+	  continue;
+	}
+
+      read_cmdline_option (opts, opts_set,
+			   decoded_options + i, loc, lang_mask, handlers,
+			   dc);
+    }
+}
+
+/* Language mask determined at initialization.  */
+static unsigned int initial_lang_mask;
+
+/* Initialize global options-related settings at start-up.  */
+
+void
+init_options_once (void)
+{
+  /* Perform language-specific options initialization.  */
+  initial_lang_mask = lang_hooks.option_lang_mask ();
+
+  lang_hooks.initialize_diagnostics (global_dc);
+}
+
+/* Decode command-line options to an array, like
+   decode_cmdline_options_to_array and with the same arguments but
+   using the default lang_mask.  */
+
+void
+decode_cmdline_options_to_array_default_mask (unsigned int argc,
+					      const char **argv, 
+					      struct cl_decoded_option **decoded_options,
+					      unsigned int *decoded_options_count)
+{
+  decode_cmdline_options_to_array (argc, argv,
+				   initial_lang_mask | CL_COMMON | CL_TARGET,
+				   decoded_options, decoded_options_count);
+}
+
+/* Set *HANDLERS to the default set of option handlers for use in the
+   compilers proper (not the driver).  */
+void
+set_default_handlers (struct cl_option_handlers *handlers)
+{
+  handlers->unknown_option_callback = unknown_option_callback;
+  handlers->wrong_lang_callback = complain_wrong_lang;
+  handlers->post_handling_callback = post_handling_callback;
+  handlers->num_handlers = 3;
+  handlers->handlers[0].handler = lang_handle_option;
+  handlers->handlers[0].mask = initial_lang_mask;
+  handlers->handlers[1].handler = common_handle_option;
+  handlers->handlers[1].mask = CL_COMMON;
+  handlers->handlers[2].handler = target_handle_option;
+  handlers->handlers[2].mask = CL_TARGET;
+}
+
+/* Parse command line options and set default flag values.  Do minimal
+   options processing.  The decoded options are in *DECODED_OPTIONS
+   and *DECODED_OPTIONS_COUNT; settings go in OPTS, OPTS_SET and DC;
+   the options are located at LOC.  */
+void
+decode_options (struct gcc_options *opts, struct gcc_options *opts_set,
+		struct cl_decoded_option *decoded_options,
+		unsigned int decoded_options_count,
+		location_t loc, diagnostic_context *dc)
+{
+  struct cl_option_handlers handlers;
+
+  unsigned int lang_mask;
+
+  lang_mask = initial_lang_mask;
+
+  set_default_handlers (&handlers);
+
+  /* Enable -Werror=coverage-mismatch by default.  */
+  control_warning_option (OPT_Wcoverage_mismatch, (int) DK_ERROR, true,
+			  loc, lang_mask,
+			  &handlers, opts, opts_set, dc);
+
+  default_options_optimization (opts, opts_set,
+				decoded_options, decoded_options_count,
+				loc, lang_mask, &handlers, dc);
+
+#ifdef ENABLE_LTO
+  /* Clear any options currently held for LTO.  */
+  lto_clear_user_options ();
+#endif
+
+  read_cmdline_options (opts, opts_set,
+			decoded_options, decoded_options_count,
+			loc, lang_mask,
+			&handlers, dc);
+
+  finish_options (opts, opts_set);
+}
+
+/* Process common options that have been deferred until after the
+   handlers have been called for all options.  */
+
 void
 handle_common_deferred_options (void)
 {
Index: gcc/Makefile.in
===================================================================
--- gcc/Makefile.in	(revision 167073)
+++ gcc/Makefile.in	(working copy)
@@ -2824,13 +2824,14 @@  fold-const.o : fold-const.c $(CONFIG_H) 
 diagnostic.o : diagnostic.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
    version.h $(INPUT_H) intl.h $(DIAGNOSTIC_H) diagnostic.def
 opts.o : opts.c $(OPTS_H) $(OPTIONS_H) $(TOPLEV_H) $(DIAGNOSTIC_CORE_H) $(CONFIG_H) $(SYSTEM_H) \
-   coretypes.h $(TREE_H) $(TM_H) langhooks.h $(EXPR_H) \
-   $(DIAGNOSTIC_H) $(TM_P_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \
+   coretypes.h $(TREE_H) $(TM_H) $(RTL_H) \
+   $(DIAGNOSTIC_H) $(INSN_ATTR_H) intl.h $(TARGET_H) \
    $(FLAGS_H) $(PARAMS_H) $(DBGCNT_H) debug.h \
-   $(EXCEPT_H) $(LTO_STREAMER_H) opts-diagnostic.h
+   opts-diagnostic.h
 opts-global.o : opts-global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
-   $(DIAGNOSTIC_CORE_H) $(OPTS_H) $(FLAGS_H) $(GGC_H) $(TM_H) $(RTL_H) \
-   output.h $(PLUGIN_H) $(TREE_PASS_H)
+   $(DIAGNOSTIC_H) $(OPTS_H) $(FLAGS_H) $(GGC_H) $(TREE_H) langhooks.h \
+   $(TM_H) $(RTL_H) $(LTO_STREAMER_H) output.h $(PLUGIN_H) $(TOPLEV_H) \
+   $(TREE_PASS_H)
 opts-common.o : opts-common.c $(OPTS_H) $(FLAGS_H) $(CONFIG_H) $(SYSTEM_H) \
    coretypes.h intl.h $(DIAGNOSTIC_H) $(TM_H)
 targhooks.o : targhooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \