Patchwork Split up init_options langhook

login
register
mail settings
Submitter Joseph S. Myers
Date June 20, 2010, 8:37 p.m.
Message ID <Pine.LNX.4.64.1006202035210.2440@digraph.polyomino.org.uk>
Download mbox | patch
Permalink /patch/56274/
State New
Headers show

Comments

Joseph S. Myers - June 20, 2010, 8:37 p.m.
In <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg01856.html>, which is
pending review, I noted that the front-end init_options hooks still
took argc and argv parameters, contrary to the general principle of
converting argv into an array of cl_decoded_option structures with
logic in a single place and not referring directly to argc and argc
elsewhere.

This patch (relative to a tree with the previous patch applied)
updates the hooks so that the init_options hooks instead take decoded
options.  The lang_mask used for decoding is determined first by a
separate option_lang_mask hook; wrong-language options for
preprocessing .S files are now handled not through changing the mask
for -lang-asm but through a complain_wrong_lang_p hook to decide
whether to warn for such options, which also avoids a special case for
LTO in the core option-processing code.  Some C init_options code that
was actually diagnostic initialization is now called from the hook to
initialize diagnostics, which seems a more appropriate place.

Ada does complicated things with the original argv and argc, which it
saved in the init_options hook, as well as putting canonical forms of
various options in gnat_argv/gnat_argc in gnat_handle_option.  I'm not
clear on exactly what use it makes of each of the arrays save_argv and
gnat_argv.  With the change to init_options no longer getting argc and
argv, gnat_init_options now reconstitutes a save_argv array from the
decoded options it is passed.  I'd urge the Ada maintainers to work
out how to stop the front end from using save_argv/save_argc at all;
expecting the front end to replicate exactly the core logic for what
is an option and what is an argument is very error-prone; whatever it
needs to do should be done based on logical, decoded options instead
(option indices and arguments).  (The gnat_argv approach in
gnat_handle_option is probably safer since that only handles a very
limited subset of options and reconstitutes text based purely on
options indices and arguments with no reference to the original form
of an option or to options it does not know explicitly about.)

To enable reconstitution of options, a new field in cl_decoded_option
is added to store a canonical command-line form of an option.  Right
now this is the original form, but the "canonical" aspect will become
more relevant in future when support for option aliases is added to
the option-processing machinery.  This field was planned for when the
driver started using the common option machinery - the driver needs to
reconstitute options to process specs - but is being added earlier
than planned so that options can be reconstituted for Ada, so that the
langhooks changes can be made without also needing to fix the uses of
argv made in Ada code.

Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  OK to
commit (both <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg01856.html>
and this patch)?

2010-06-20  Joseph Myers  <joseph@codesourcery.com>

	* langhooks-def.h (lhd_init_options, LANG_HOOKS_OPTION_LANG_MASK,
	LANG_HOOKS_COMPLAIN_WRONG_LANG_P): New.
	(LANG_HOOKS_INIT_OPTIONS): Update default definition.
	(LANG_HOOKS_INITIALIZER): Add new hooks.
	* langhooks.c (lhd_init_options, lhd_complain_wrong_lang_p): New.
	* langhooks.h (struct lang_hooks): Add new hooks option_lang_mask
	and complain_wrong_lang_p.  Update init_options prototype.
	* c-objc-common.c (c_initialize_diagnostics): First call
	c_common_initialize_diagnostics.
	* c-objc-common.h (LANG_HOOKS_OPTION_LANG_MASK,
	LANG_HOOKS_COMPLAIN_WRONG_LANG_P): Define.
	* coretypes.h (struct cl_option, struct cl_decoded_option):
	Declare.
	* hooks.c (hook_uint_uint_constcharptrptr_0): Remove.
	(hook_uint_void_0): New.
	* hooks.h (hook_uint_uint_constcharptrptr_0): Remove.
	(hook_uint_void_0): New.
	* opts-common.c (decode_cmdline_option,
	decode_cmdline_options_to_array): Also fill in canonical_option
	field.
	* opts.c (complain_wrong_lang): Use langhook to determine whether
	to complain instead of special-casing LTO.
	(decode_options): Separate lang_mask determination with
	option_lang_mask hook from call of init_options hook.
	* opts.h (struct cl_decoded_option): Add canonical_option.

ada:
2010-06-20  Joseph Myers  <joseph@codesourcery.com>

	* gcc-interface/misc.c (gnat_option_lang_mask): New.
	(gnat_init_options): Update prototype.  Reconstruct argv array
	from decoded options.

c-family:
2010-06-20  Joseph Myers  <joseph@codesourcery.com>

	* c-common.h (c_common_option_lang_mask,
	c_common_initialize_diagnostics, c_common_complain_wrong_lang_p):
	New.
	(c_common_init_options): Update prototype.
	* c-opts.c (c_common_option_lang_mask): New.
	(c_common_initialize_diagnostics): Split out of
	c_common_init_options.
	(accept_all_c_family_options, c_common_complain_wrong_lang_p):
	New.
	(c_common_init_options): Update prototype.  Use decoded options in
	search for -lang-asm.

cp:
2010-06-20  Joseph Myers  <joseph@codesourcery.com>

	* cp-objcp-common.c (cxx_initialize_diagnostics): First call
	c_common_initialize_diagnostics.
	* cp-objcp-common.h (LANG_HOOKS_OPTION_LANG_MASK,
	LANG_HOOKS_COMPLAIN_WRONG_LANG_P): Define.

fortran:
2010-06-20  Joseph Myers  <joseph@codesourcery.com>

	* cpp.c (gfc_cpp_init_options): Update prototype.  Use number of
	decoded options in allocating deferred_opt.
	* cpp.h (gfc_cpp_init_options): Update prototype.
	* f95-lang.c (LANG_HOOKS_OPTION_LANG_MASK): Define.
	* gfortran.h (gfc_option_lang_mask): New.
	(gfc_init_options): Update prototype.
	* options.c (gfc_option_lang_mask): New.
	(gfc_init_options): Update prototype.  Pass new arguments to
	gfc_cpp_init_options.

java:
2010-06-20  Joseph Myers  <joseph@codesourcery.com>

	* lang.c (java_option_lang_mask): New.
	(java_init_options): Update prototype.
	(LANG_HOOKS_OPTION_LANG_MASK): Define.

lto:
2010-06-20  Joseph Myers  <joseph@codesourcery.com>

	* lto-lang.c (lto_option_lang_mask, lto_complain_wrong_lang_p):
	New.
	(lto_init_options): Update prototype.
	(LANG_HOOKS_OPTION_LANG_MASK, LANG_HOOKS_COMPLAIN_WRONG_LANG_P):
	Define.
Richard Guenther - June 22, 2010, 3:57 p.m.
On Sun, Jun 20, 2010 at 10:37 PM, Joseph S. Myers
<joseph@codesourcery.com> wrote:
> In <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg01856.html>, which is
> pending review, I noted that the front-end init_options hooks still
> took argc and argv parameters, contrary to the general principle of
> converting argv into an array of cl_decoded_option structures with
> logic in a single place and not referring directly to argc and argc
> elsewhere.
>
> This patch (relative to a tree with the previous patch applied)
> updates the hooks so that the init_options hooks instead take decoded
> options.  The lang_mask used for decoding is determined first by a
> separate option_lang_mask hook; wrong-language options for
> preprocessing .S files are now handled not through changing the mask
> for -lang-asm but through a complain_wrong_lang_p hook to decide
> whether to warn for such options, which also avoids a special case for
> LTO in the core option-processing code.  Some C init_options code that
> was actually diagnostic initialization is now called from the hook to
> initialize diagnostics, which seems a more appropriate place.
>
> Ada does complicated things with the original argv and argc, which it
> saved in the init_options hook, as well as putting canonical forms of
> various options in gnat_argv/gnat_argc in gnat_handle_option.  I'm not
> clear on exactly what use it makes of each of the arrays save_argv and
> gnat_argv.  With the change to init_options no longer getting argc and
> argv, gnat_init_options now reconstitutes a save_argv array from the
> decoded options it is passed.  I'd urge the Ada maintainers to work
> out how to stop the front end from using save_argv/save_argc at all;
> expecting the front end to replicate exactly the core logic for what
> is an option and what is an argument is very error-prone; whatever it
> needs to do should be done based on logical, decoded options instead
> (option indices and arguments).  (The gnat_argv approach in
> gnat_handle_option is probably safer since that only handles a very
> limited subset of options and reconstitutes text based purely on
> options indices and arguments with no reference to the original form
> of an option or to options it does not know explicitly about.)
>
> To enable reconstitution of options, a new field in cl_decoded_option
> is added to store a canonical command-line form of an option.  Right
> now this is the original form, but the "canonical" aspect will become
> more relevant in future when support for option aliases is added to
> the option-processing machinery.  This field was planned for when the
> driver started using the common option machinery - the driver needs to
> reconstitute options to process specs - but is being added earlier
> than planned so that options can be reconstituted for Ada, so that the
> langhooks changes can be made without also needing to fix the uses of
> argv made in Ada code.
>
> Bootstrapped with no regressions on x86_64-unknown-linux-gnu.  OK to
> commit (both <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg01856.html>
> and this patch)?

The middle-end and LTO pieces are ok.

Thanks,
Richard.

> 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
>
>        * langhooks-def.h (lhd_init_options, LANG_HOOKS_OPTION_LANG_MASK,
>        LANG_HOOKS_COMPLAIN_WRONG_LANG_P): New.
>        (LANG_HOOKS_INIT_OPTIONS): Update default definition.
>        (LANG_HOOKS_INITIALIZER): Add new hooks.
>        * langhooks.c (lhd_init_options, lhd_complain_wrong_lang_p): New.
>        * langhooks.h (struct lang_hooks): Add new hooks option_lang_mask
>        and complain_wrong_lang_p.  Update init_options prototype.
>        * c-objc-common.c (c_initialize_diagnostics): First call
>        c_common_initialize_diagnostics.
>        * c-objc-common.h (LANG_HOOKS_OPTION_LANG_MASK,
>        LANG_HOOKS_COMPLAIN_WRONG_LANG_P): Define.
>        * coretypes.h (struct cl_option, struct cl_decoded_option):
>        Declare.
>        * hooks.c (hook_uint_uint_constcharptrptr_0): Remove.
>        (hook_uint_void_0): New.
>        * hooks.h (hook_uint_uint_constcharptrptr_0): Remove.
>        (hook_uint_void_0): New.
>        * opts-common.c (decode_cmdline_option,
>        decode_cmdline_options_to_array): Also fill in canonical_option
>        field.
>        * opts.c (complain_wrong_lang): Use langhook to determine whether
>        to complain instead of special-casing LTO.
>        (decode_options): Separate lang_mask determination with
>        option_lang_mask hook from call of init_options hook.
>        * opts.h (struct cl_decoded_option): Add canonical_option.
>
> ada:
> 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
>
>        * gcc-interface/misc.c (gnat_option_lang_mask): New.
>        (gnat_init_options): Update prototype.  Reconstruct argv array
>        from decoded options.
>
> c-family:
> 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
>
>        * c-common.h (c_common_option_lang_mask,
>        c_common_initialize_diagnostics, c_common_complain_wrong_lang_p):
>        New.
>        (c_common_init_options): Update prototype.
>        * c-opts.c (c_common_option_lang_mask): New.
>        (c_common_initialize_diagnostics): Split out of
>        c_common_init_options.
>        (accept_all_c_family_options, c_common_complain_wrong_lang_p):
>        New.
>        (c_common_init_options): Update prototype.  Use decoded options in
>        search for -lang-asm.
>
> cp:
> 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
>
>        * cp-objcp-common.c (cxx_initialize_diagnostics): First call
>        c_common_initialize_diagnostics.
>        * cp-objcp-common.h (LANG_HOOKS_OPTION_LANG_MASK,
>        LANG_HOOKS_COMPLAIN_WRONG_LANG_P): Define.
>
> fortran:
> 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
>
>        * cpp.c (gfc_cpp_init_options): Update prototype.  Use number of
>        decoded options in allocating deferred_opt.
>        * cpp.h (gfc_cpp_init_options): Update prototype.
>        * f95-lang.c (LANG_HOOKS_OPTION_LANG_MASK): Define.
>        * gfortran.h (gfc_option_lang_mask): New.
>        (gfc_init_options): Update prototype.
>        * options.c (gfc_option_lang_mask): New.
>        (gfc_init_options): Update prototype.  Pass new arguments to
>        gfc_cpp_init_options.
>
> java:
> 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
>
>        * lang.c (java_option_lang_mask): New.
>        (java_init_options): Update prototype.
>        (LANG_HOOKS_OPTION_LANG_MASK): Define.
>
> lto:
> 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
>
>        * lto-lang.c (lto_option_lang_mask, lto_complain_wrong_lang_p):
>        New.
>        (lto_init_options): Update prototype.
>        (LANG_HOOKS_OPTION_LANG_MASK, LANG_HOOKS_COMPLAIN_WRONG_LANG_P):
>        Define.
>
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/ada/gcc-interface/misc.c gcc-mainline/gcc/ada/gcc-interface/misc.c
> --- gcc-mainline-opt1/gcc/ada/gcc-interface/misc.c      2010-06-08 04:18:42.000000000 -0700
> +++ gcc-mainline/gcc/ada/gcc-interface/misc.c   2010-06-20 08:17:54.000000000 -0700
> @@ -62,7 +62,9 @@
>  #include "gigi.h"
>
>  static bool gnat_init                  (void);
> -static unsigned int gnat_init_options  (unsigned int, const char **);
> +static unsigned int gnat_option_lang_mask (void);
> +static void gnat_init_options          (unsigned int,
> +                                        struct cl_decoded_option *);
>  static int gnat_handle_option          (size_t, const char *, int, int);
>  static bool gnat_post_options          (const char **);
>  static alias_set_type gnat_get_alias_set (tree);
> @@ -86,6 +88,8 @@ static tree gnat_eh_personality               (void);
>  #define LANG_HOOKS_IDENTIFIER_SIZE     sizeof (struct tree_identifier)
>  #undef  LANG_HOOKS_INIT
>  #define LANG_HOOKS_INIT                        gnat_init
> +#undef  LANG_HOOKS_OPTION_LANG_MASK
> +#define LANG_HOOKS_OPTION_LANG_MASK    gnat_option_lang_mask
>  #undef  LANG_HOOKS_INIT_OPTIONS
>  #define LANG_HOOKS_INIT_OPTIONS                gnat_init_options
>  #undef  LANG_HOOKS_HANDLE_OPTION
> @@ -276,23 +280,45 @@ gnat_handle_option (size_t scode, const
>   return 1;
>  }
>
> -/* Initialize for option processing.  */
> +/* Return language mask for option processing.  */
>
>  static unsigned int
> -gnat_init_options (unsigned int argc, const char **argv)
> +gnat_option_lang_mask (void)
> +{
> +  return CL_Ada;
> +}
> +
> +/* Initialize for option processing.  */
> +
> +static void
> +gnat_init_options (unsigned int decoded_options_count,
> +                  struct cl_decoded_option *decoded_options)
>  {
> +  /* Reconstruct an argv array for use of back_end.adb.
> +
> +     ??? back_end.adb should not rely on this; instead, it should work
> +     with decoded options without such reparsing, or with the subset
> +     of options placed in gnat_argv by gnat_handle_option, to ensure
> +     consistency in how options are decoded.  */
> +  unsigned int i;
> +
> +  save_argv = XNEWVEC (const char *, 2 * decoded_options_count + 1);
> +  save_argc = 0;
> +  for (i = 0; i < decoded_options_count; i++)
> +    {
> +      save_argv[save_argc++] = decoded_options[i].canonical_option[0];
> +      if (decoded_options[i].canonical_option[1] != NULL)
> +       save_argv[save_argc++] = decoded_options[i].canonical_option[1];
> +    }
> +  save_argv[save_argc] = NULL;
> +
>   /* Initialize gnat_argv with save_argv size.  */
> -  gnat_argv = (char **) xmalloc ((argc + 1) * sizeof (argv[0]));
> -  gnat_argv[0] = xstrdup (argv[0]);     /* name of the command */
> +  gnat_argv = (char **) xmalloc ((save_argc + 1) * sizeof (save_argv[0]));
> +  gnat_argv[0] = xstrdup (save_argv[0]);     /* name of the command */
>   gnat_argc = 1;
>
> -  save_argc = argc;
> -  save_argv = argv;
> -
>   /* Uninitialized really means uninitialized in Ada.  */
>   flag_zero_initialized_in_bss = 0;
> -
> -  return CL_Ada;
>  }
>
>  /* Post-switch processing.  */
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/c-family/c-common.h gcc-mainline/gcc/c-family/c-common.h
> --- gcc-mainline-opt1/gcc/c-family/c-common.h   2010-06-08 04:18:40.000000000 -0700
> +++ gcc-mainline/gcc/c-family/c-common.h        2010-06-20 09:11:29.000000000 -0700
> @@ -1,6 +1,6 @@
>  /* Definitions for c-common.c.
>    Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
> -   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
> +   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
>    Free Software Foundation, Inc.
>
>  This file is part of GCC.
> @@ -718,7 +718,12 @@ extern void set_compound_literal_name (t
>
>  extern tree build_va_arg (location_t, tree, tree);
>
> -extern unsigned int c_common_init_options (unsigned int, const char **);
> +struct diagnostic_context;
> +
> +extern unsigned int c_common_option_lang_mask (void);
> +extern void c_common_initialize_diagnostics (struct diagnostic_context *);
> +extern bool c_common_complain_wrong_lang_p (const struct cl_option *);
> +extern void c_common_init_options (unsigned int, struct cl_decoded_option *);
>  extern bool c_common_post_options (const char **);
>  extern bool c_common_init (void);
>  extern void c_common_finish (void);
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/c-family/c-opts.c gcc-mainline/gcc/c-family/c-opts.c
> --- gcc-mainline-opt1/gcc/c-family/c-opts.c     2010-06-10 05:56:45.000000000 -0700
> +++ gcc-mainline/gcc/c-family/c-opts.c  2010-06-20 09:07:16.000000000 -0700
> @@ -280,14 +280,19 @@ warning_as_error_callback (int option_in
>     }
>  }
>
> -/* Common initialization before parsing options.  */
> +/* Return language mask for option parsing.  */
>  unsigned int
> -c_common_init_options (unsigned int argc, const char **argv)
> +c_common_option_lang_mask (void)
>  {
>   static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX};
> -  unsigned int i, result;
> -  struct cpp_callbacks *cb;
>
> +  return lang_flags[c_language];
> +}
> +
> +/* Common diagnostics initialization.  */
> +void
> +c_common_initialize_diagnostics (diagnostic_context *context)
> +{
>   /* Register callback for warnings enabled by -Werror=.  */
>   register_warning_as_error_callback (warning_as_error_callback);
>
> @@ -297,13 +302,37 @@ c_common_init_options (unsigned int argc
>     {
>       /* By default wrap lines at 80 characters.  Is getenv
>         ("COLUMNS") preferable?  */
> -      diagnostic_line_cutoff (global_dc) = 80;
> +      diagnostic_line_cutoff (context) = 80;
>       /* By default, emit location information once for every
>         diagnostic message.  */
> -      diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
> +      diagnostic_prefixing_rule (context) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
>     }
>
> -  global_dc->opt_permissive = OPT_fpermissive;
> +  context->opt_permissive = OPT_fpermissive;
> +}
> +
> +/* Whether options from all C-family languages should be accepted
> +   quietly.  */
> +static bool accept_all_c_family_options = false;
> +
> +/* Return whether to complain about a wrong-language option.  */
> +bool
> +c_common_complain_wrong_lang_p (const struct cl_option *option)
> +{
> +  if (accept_all_c_family_options
> +      && (option->flags & c_family_lang_mask))
> +    return false;
> +
> +  return true;
> +}
> +
> +/* Common initialization before calling option handlers.  */
> +void
> +c_common_init_options (unsigned int decoded_options_count,
> +                      struct cl_decoded_option *decoded_options)
> +{
> +  unsigned int i;
> +  struct cpp_callbacks *cb;
>
>   parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89,
>                                ident_hash, line_table);
> @@ -326,23 +355,19 @@ c_common_init_options (unsigned int argc
>   /* By default, C99-like requirements for complex multiply and divide.  */
>   flag_complex_method = 2;
>
> -  deferred_opts = XNEWVEC (struct deferred_opt, argc);
> -
> -  result = lang_flags[c_language];
> +  deferred_opts = XNEWVEC (struct deferred_opt, decoded_options_count);
>
>   if (c_language == clk_c)
>     {
>       /* If preprocessing assembly language, accept any of the C-family
>         front end options since the driver may pass them through.  */
> -      for (i = 1; i < argc; i++)
> -       if (! strcmp (argv[i], "-lang-asm"))
> +      for (i = 1; i < decoded_options_count; i++)
> +       if (decoded_options[i].opt_index == OPT_lang_asm)
>          {
> -           result |= CL_C | CL_ObjC | CL_CXX | CL_ObjCXX;
> +           accept_all_c_family_options = true;
>            break;
>          }
>     }
> -
> -  return result;
>  }
>
>  /* Handle switch SCODE with argument ARG.  VALUE is true, unless no-
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/c-objc-common.c gcc-mainline/gcc/c-objc-common.c
> --- gcc-mainline-opt1/gcc/c-objc-common.c       2010-06-10 04:10:43.000000000 -0700
> +++ gcc-mainline/gcc/c-objc-common.c    2010-06-20 07:21:47.000000000 -0700
> @@ -184,8 +184,13 @@ has_c_linkage (const_tree decl ATTRIBUTE
>  void
>  c_initialize_diagnostics (diagnostic_context *context)
>  {
> -  pretty_printer *base = context->printer;
> -  c_pretty_printer *pp = XNEW (c_pretty_printer);
> +  pretty_printer *base;
> +  c_pretty_printer *pp;
> +
> +  c_common_initialize_diagnostics (context);
> +
> +  base = context->printer;
> +  pp = XNEW (c_pretty_printer);
>   memcpy (pp_base (pp), base, sizeof (pretty_printer));
>   pp_c_pretty_printer_init (pp);
>   context->printer = (pretty_printer *) pp;
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/c-objc-common.h gcc-mainline/gcc/c-objc-common.h
> --- gcc-mainline-opt1/gcc/c-objc-common.h       2009-10-07 09:35:32.000000000 -0700
> +++ gcc-mainline/gcc/c-objc-common.h    2010-06-20 09:01:25.000000000 -0700
> @@ -1,5 +1,6 @@
>  /* Language hooks common to C and ObjC front ends.
> -   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
> +   Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
> +   Free Software Foundation, Inc.
>    Contributed by Ziemowit Laski  <zlaski@apple.com>
>
>  This file is part of GCC.
> @@ -28,6 +29,10 @@ along with GCC; see the file COPYING3.
>  #define LANG_HOOKS_IDENTIFIER_SIZE C_SIZEOF_STRUCT_LANG_IDENTIFIER
>  #undef LANG_HOOKS_FINISH
>  #define LANG_HOOKS_FINISH c_common_finish
> +#undef LANG_HOOKS_OPTION_LANG_MASK
> +#define LANG_HOOKS_OPTION_LANG_MASK c_common_option_lang_mask
> +#undef LANG_HOOKS_COMPLAIN_WRONG_LANG_P
> +#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P c_common_complain_wrong_lang_p
>  #undef LANG_HOOKS_INIT_OPTIONS
>  #define LANG_HOOKS_INIT_OPTIONS c_common_init_options
>  #undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/coretypes.h gcc-mainline/gcc/coretypes.h
> --- gcc-mainline-opt1/gcc/coretypes.h   2010-06-11 02:16:45.000000000 -0700
> +++ gcc-mainline/gcc/coretypes.h        2010-06-20 09:11:08.000000000 -0700
> @@ -1,5 +1,6 @@
>  /* GCC core type declarations.
> -   Copyright (C) 2002, 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
> +   Copyright (C) 2002, 2004, 2007, 2008, 2009, 2010
> +   Free Software Foundation, Inc.
>
>  This file is part of GCC.
>
> @@ -65,6 +66,8 @@ union section;
>  typedef union section section;
>  struct cl_target_option;
>  struct cl_optimization;
> +struct cl_option;
> +struct cl_decoded_option;
>  struct gimple_seq_d;
>  typedef struct gimple_seq_d *gimple_seq;
>  typedef const struct gimple_seq_d *const_gimple_seq;
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/cp/cp-objcp-common.c gcc-mainline/gcc/cp/cp-objcp-common.c
> --- gcc-mainline-opt1/gcc/cp/cp-objcp-common.c  2010-06-08 04:18:42.000000000 -0700
> +++ gcc-mainline/gcc/cp/cp-objcp-common.c       2010-06-20 07:22:14.000000000 -0700
> @@ -129,8 +129,13 @@ cp_var_mod_type_p (tree type, tree fn)
>  void
>  cxx_initialize_diagnostics (diagnostic_context *context)
>  {
> -  pretty_printer *base = context->printer;
> -  cxx_pretty_printer *pp = XNEW (cxx_pretty_printer);
> +  pretty_printer *base;
> +  cxx_pretty_printer *pp;
> +
> +  c_common_initialize_diagnostics (context);
> +
> +  base = context->printer;
> +  pp = XNEW (cxx_pretty_printer);
>   memcpy (pp_base (pp), base, sizeof (pretty_printer));
>   pp_cxx_pretty_printer_init (pp);
>   context->printer = (pretty_printer *) pp;
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/cp/cp-objcp-common.h gcc-mainline/gcc/cp/cp-objcp-common.h
> --- gcc-mainline-opt1/gcc/cp/cp-objcp-common.h  2009-12-30 09:04:14.000000000 -0800
> +++ gcc-mainline/gcc/cp/cp-objcp-common.h       2010-06-20 09:01:45.000000000 -0700
> @@ -1,5 +1,6 @@
>  /* Language hooks common to C++ and ObjC++ front ends.
> -   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
> +   Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
> +   Free Software Foundation, Inc.
>    Contributed by Ziemowit Laski  <zlaski@apple.com>
>
>  This file is part of GCC.
> @@ -40,6 +41,10 @@ extern bool cp_function_decl_explicit_p
>  #define LANG_HOOKS_FINISH cxx_finish
>  #undef LANG_HOOKS_CLEAR_BINDING_STACK
>  #define LANG_HOOKS_CLEAR_BINDING_STACK pop_everything
> +#undef LANG_HOOKS_OPTION_LANG_MASK
> +#define LANG_HOOKS_OPTION_LANG_MASK c_common_option_lang_mask
> +#undef LANG_HOOKS_COMPLAIN_WRONG_LANG_P
> +#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P c_common_complain_wrong_lang_p
>  #undef LANG_HOOKS_INIT_OPTIONS
>  #define LANG_HOOKS_INIT_OPTIONS c_common_init_options
>  #undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/fortran/cpp.c gcc-mainline/gcc/fortran/cpp.c
> --- gcc-mainline-opt1/gcc/fortran/cpp.c 2010-06-16 09:07:29.000000000 -0700
> +++ gcc-mainline/gcc/fortran/cpp.c      2010-06-20 07:28:15.000000000 -0700
> @@ -304,8 +304,8 @@ gfc_cpp_temporary_file (void)
>  }
>
>  void
> -gfc_cpp_init_options (unsigned int argc,
> -                     const char **argv ATTRIBUTE_UNUSED)
> +gfc_cpp_init_options (unsigned int decoded_options_count,
> +                     struct cl_decoded_option *decoded_options ATTRIBUTE_UNUSED)
>  {
>   /* Do not create any objects from libcpp here. If no
>      preprocessing is requested, this would be wasted
> @@ -337,7 +337,8 @@ gfc_cpp_init_options (unsigned int argc,
>   gfc_cpp_option.prefix = NULL;
>   gfc_cpp_option.sysroot = NULL;
>
> -  gfc_cpp_option.deferred_opt = XNEWVEC (gfc_cpp_deferred_opt_t, argc);
> +  gfc_cpp_option.deferred_opt = XNEWVEC (gfc_cpp_deferred_opt_t,
> +                                        decoded_options_count);
>   gfc_cpp_option.deferred_opt_count = 0;
>  }
>
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/fortran/cpp.h gcc-mainline/gcc/fortran/cpp.h
> --- gcc-mainline-opt1/gcc/fortran/cpp.h 2010-06-16 09:07:29.000000000 -0700
> +++ gcc-mainline/gcc/fortran/cpp.h      2010-06-20 07:32:08.000000000 -0700
> @@ -1,4 +1,4 @@
> -/* Copyright (C) 2008 Free Software Foundation, Inc.
> +/* Copyright (C) 2008, 2010 Free Software Foundation, Inc.
>
>  This file is part of GCC.
>
> @@ -36,7 +36,8 @@ const char *gfc_cpp_temporary_file (void
>  void gfc_cpp_init_0 (void);
>  void gfc_cpp_init (void);
>
> -void gfc_cpp_init_options (unsigned int argc, const char **argv);
> +void gfc_cpp_init_options (unsigned int decoded_options_count,
> +                          struct cl_decoded_option *decoded_options);
>
>  int gfc_cpp_handle_option(size_t scode, const char *arg, int value);
>
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/fortran/f95-lang.c gcc-mainline/gcc/fortran/f95-lang.c
> --- gcc-mainline-opt1/gcc/fortran/f95-lang.c    2010-06-16 09:07:30.000000000 -0700
> +++ gcc-mainline/gcc/fortran/f95-lang.c 2010-06-20 07:29:41.000000000 -0700
> @@ -99,6 +99,7 @@ static void gfc_init_ts (void);
>  #undef LANG_HOOKS_NAME
>  #undef LANG_HOOKS_INIT
>  #undef LANG_HOOKS_FINISH
> +#undef LANG_HOOKS_OPTION_LANG_MASK
>  #undef LANG_HOOKS_INIT_OPTIONS
>  #undef LANG_HOOKS_HANDLE_OPTION
>  #undef LANG_HOOKS_POST_OPTIONS
> @@ -127,6 +128,7 @@ static void gfc_init_ts (void);
>  #define LANG_HOOKS_NAME                 "GNU Fortran"
>  #define LANG_HOOKS_INIT                 gfc_init
>  #define LANG_HOOKS_FINISH               gfc_finish
> +#define LANG_HOOKS_OPTION_LANG_MASK    gfc_option_lang_mask
>  #define LANG_HOOKS_INIT_OPTIONS         gfc_init_options
>  #define LANG_HOOKS_HANDLE_OPTION        gfc_handle_option
>  #define LANG_HOOKS_POST_OPTIONS                gfc_post_options
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/fortran/gfortran.h gcc-mainline/gcc/fortran/gfortran.h
> --- gcc-mainline-opt1/gcc/fortran/gfortran.h    2010-06-16 09:07:29.000000000 -0700
> +++ gcc-mainline/gcc/fortran/gfortran.h 2010-06-20 07:33:00.000000000 -0700
> @@ -2342,7 +2342,9 @@ void gfc_done_2 (void);
>  int get_c_kind (const char *, CInteropKind_t *);
>
>  /* options.c */
> -unsigned int gfc_init_options (unsigned int, const char **);
> +unsigned int gfc_option_lang_mask (void);
> +void gfc_init_options (unsigned int,
> +                      struct cl_decoded_option *);
>  int gfc_handle_option (size_t, const char *, int, int);
>  bool gfc_post_options (const char **);
>
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/fortran/options.c gcc-mainline/gcc/fortran/options.c
> --- gcc-mainline-opt1/gcc/fortran/options.c     2010-06-17 08:49:25.000000000 -0700
> +++ gcc-mainline/gcc/fortran/options.c  2010-06-20 07:25:46.000000000 -0700
> @@ -53,11 +53,21 @@ set_default_std_flags (void)
>  }
>
>
> +/* Return language mask for Fortran options.  */
> +
> +unsigned int
> +gfc_option_lang_mask (void)
> +{
> +  return CL_Fortran;
> +}
> +
> +
>  /* Get ready for options handling. Keep in sync with
>    libgfortran/runtime/compile_options.c (init_compile_options). */
>
> -unsigned int
> -gfc_init_options (unsigned int argc, const char **argv)
> +void
> +gfc_init_options (unsigned int decoded_options_count,
> +                 struct cl_decoded_option *decoded_options)
>  {
>   gfc_source_file = NULL;
>   gfc_option.module_dir = NULL;
> @@ -143,9 +153,7 @@ gfc_init_options (unsigned int argc, con
>   flag_short_enums = targetm.default_short_enums ();
>
>   /* Initialize cpp-related options.  */
> -  gfc_cpp_init_options(argc, argv);
> -
> -  return CL_Fortran;
> +  gfc_cpp_init_options (decoded_options_count, decoded_options);
>  }
>
>
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/hooks.c gcc-mainline/gcc/hooks.c
> --- gcc-mainline-opt1/gcc/hooks.c       2010-05-19 14:30:26.000000000 -0700
> +++ gcc-mainline/gcc/hooks.c    2010-06-20 06:38:02.000000000 -0700
> @@ -1,5 +1,5 @@
>  /* General-purpose hooks.
> -   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009
> +   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
>    Free Software Foundation, Inc.
>
>    This program is free software; you can redistribute it and/or modify it
> @@ -176,8 +176,7 @@ hook_int_size_t_constcharptr_int_0 (size
>  }
>
>  unsigned int
> -hook_uint_uint_constcharptrptr_0 (unsigned int a ATTRIBUTE_UNUSED,
> -                                 const char **b ATTRIBUTE_UNUSED)
> +hook_uint_void_0 (void)
>  {
>   return 0;
>  }
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/hooks.h gcc-mainline/gcc/hooks.h
> --- gcc-mainline-opt1/gcc/hooks.h       2010-05-19 14:30:26.000000000 -0700
> +++ gcc-mainline/gcc/hooks.h    2010-06-20 09:05:54.000000000 -0700
> @@ -1,5 +1,5 @@
>  /* General-purpose hooks.
> -   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009
> +   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
>    Free Software Foundation, Inc.
>
>    This program is free software; you can redistribute it and/or modify it
> @@ -73,7 +73,7 @@ extern tree hook_tree_tree_tree_tree_nul
>  extern tree hook_tree_tree_tree_tree_3rd_identity (tree, tree, tree);
>  extern tree hook_tree_tree_int_treep_bool_null (tree, int, tree *, bool);
>
> -extern unsigned hook_uint_uint_constcharptrptr_0 (unsigned, const char **);
> +extern unsigned hook_uint_void_0 (void);
>
>  extern bool default_can_output_mi_thunk_no_vcall (const_tree, HOST_WIDE_INT,
>                                                  HOST_WIDE_INT, const_tree);
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/java/lang.c gcc-mainline/gcc/java/lang.c
> --- gcc-mainline-opt1/gcc/java/lang.c   2010-05-26 06:39:14.000000000 -0700
> +++ gcc-mainline/gcc/java/lang.c        2010-06-20 07:49:25.000000000 -0700
> @@ -47,7 +47,8 @@ The Free Software Foundation is independ
>
>  static bool java_init (void);
>  static void java_finish (void);
> -static unsigned int java_init_options (unsigned int, const char **);
> +static unsigned int java_option_lang_mask (void);
> +static void java_init_options (unsigned int, struct cl_decoded_option *);
>  static bool java_post_options (const char **);
>
>  static int java_handle_option (size_t scode, const char *arg, int value, int kind);
> @@ -122,6 +123,8 @@ struct GTY(()) language_function {
>  #define LANG_HOOKS_INIT java_init
>  #undef LANG_HOOKS_FINISH
>  #define LANG_HOOKS_FINISH java_finish
> +#undef LANG_HOOKS_OPTION_LANG_MASK
> +#define LANG_HOOKS_OPTION_LANG_MASK java_option_lang_mask
>  #undef LANG_HOOKS_INIT_OPTIONS
>  #define LANG_HOOKS_INIT_OPTIONS java_init_options
>  #undef LANG_HOOKS_HANDLE_OPTION
> @@ -526,8 +529,14 @@ lang_init_source (int level)
>  }
>
>  static unsigned int
> -java_init_options (unsigned int argc ATTRIBUTE_UNUSED,
> -                  const char **argv ATTRIBUTE_UNUSED)
> +java_option_lang_mask (void)
> +{
> +  return CL_Java;
> +}
> +
> +static void
> +java_init_options (unsigned int decoded_options_count ATTRIBUTE_UNUSED,
> +                  struct cl_decoded_option *decoded_options ATTRIBUTE_UNUSED)
>  {
>   flag_bounds_check = 1;
>   flag_exceptions = 1;
> @@ -543,8 +552,6 @@ java_init_options (unsigned int argc ATT
>   flag_evaluation_order = 1;
>
>   jcf_path_init ();
> -
> -  return CL_Java;
>  }
>
>  /* Post-switch processing.  */
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/langhooks-def.h gcc-mainline/gcc/langhooks-def.h
> --- gcc-mainline-opt1/gcc/langhooks-def.h       2010-06-16 09:07:33.000000000 -0700
> +++ gcc-mainline/gcc/langhooks-def.h    2010-06-20 09:11:46.000000000 -0700
> @@ -1,5 +1,5 @@
>  /* Default macros to initialize the lang_hooks data structure.
> -   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
> +   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
>    Free Software Foundation, Inc.
>    Contributed by Alexandre Oliva  <aoliva@redhat.com>
>
> @@ -66,6 +66,9 @@ extern tree lhd_builtin_function (tree);
>
>  /* Declarations of default tree inlining hooks.  */
>  extern void lhd_initialize_diagnostics (struct diagnostic_context *);
> +extern void lhd_init_options (unsigned int,
> +                             struct cl_decoded_option *);
> +extern bool lhd_complain_wrong_lang_p (const struct cl_option *);
>  extern tree lhd_callgraph_analyze_expr (tree *, int *);
>
>
> @@ -82,8 +85,10 @@ extern void lhd_omp_firstprivatize_type_
>  #define LANG_HOOKS_INIT                        hook_bool_void_false
>  #define LANG_HOOKS_FINISH              lhd_do_nothing
>  #define LANG_HOOKS_PARSE_FILE          lhd_do_nothing_i
> -#define LANG_HOOKS_INIT_OPTIONS                hook_uint_uint_constcharptrptr_0
> +#define LANG_HOOKS_OPTION_LANG_MASK    hook_uint_void_0
> +#define LANG_HOOKS_INIT_OPTIONS                lhd_init_options
>  #define LANG_HOOKS_INITIALIZE_DIAGNOSTICS lhd_initialize_diagnostics
> +#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lhd_complain_wrong_lang_p
>  #define LANG_HOOKS_HANDLE_OPTION       hook_int_size_t_constcharptr_int_0
>  #define LANG_HOOKS_MISSING_ARGUMENT    hook_bool_constcharptr_size_t_false
>  #define LANG_HOOKS_POST_OPTIONS                lhd_post_options
> @@ -257,8 +262,10 @@ extern void lhd_end_section (void);
>   LANG_HOOKS_IDENTIFIER_SIZE, \
>   LANG_HOOKS_FREE_LANG_DATA, \
>   LANG_HOOKS_TREE_SIZE, \
> +  LANG_HOOKS_OPTION_LANG_MASK, \
>   LANG_HOOKS_INIT_OPTIONS, \
>   LANG_HOOKS_INITIALIZE_DIAGNOSTICS, \
> +  LANG_HOOKS_COMPLAIN_WRONG_LANG_P, \
>   LANG_HOOKS_HANDLE_OPTION, \
>   LANG_HOOKS_MISSING_ARGUMENT, \
>   LANG_HOOKS_POST_OPTIONS, \
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/langhooks.c gcc-mainline/gcc/langhooks.c
> --- gcc-mainline-opt1/gcc/langhooks.c   2010-05-24 06:14:24.000000000 -0700
> +++ gcc-mainline/gcc/langhooks.c        2010-06-20 08:41:42.000000000 -0700
> @@ -337,6 +337,20 @@ lhd_initialize_diagnostics (struct diagn
>  {
>  }
>
> +/* Called to perform language-specific options initialization.  */
> +void
> +lhd_init_options (unsigned int decoded_options_count ATTRIBUTE_UNUSED,
> +                 struct cl_decoded_option *decoded_options ATTRIBUTE_UNUSED)
> +{
> +}
> +
> +/* By default, always complain about options for the wrong language.  */
> +bool
> +lhd_complain_wrong_lang_p (const struct cl_option *option ATTRIBUTE_UNUSED)
> +{
> +  return true;
> +}
> +
>  /* The default function to print out name of current function that caused
>    an error.  */
>  void
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/langhooks.h gcc-mainline/gcc/langhooks.h
> --- gcc-mainline-opt1/gcc/langhooks.h   2010-06-16 09:07:33.000000000 -0700
> +++ gcc-mainline/gcc/langhooks.h        2010-06-20 09:11:57.000000000 -0700
> @@ -1,5 +1,5 @@
>  /* The lang_hooks data structure.
> -   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
> +   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
>    Free Software Foundation, Inc.
>
>  This file is part of GCC.
> @@ -269,15 +269,24 @@ struct lang_hooks
>      on unrecognized codes.  */
>   size_t (*tree_size) (enum tree_code);
>
> -  /* The first callback made to the front end, for simple
> -     initialization needed before any calls to handle_option.  Return
> -     the language mask to filter the switch array with.  */
> -  unsigned int (*init_options) (unsigned int argc, const char **argv);
> +  /* Return the language mask used for converting argv into a sequence
> +     of options.  */
> +  unsigned int (*option_lang_mask) (void);
> +
> +  /* After the initialize_diagnostics hook is called, do any simple
> +     initialization needed before any calls to handle_option.  */
> +  void (*init_options) (unsigned int decoded_options_count,
> +                       struct cl_decoded_option *decoded_options);
>
>   /* Callback used to perform language-specific initialization for the
>      global diagnostic context structure.  */
>   void (*initialize_diagnostics) (struct diagnostic_context *);
>
> +  /* Return true if a warning should be given about option OPTION,
> +     which is for the wrong language, false if it should be quietly
> +     ignored.  */
> +  bool (*complain_wrong_lang_p) (const struct cl_option *option);
> +
>   /* Handle the switch CODE, which has real type enum opt_code from
>      options.h.  If the switch takes an argument, it is passed in ARG
>      which points to permanent storage.  The handler is responsible for
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/lto/lto-lang.c gcc-mainline/gcc/lto/lto-lang.c
> --- gcc-mainline-opt1/gcc/lto/lto-lang.c        2010-06-07 05:37:01.000000000 -0700
> +++ gcc-mainline/gcc/lto/lto-lang.c     2010-06-20 09:03:38.000000000 -0700
> @@ -594,16 +594,34 @@ static GTY(()) tree registered_builtin_f
>  /* Language hooks.  */
>
>  static unsigned int
> -lto_init_options (unsigned int argc ATTRIBUTE_UNUSED,
> -                 const char **argv ATTRIBUTE_UNUSED)
> +lto_option_lang_mask (void)
> +{
> +  return CL_LTO;
> +}
> +
> +static bool
> +lto_complain_wrong_lang_p (const struct cl_option *option ATTRIBUTE_UNUSED)
> +{
> +  /* The LTO front end inherits all the options from the first front
> +     end that was used.  However, not all the original front end
> +     options make sense in LTO.
> +
> +     A real solution would be to filter this in collect2, but collect2
> +     does not have access to all the option attributes to know what to
> +     filter.  So, in lto1 we silently accept inherited flags and do
> +     nothing about it.  */
> +  return false;
> +}
> +
> +static void
> +lto_init_options (unsigned int decoded_options_count ATTRIBUTE_UNUSED,
> +                 struct cl_decoded_option *decoded_options ATTRIBUTE_UNUSED)
>  {
>   /* By default, C99-like requirements for complex multiply and divide.
>      ???  Until the complex method is encoded in the IL this is the only
>      safe choice.  This will pessimize Fortran code with LTO unless
>      people specify a complex method manually or use -ffast-math.  */
>   flag_complex_method = 2;
> -
> -  return CL_LTO;
>  }
>
>  /* Handle command-line option SCODE.  If the option takes an argument, it is
> @@ -1115,6 +1133,10 @@ static void lto_init_ts (void)
>
>  #undef LANG_HOOKS_NAME
>  #define LANG_HOOKS_NAME "GNU GIMPLE"
> +#undef LANG_HOOKS_OPTION_LANG_MASK
> +#define LANG_HOOKS_OPTION_LANG_MASK lto_option_lang_mask
> +#undef LANG_HOOKS_COMPLAIN_WRONG_LANG_P
> +#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lto_complain_wrong_lang_p
>  #undef LANG_HOOKS_INIT_OPTIONS
>  #define LANG_HOOKS_INIT_OPTIONS lto_init_options
>  #undef LANG_HOOKS_HANDLE_OPTION
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/opts-common.c gcc-mainline/gcc/opts-common.c
> --- gcc-mainline-opt1/gcc/opts-common.c 2010-06-18 03:12:32.000000000 -0700
> +++ gcc-mainline/gcc/opts-common.c      2010-06-20 08:03:58.000000000 -0700
> @@ -245,10 +245,14 @@ decode_cmdline_option (const char **argv
>     {
>     case 1:
>       decoded->orig_option_with_args_text = argv[0];
> +      decoded->canonical_option[0] = argv[0];
> +      decoded->canonical_option[1] = NULL;
>       break;
>     case 2:
>       decoded->orig_option_with_args_text = concat (argv[0], " ",
>                                                    argv[1], NULL);
> +      decoded->canonical_option[0] = argv[0];
> +      decoded->canonical_option[1] = argv[1];
>       break;
>     default:
>       gcc_unreachable ();
> @@ -279,6 +283,8 @@ decode_cmdline_options_to_array (unsigne
>   opt_array[0].opt_index = OPT_SPECIAL_program_name;
>   opt_array[0].arg = argv[0];
>   opt_array[0].orig_option_with_args_text = argv[0];
> +  opt_array[0].canonical_option[0] = argv[0];
> +  opt_array[0].canonical_option[1] = NULL;
>   opt_array[0].value = 1;
>   opt_array[0].errors = 0;
>   num_decoded_options = 1;
> @@ -293,6 +299,8 @@ decode_cmdline_options_to_array (unsigne
>          opt_array[num_decoded_options].opt_index = OPT_SPECIAL_input_file;
>          opt_array[num_decoded_options].arg = opt;
>          opt_array[num_decoded_options].orig_option_with_args_text = opt;
> +         opt_array[num_decoded_options].canonical_option[0] = opt;
> +         opt_array[num_decoded_options].canonical_option[1] = NULL;
>          opt_array[num_decoded_options].value = 1;
>          opt_array[num_decoded_options].errors = 0;
>          num_decoded_options++;
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/opts.c gcc-mainline/gcc/opts.c
> --- gcc-mainline-opt1/gcc/opts.c        2010-06-17 14:44:07.000000000 -0700
> +++ gcc-mainline/gcc/opts.c     2010-06-20 09:02:58.000000000 -0700
> @@ -416,15 +416,7 @@ complain_wrong_lang (const char *text, c
>  {
>   char *ok_langs, *bad_lang;
>
> -  /* The LTO front end inherits all the options from the first front
> -     end that was used.  However, not all the original front end
> -     options make sense in LTO.
> -
> -     A real solution would be to filter this in collect2, but collect2
> -     does not have access to all the option attributes to know what to
> -     filter.  So, in lto1 we silently accept inherited flags and do
> -     nothing about it.  */
> -  if (lang_mask & CL_LTO)
> +  if (!lang_hooks.complain_wrong_lang_p (option))
>     return;
>
>   ok_langs = write_langs (option->flags);
> @@ -715,7 +707,7 @@ decode_options (unsigned int argc, const
>   if (first_time_p)
>     {
>       /* Perform language-specific options initialization.  */
> -      initial_lang_mask = lang_mask = lang_hooks.init_options (argc, argv);
> +      initial_lang_mask = lang_mask = lang_hooks.option_lang_mask ();
>
>       lang_hooks.initialize_diagnostics (global_dc);
>
> @@ -732,6 +724,9 @@ decode_options (unsigned int argc, const
>
>   decode_cmdline_options_to_array (argc, argv, lang_mask,
>                                   decoded_options, decoded_options_count);
> +  if (first_time_p)
> +    /* Perform language-specific options initialization.  */
> +    lang_hooks.init_options (*decoded_options_count, *decoded_options);
>
>   /* Scan to see what optimization level has been specified.  That will
>      determine the default value of many flags.  */
> diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/opts.h gcc-mainline/gcc/opts.h
> --- gcc-mainline-opt1/gcc/opts.h        2010-06-17 16:56:25.000000000 -0700
> +++ gcc-mainline/gcc/opts.h     2010-06-20 08:02:11.000000000 -0700
> @@ -117,6 +117,14 @@ struct cl_decoded_option
>      -frecord-gcc-switches.  */
>   const char *orig_option_with_args_text;
>
> +  /* The canonical form of the option and its argument, for when it is
> +     necessary to reconstruct argv elements (in particular, for
> +     processing specs and passing options to subprocesses from the
> +     driver).  The first element of this array is non-NULL; the second
> +     is NULL if the canonical form uses only one argv element,
> +     non-NULL otherwise.  */
> +  const char *canonical_option[2];
> +
>   /* For a boolean option, 1 for the true case and 0 for the "no-"
>      case.  For an unsigned integer option, the value of the
>      argument.  1 in all other cases.  */
>
> --
> Joseph S. Myers
> joseph@codesourcery.com
>
Joseph S. Myers - June 22, 2010, 4:11 p.m.
On Tue, 22 Jun 2010, Richard Guenther wrote:

> The middle-end and LTO pieces are ok.

Thanks.  This patch 
<http://gcc.gnu.org/ml/gcc-patches/2010-06/msg01968.html> still needs 
review of the Ada, C++, Fortran and Java pieces.

> > ada:
> > 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
> >
> >        * gcc-interface/misc.c (gnat_option_lang_mask): New.
> >        (gnat_init_options): Update prototype.  Reconstruct argv array
> >        from decoded options.

> > cp:
> > 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
> >
> >        * cp-objcp-common.c (cxx_initialize_diagnostics): First call
> >        c_common_initialize_diagnostics.
> >        * cp-objcp-common.h (LANG_HOOKS_OPTION_LANG_MASK,
> >        LANG_HOOKS_COMPLAIN_WRONG_LANG_P): Define.

> > fortran:
> > 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
> >
> >        * cpp.c (gfc_cpp_init_options): Update prototype.  Use number of
> >        decoded options in allocating deferred_opt.
> >        * cpp.h (gfc_cpp_init_options): Update prototype.
> >        * f95-lang.c (LANG_HOOKS_OPTION_LANG_MASK): Define.
> >        * gfortran.h (gfc_option_lang_mask): New.
> >        (gfc_init_options): Update prototype.
> >        * options.c (gfc_option_lang_mask): New.
> >        (gfc_init_options): Update prototype.  Pass new arguments to
> >        gfc_cpp_init_options.

> > java:
> > 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
> >
> >        * lang.c (java_option_lang_mask): New.
> >        (java_init_options): Update prototype.
> >        (LANG_HOOKS_OPTION_LANG_MASK): Define.
Tom Tromey - June 22, 2010, 4:49 p.m.
>>>>> "Joseph" == Joseph S Myers <joseph@codesourcery.com> writes:

Joseph> Thanks.  This patch 
Joseph> <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg01968.html> still needs 
Joseph> review of the Ada, C++, Fortran and Java pieces.

The Java parts are ok, thanks.

Tom
Tobias Burnus - June 22, 2010, 8:50 p.m.
Joseph S. Myers wrote:
>> The middle-end and LTO pieces are ok.
>>     
> Thanks.  This patch 
> <http://gcc.gnu.org/ml/gcc-patches/2010-06/msg01968.html> still needs 
> review of the Ada, C++, Fortran and Java pieces.

The Fortran part of the patch is OK. Thanks for the cleanup!

Tobias

>>> fortran:
>>> 2010-06-20  Joseph Myers  <joseph@codesourcery.com>
>>>
>>>        * cpp.c (gfc_cpp_init_options): Update prototype.  Use number of
>>>        decoded options in allocating deferred_opt.
>>>        * cpp.h (gfc_cpp_init_options): Update prototype.
>>>        * f95-lang.c (LANG_HOOKS_OPTION_LANG_MASK): Define.
>>>        * gfortran.h (gfc_option_lang_mask): New.
>>>        (gfc_init_options): Update prototype.
>>>        * options.c (gfc_option_lang_mask): New.
>>>        (gfc_init_options): Update prototype.  Pass new arguments to
>>>        gfc_cpp_init_options

Patch

diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/ada/gcc-interface/misc.c gcc-mainline/gcc/ada/gcc-interface/misc.c
--- gcc-mainline-opt1/gcc/ada/gcc-interface/misc.c	2010-06-08 04:18:42.000000000 -0700
+++ gcc-mainline/gcc/ada/gcc-interface/misc.c	2010-06-20 08:17:54.000000000 -0700
@@ -62,7 +62,9 @@ 
 #include "gigi.h"
 
 static bool gnat_init			(void);
-static unsigned int gnat_init_options	(unsigned int, const char **);
+static unsigned int gnat_option_lang_mask (void);
+static void gnat_init_options		(unsigned int,
+					 struct cl_decoded_option *);
 static int gnat_handle_option		(size_t, const char *, int, int);
 static bool gnat_post_options		(const char **);
 static alias_set_type gnat_get_alias_set (tree);
@@ -86,6 +88,8 @@  static tree gnat_eh_personality		(void);
 #define LANG_HOOKS_IDENTIFIER_SIZE	sizeof (struct tree_identifier)
 #undef  LANG_HOOKS_INIT
 #define LANG_HOOKS_INIT			gnat_init
+#undef  LANG_HOOKS_OPTION_LANG_MASK
+#define LANG_HOOKS_OPTION_LANG_MASK	gnat_option_lang_mask
 #undef  LANG_HOOKS_INIT_OPTIONS
 #define LANG_HOOKS_INIT_OPTIONS		gnat_init_options
 #undef  LANG_HOOKS_HANDLE_OPTION
@@ -276,23 +280,45 @@  gnat_handle_option (size_t scode, const 
   return 1;
 }
 
-/* Initialize for option processing.  */
+/* Return language mask for option processing.  */
 
 static unsigned int
-gnat_init_options (unsigned int argc, const char **argv)
+gnat_option_lang_mask (void)
+{
+  return CL_Ada;
+}
+
+/* Initialize for option processing.  */
+
+static void
+gnat_init_options (unsigned int decoded_options_count,
+		   struct cl_decoded_option *decoded_options)
 {
+  /* Reconstruct an argv array for use of back_end.adb.
+
+     ??? back_end.adb should not rely on this; instead, it should work
+     with decoded options without such reparsing, or with the subset
+     of options placed in gnat_argv by gnat_handle_option, to ensure
+     consistency in how options are decoded.  */
+  unsigned int i;
+
+  save_argv = XNEWVEC (const char *, 2 * decoded_options_count + 1);
+  save_argc = 0;
+  for (i = 0; i < decoded_options_count; i++)
+    {
+      save_argv[save_argc++] = decoded_options[i].canonical_option[0];
+      if (decoded_options[i].canonical_option[1] != NULL)
+	save_argv[save_argc++] = decoded_options[i].canonical_option[1];
+    }
+  save_argv[save_argc] = NULL;
+
   /* Initialize gnat_argv with save_argv size.  */
-  gnat_argv = (char **) xmalloc ((argc + 1) * sizeof (argv[0]));
-  gnat_argv[0] = xstrdup (argv[0]);     /* name of the command */
+  gnat_argv = (char **) xmalloc ((save_argc + 1) * sizeof (save_argv[0]));
+  gnat_argv[0] = xstrdup (save_argv[0]);     /* name of the command */
   gnat_argc = 1;
 
-  save_argc = argc;
-  save_argv = argv;
-
   /* Uninitialized really means uninitialized in Ada.  */
   flag_zero_initialized_in_bss = 0;
-
-  return CL_Ada;
 }
 
 /* Post-switch processing.  */
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/c-family/c-common.h gcc-mainline/gcc/c-family/c-common.h
--- gcc-mainline-opt1/gcc/c-family/c-common.h	2010-06-08 04:18:40.000000000 -0700
+++ gcc-mainline/gcc/c-family/c-common.h	2010-06-20 09:11:29.000000000 -0700
@@ -1,6 +1,6 @@ 
 /* Definitions for c-common.c.
    Copyright (C) 1987, 1993, 1994, 1995, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -718,7 +718,12 @@  extern void set_compound_literal_name (t
 
 extern tree build_va_arg (location_t, tree, tree);
 
-extern unsigned int c_common_init_options (unsigned int, const char **);
+struct diagnostic_context;
+
+extern unsigned int c_common_option_lang_mask (void);
+extern void c_common_initialize_diagnostics (struct diagnostic_context *);
+extern bool c_common_complain_wrong_lang_p (const struct cl_option *);
+extern void c_common_init_options (unsigned int, struct cl_decoded_option *);
 extern bool c_common_post_options (const char **);
 extern bool c_common_init (void);
 extern void c_common_finish (void);
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/c-family/c-opts.c gcc-mainline/gcc/c-family/c-opts.c
--- gcc-mainline-opt1/gcc/c-family/c-opts.c	2010-06-10 05:56:45.000000000 -0700
+++ gcc-mainline/gcc/c-family/c-opts.c	2010-06-20 09:07:16.000000000 -0700
@@ -280,14 +280,19 @@  warning_as_error_callback (int option_in
     }
 }
 
-/* Common initialization before parsing options.  */
+/* Return language mask for option parsing.  */
 unsigned int
-c_common_init_options (unsigned int argc, const char **argv)
+c_common_option_lang_mask (void)
 {
   static const unsigned int lang_flags[] = {CL_C, CL_ObjC, CL_CXX, CL_ObjCXX};
-  unsigned int i, result;
-  struct cpp_callbacks *cb;
 
+  return lang_flags[c_language];
+}
+
+/* Common diagnostics initialization.  */
+void
+c_common_initialize_diagnostics (diagnostic_context *context)
+{
   /* Register callback for warnings enabled by -Werror=.  */
   register_warning_as_error_callback (warning_as_error_callback);
 
@@ -297,13 +302,37 @@  c_common_init_options (unsigned int argc
     {
       /* By default wrap lines at 80 characters.  Is getenv
 	 ("COLUMNS") preferable?  */
-      diagnostic_line_cutoff (global_dc) = 80;
+      diagnostic_line_cutoff (context) = 80;
       /* By default, emit location information once for every
 	 diagnostic message.  */
-      diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
+      diagnostic_prefixing_rule (context) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
     }
 
-  global_dc->opt_permissive = OPT_fpermissive;
+  context->opt_permissive = OPT_fpermissive;
+}
+
+/* Whether options from all C-family languages should be accepted
+   quietly.  */
+static bool accept_all_c_family_options = false;
+
+/* Return whether to complain about a wrong-language option.  */
+bool
+c_common_complain_wrong_lang_p (const struct cl_option *option)
+{
+  if (accept_all_c_family_options
+      && (option->flags & c_family_lang_mask))
+    return false;
+
+  return true;
+}
+
+/* Common initialization before calling option handlers.  */
+void
+c_common_init_options (unsigned int decoded_options_count,
+		       struct cl_decoded_option *decoded_options)
+{
+  unsigned int i;
+  struct cpp_callbacks *cb;
 
   parse_in = cpp_create_reader (c_dialect_cxx () ? CLK_GNUCXX: CLK_GNUC89,
 				ident_hash, line_table);
@@ -326,23 +355,19 @@  c_common_init_options (unsigned int argc
   /* By default, C99-like requirements for complex multiply and divide.  */
   flag_complex_method = 2;
 
-  deferred_opts = XNEWVEC (struct deferred_opt, argc);
-
-  result = lang_flags[c_language];
+  deferred_opts = XNEWVEC (struct deferred_opt, decoded_options_count);
 
   if (c_language == clk_c)
     {
       /* If preprocessing assembly language, accept any of the C-family
 	 front end options since the driver may pass them through.  */
-      for (i = 1; i < argc; i++)
-	if (! strcmp (argv[i], "-lang-asm"))
+      for (i = 1; i < decoded_options_count; i++)
+	if (decoded_options[i].opt_index == OPT_lang_asm)
 	  {
-	    result |= CL_C | CL_ObjC | CL_CXX | CL_ObjCXX;
+	    accept_all_c_family_options = true;
 	    break;
 	  }
     }
-
-  return result;
 }
 
 /* Handle switch SCODE with argument ARG.  VALUE is true, unless no-
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/c-objc-common.c gcc-mainline/gcc/c-objc-common.c
--- gcc-mainline-opt1/gcc/c-objc-common.c	2010-06-10 04:10:43.000000000 -0700
+++ gcc-mainline/gcc/c-objc-common.c	2010-06-20 07:21:47.000000000 -0700
@@ -184,8 +184,13 @@  has_c_linkage (const_tree decl ATTRIBUTE
 void
 c_initialize_diagnostics (diagnostic_context *context)
 {
-  pretty_printer *base = context->printer;
-  c_pretty_printer *pp = XNEW (c_pretty_printer);
+  pretty_printer *base;
+  c_pretty_printer *pp;
+
+  c_common_initialize_diagnostics (context);
+
+  base = context->printer;
+  pp = XNEW (c_pretty_printer);
   memcpy (pp_base (pp), base, sizeof (pretty_printer));
   pp_c_pretty_printer_init (pp);
   context->printer = (pretty_printer *) pp;
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/c-objc-common.h gcc-mainline/gcc/c-objc-common.h
--- gcc-mainline-opt1/gcc/c-objc-common.h	2009-10-07 09:35:32.000000000 -0700
+++ gcc-mainline/gcc/c-objc-common.h	2010-06-20 09:01:25.000000000 -0700
@@ -1,5 +1,6 @@ 
 /* Language hooks common to C and ObjC front ends.
-   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
    Contributed by Ziemowit Laski  <zlaski@apple.com>
 
 This file is part of GCC.
@@ -28,6 +29,10 @@  along with GCC; see the file COPYING3.  
 #define LANG_HOOKS_IDENTIFIER_SIZE C_SIZEOF_STRUCT_LANG_IDENTIFIER
 #undef LANG_HOOKS_FINISH
 #define LANG_HOOKS_FINISH c_common_finish
+#undef LANG_HOOKS_OPTION_LANG_MASK
+#define LANG_HOOKS_OPTION_LANG_MASK c_common_option_lang_mask
+#undef LANG_HOOKS_COMPLAIN_WRONG_LANG_P
+#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P c_common_complain_wrong_lang_p
 #undef LANG_HOOKS_INIT_OPTIONS
 #define LANG_HOOKS_INIT_OPTIONS c_common_init_options
 #undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/coretypes.h gcc-mainline/gcc/coretypes.h
--- gcc-mainline-opt1/gcc/coretypes.h	2010-06-11 02:16:45.000000000 -0700
+++ gcc-mainline/gcc/coretypes.h	2010-06-20 09:11:08.000000000 -0700
@@ -1,5 +1,6 @@ 
 /* GCC core type declarations.
-   Copyright (C) 2002, 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2004, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -65,6 +66,8 @@  union section;
 typedef union section section;
 struct cl_target_option;
 struct cl_optimization;
+struct cl_option;
+struct cl_decoded_option;
 struct gimple_seq_d;
 typedef struct gimple_seq_d *gimple_seq;
 typedef const struct gimple_seq_d *const_gimple_seq;
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/cp/cp-objcp-common.c gcc-mainline/gcc/cp/cp-objcp-common.c
--- gcc-mainline-opt1/gcc/cp/cp-objcp-common.c	2010-06-08 04:18:42.000000000 -0700
+++ gcc-mainline/gcc/cp/cp-objcp-common.c	2010-06-20 07:22:14.000000000 -0700
@@ -129,8 +129,13 @@  cp_var_mod_type_p (tree type, tree fn)
 void
 cxx_initialize_diagnostics (diagnostic_context *context)
 {
-  pretty_printer *base = context->printer;
-  cxx_pretty_printer *pp = XNEW (cxx_pretty_printer);
+  pretty_printer *base;
+  cxx_pretty_printer *pp;
+
+  c_common_initialize_diagnostics (context);
+
+  base = context->printer;
+  pp = XNEW (cxx_pretty_printer);
   memcpy (pp_base (pp), base, sizeof (pretty_printer));
   pp_cxx_pretty_printer_init (pp);
   context->printer = (pretty_printer *) pp;
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/cp/cp-objcp-common.h gcc-mainline/gcc/cp/cp-objcp-common.h
--- gcc-mainline-opt1/gcc/cp/cp-objcp-common.h	2009-12-30 09:04:14.000000000 -0800
+++ gcc-mainline/gcc/cp/cp-objcp-common.h	2010-06-20 09:01:45.000000000 -0700
@@ -1,5 +1,6 @@ 
 /* Language hooks common to C++ and ObjC++ front ends.
-   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2007, 2008, 2009, 2010
+   Free Software Foundation, Inc.
    Contributed by Ziemowit Laski  <zlaski@apple.com>
 
 This file is part of GCC.
@@ -40,6 +41,10 @@  extern bool cp_function_decl_explicit_p 
 #define LANG_HOOKS_FINISH cxx_finish
 #undef LANG_HOOKS_CLEAR_BINDING_STACK
 #define LANG_HOOKS_CLEAR_BINDING_STACK pop_everything
+#undef LANG_HOOKS_OPTION_LANG_MASK
+#define LANG_HOOKS_OPTION_LANG_MASK c_common_option_lang_mask
+#undef LANG_HOOKS_COMPLAIN_WRONG_LANG_P
+#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P c_common_complain_wrong_lang_p
 #undef LANG_HOOKS_INIT_OPTIONS
 #define LANG_HOOKS_INIT_OPTIONS c_common_init_options
 #undef LANG_HOOKS_INITIALIZE_DIAGNOSTICS
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/fortran/cpp.c gcc-mainline/gcc/fortran/cpp.c
--- gcc-mainline-opt1/gcc/fortran/cpp.c	2010-06-16 09:07:29.000000000 -0700
+++ gcc-mainline/gcc/fortran/cpp.c	2010-06-20 07:28:15.000000000 -0700
@@ -304,8 +304,8 @@  gfc_cpp_temporary_file (void)
 }
 
 void
-gfc_cpp_init_options (unsigned int argc,
-		      const char **argv ATTRIBUTE_UNUSED)
+gfc_cpp_init_options (unsigned int decoded_options_count,
+		      struct cl_decoded_option *decoded_options ATTRIBUTE_UNUSED)
 {
   /* Do not create any objects from libcpp here. If no
      preprocessing is requested, this would be wasted
@@ -337,7 +337,8 @@  gfc_cpp_init_options (unsigned int argc,
   gfc_cpp_option.prefix = NULL;
   gfc_cpp_option.sysroot = NULL;
 
-  gfc_cpp_option.deferred_opt = XNEWVEC (gfc_cpp_deferred_opt_t, argc);
+  gfc_cpp_option.deferred_opt = XNEWVEC (gfc_cpp_deferred_opt_t,
+					 decoded_options_count);
   gfc_cpp_option.deferred_opt_count = 0;
 }
 
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/fortran/cpp.h gcc-mainline/gcc/fortran/cpp.h
--- gcc-mainline-opt1/gcc/fortran/cpp.h	2010-06-16 09:07:29.000000000 -0700
+++ gcc-mainline/gcc/fortran/cpp.h	2010-06-20 07:32:08.000000000 -0700
@@ -1,4 +1,4 @@ 
-/* Copyright (C) 2008 Free Software Foundation, Inc.
+/* Copyright (C) 2008, 2010 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -36,7 +36,8 @@  const char *gfc_cpp_temporary_file (void
 void gfc_cpp_init_0 (void);
 void gfc_cpp_init (void);
 
-void gfc_cpp_init_options (unsigned int argc, const char **argv);
+void gfc_cpp_init_options (unsigned int decoded_options_count,
+			   struct cl_decoded_option *decoded_options);
 
 int gfc_cpp_handle_option(size_t scode, const char *arg, int value);
 
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/fortran/f95-lang.c gcc-mainline/gcc/fortran/f95-lang.c
--- gcc-mainline-opt1/gcc/fortran/f95-lang.c	2010-06-16 09:07:30.000000000 -0700
+++ gcc-mainline/gcc/fortran/f95-lang.c	2010-06-20 07:29:41.000000000 -0700
@@ -99,6 +99,7 @@  static void gfc_init_ts (void);
 #undef LANG_HOOKS_NAME
 #undef LANG_HOOKS_INIT
 #undef LANG_HOOKS_FINISH
+#undef LANG_HOOKS_OPTION_LANG_MASK
 #undef LANG_HOOKS_INIT_OPTIONS
 #undef LANG_HOOKS_HANDLE_OPTION
 #undef LANG_HOOKS_POST_OPTIONS
@@ -127,6 +128,7 @@  static void gfc_init_ts (void);
 #define LANG_HOOKS_NAME                 "GNU Fortran"
 #define LANG_HOOKS_INIT                 gfc_init
 #define LANG_HOOKS_FINISH               gfc_finish
+#define LANG_HOOKS_OPTION_LANG_MASK	gfc_option_lang_mask
 #define LANG_HOOKS_INIT_OPTIONS         gfc_init_options
 #define LANG_HOOKS_HANDLE_OPTION        gfc_handle_option
 #define LANG_HOOKS_POST_OPTIONS		gfc_post_options
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/fortran/gfortran.h gcc-mainline/gcc/fortran/gfortran.h
--- gcc-mainline-opt1/gcc/fortran/gfortran.h	2010-06-16 09:07:29.000000000 -0700
+++ gcc-mainline/gcc/fortran/gfortran.h	2010-06-20 07:33:00.000000000 -0700
@@ -2342,7 +2342,9 @@  void gfc_done_2 (void);
 int get_c_kind (const char *, CInteropKind_t *);
 
 /* options.c */
-unsigned int gfc_init_options (unsigned int, const char **);
+unsigned int gfc_option_lang_mask (void);
+void gfc_init_options (unsigned int,
+		       struct cl_decoded_option *);
 int gfc_handle_option (size_t, const char *, int, int);
 bool gfc_post_options (const char **);
 
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/fortran/options.c gcc-mainline/gcc/fortran/options.c
--- gcc-mainline-opt1/gcc/fortran/options.c	2010-06-17 08:49:25.000000000 -0700
+++ gcc-mainline/gcc/fortran/options.c	2010-06-20 07:25:46.000000000 -0700
@@ -53,11 +53,21 @@  set_default_std_flags (void)
 }
 
 
+/* Return language mask for Fortran options.  */
+
+unsigned int
+gfc_option_lang_mask (void)
+{
+  return CL_Fortran;
+}
+
+
 /* Get ready for options handling. Keep in sync with
    libgfortran/runtime/compile_options.c (init_compile_options). */
 
-unsigned int
-gfc_init_options (unsigned int argc, const char **argv)
+void
+gfc_init_options (unsigned int decoded_options_count,
+		  struct cl_decoded_option *decoded_options)
 {
   gfc_source_file = NULL;
   gfc_option.module_dir = NULL;
@@ -143,9 +153,7 @@  gfc_init_options (unsigned int argc, con
   flag_short_enums = targetm.default_short_enums ();
 
   /* Initialize cpp-related options.  */
-  gfc_cpp_init_options(argc, argv);
-
-  return CL_Fortran;
+  gfc_cpp_init_options (decoded_options_count, decoded_options);
 }
 
 
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/hooks.c gcc-mainline/gcc/hooks.c
--- gcc-mainline-opt1/gcc/hooks.c	2010-05-19 14:30:26.000000000 -0700
+++ gcc-mainline/gcc/hooks.c	2010-06-20 06:38:02.000000000 -0700
@@ -1,5 +1,5 @@ 
 /* General-purpose hooks.
-   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
@@ -176,8 +176,7 @@  hook_int_size_t_constcharptr_int_0 (size
 }
 
 unsigned int
-hook_uint_uint_constcharptrptr_0 (unsigned int a ATTRIBUTE_UNUSED,
-				  const char **b ATTRIBUTE_UNUSED)
+hook_uint_void_0 (void)
 {
   return 0;
 }
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/hooks.h gcc-mainline/gcc/hooks.h
--- gcc-mainline-opt1/gcc/hooks.h	2010-05-19 14:30:26.000000000 -0700
+++ gcc-mainline/gcc/hooks.h	2010-06-20 09:05:54.000000000 -0700
@@ -1,5 +1,5 @@ 
 /* General-purpose hooks.
-   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009
+   Copyright (C) 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify it
@@ -73,7 +73,7 @@  extern tree hook_tree_tree_tree_tree_nul
 extern tree hook_tree_tree_tree_tree_3rd_identity (tree, tree, tree);
 extern tree hook_tree_tree_int_treep_bool_null (tree, int, tree *, bool);
 
-extern unsigned hook_uint_uint_constcharptrptr_0 (unsigned, const char **);
+extern unsigned hook_uint_void_0 (void);
 
 extern bool default_can_output_mi_thunk_no_vcall (const_tree, HOST_WIDE_INT,
 						  HOST_WIDE_INT, const_tree);
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/java/lang.c gcc-mainline/gcc/java/lang.c
--- gcc-mainline-opt1/gcc/java/lang.c	2010-05-26 06:39:14.000000000 -0700
+++ gcc-mainline/gcc/java/lang.c	2010-06-20 07:49:25.000000000 -0700
@@ -47,7 +47,8 @@  The Free Software Foundation is independ
 
 static bool java_init (void);
 static void java_finish (void);
-static unsigned int java_init_options (unsigned int, const char **);
+static unsigned int java_option_lang_mask (void);
+static void java_init_options (unsigned int, struct cl_decoded_option *);
 static bool java_post_options (const char **);
 
 static int java_handle_option (size_t scode, const char *arg, int value, int kind);
@@ -122,6 +123,8 @@  struct GTY(()) language_function {
 #define LANG_HOOKS_INIT java_init
 #undef LANG_HOOKS_FINISH
 #define LANG_HOOKS_FINISH java_finish
+#undef LANG_HOOKS_OPTION_LANG_MASK
+#define LANG_HOOKS_OPTION_LANG_MASK java_option_lang_mask
 #undef LANG_HOOKS_INIT_OPTIONS
 #define LANG_HOOKS_INIT_OPTIONS java_init_options
 #undef LANG_HOOKS_HANDLE_OPTION
@@ -526,8 +529,14 @@  lang_init_source (int level)
 }
 
 static unsigned int
-java_init_options (unsigned int argc ATTRIBUTE_UNUSED,
-		   const char **argv ATTRIBUTE_UNUSED)
+java_option_lang_mask (void)
+{
+  return CL_Java;
+}
+
+static void
+java_init_options (unsigned int decoded_options_count ATTRIBUTE_UNUSED,
+		   struct cl_decoded_option *decoded_options ATTRIBUTE_UNUSED)
 {
   flag_bounds_check = 1;
   flag_exceptions = 1;
@@ -543,8 +552,6 @@  java_init_options (unsigned int argc ATT
   flag_evaluation_order = 1;
 
   jcf_path_init ();
-
-  return CL_Java;
 }
 
 /* Post-switch processing.  */
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/langhooks-def.h gcc-mainline/gcc/langhooks-def.h
--- gcc-mainline-opt1/gcc/langhooks-def.h	2010-06-16 09:07:33.000000000 -0700
+++ gcc-mainline/gcc/langhooks-def.h	2010-06-20 09:11:46.000000000 -0700
@@ -1,5 +1,5 @@ 
 /* Default macros to initialize the lang_hooks data structure.
-   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
    Contributed by Alexandre Oliva  <aoliva@redhat.com>
 
@@ -66,6 +66,9 @@  extern tree lhd_builtin_function (tree);
 
 /* Declarations of default tree inlining hooks.  */
 extern void lhd_initialize_diagnostics (struct diagnostic_context *);
+extern void lhd_init_options (unsigned int,
+			      struct cl_decoded_option *);
+extern bool lhd_complain_wrong_lang_p (const struct cl_option *);
 extern tree lhd_callgraph_analyze_expr (tree *, int *);
 
 
@@ -82,8 +85,10 @@  extern void lhd_omp_firstprivatize_type_
 #define LANG_HOOKS_INIT			hook_bool_void_false
 #define LANG_HOOKS_FINISH		lhd_do_nothing
 #define LANG_HOOKS_PARSE_FILE		lhd_do_nothing_i
-#define LANG_HOOKS_INIT_OPTIONS		hook_uint_uint_constcharptrptr_0
+#define LANG_HOOKS_OPTION_LANG_MASK	hook_uint_void_0
+#define LANG_HOOKS_INIT_OPTIONS		lhd_init_options
 #define LANG_HOOKS_INITIALIZE_DIAGNOSTICS lhd_initialize_diagnostics
+#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lhd_complain_wrong_lang_p
 #define LANG_HOOKS_HANDLE_OPTION	hook_int_size_t_constcharptr_int_0
 #define LANG_HOOKS_MISSING_ARGUMENT	hook_bool_constcharptr_size_t_false
 #define LANG_HOOKS_POST_OPTIONS		lhd_post_options
@@ -257,8 +262,10 @@  extern void lhd_end_section (void);
   LANG_HOOKS_IDENTIFIER_SIZE, \
   LANG_HOOKS_FREE_LANG_DATA, \
   LANG_HOOKS_TREE_SIZE, \
+  LANG_HOOKS_OPTION_LANG_MASK, \
   LANG_HOOKS_INIT_OPTIONS, \
   LANG_HOOKS_INITIALIZE_DIAGNOSTICS, \
+  LANG_HOOKS_COMPLAIN_WRONG_LANG_P, \
   LANG_HOOKS_HANDLE_OPTION, \
   LANG_HOOKS_MISSING_ARGUMENT, \
   LANG_HOOKS_POST_OPTIONS, \
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/langhooks.c gcc-mainline/gcc/langhooks.c
--- gcc-mainline-opt1/gcc/langhooks.c	2010-05-24 06:14:24.000000000 -0700
+++ gcc-mainline/gcc/langhooks.c	2010-06-20 08:41:42.000000000 -0700
@@ -337,6 +337,20 @@  lhd_initialize_diagnostics (struct diagn
 {
 }
 
+/* Called to perform language-specific options initialization.  */
+void
+lhd_init_options (unsigned int decoded_options_count ATTRIBUTE_UNUSED,
+		  struct cl_decoded_option *decoded_options ATTRIBUTE_UNUSED)
+{
+}
+
+/* By default, always complain about options for the wrong language.  */
+bool
+lhd_complain_wrong_lang_p (const struct cl_option *option ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
 /* The default function to print out name of current function that caused
    an error.  */
 void
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/langhooks.h gcc-mainline/gcc/langhooks.h
--- gcc-mainline-opt1/gcc/langhooks.h	2010-06-16 09:07:33.000000000 -0700
+++ gcc-mainline/gcc/langhooks.h	2010-06-20 09:11:57.000000000 -0700
@@ -1,5 +1,5 @@ 
 /* The lang_hooks data structure.
-   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -269,15 +269,24 @@  struct lang_hooks
      on unrecognized codes.  */
   size_t (*tree_size) (enum tree_code);
 
-  /* The first callback made to the front end, for simple
-     initialization needed before any calls to handle_option.  Return
-     the language mask to filter the switch array with.  */
-  unsigned int (*init_options) (unsigned int argc, const char **argv);
+  /* Return the language mask used for converting argv into a sequence
+     of options.  */
+  unsigned int (*option_lang_mask) (void);
+
+  /* After the initialize_diagnostics hook is called, do any simple
+     initialization needed before any calls to handle_option.  */
+  void (*init_options) (unsigned int decoded_options_count,
+			struct cl_decoded_option *decoded_options);
 
   /* Callback used to perform language-specific initialization for the
      global diagnostic context structure.  */
   void (*initialize_diagnostics) (struct diagnostic_context *);
 
+  /* Return true if a warning should be given about option OPTION,
+     which is for the wrong language, false if it should be quietly
+     ignored.  */
+  bool (*complain_wrong_lang_p) (const struct cl_option *option);
+
   /* Handle the switch CODE, which has real type enum opt_code from
      options.h.  If the switch takes an argument, it is passed in ARG
      which points to permanent storage.  The handler is responsible for
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/lto/lto-lang.c gcc-mainline/gcc/lto/lto-lang.c
--- gcc-mainline-opt1/gcc/lto/lto-lang.c	2010-06-07 05:37:01.000000000 -0700
+++ gcc-mainline/gcc/lto/lto-lang.c	2010-06-20 09:03:38.000000000 -0700
@@ -594,16 +594,34 @@  static GTY(()) tree registered_builtin_f
 /* Language hooks.  */
 
 static unsigned int
-lto_init_options (unsigned int argc ATTRIBUTE_UNUSED,
-		  const char **argv ATTRIBUTE_UNUSED)
+lto_option_lang_mask (void)
+{
+  return CL_LTO;
+}
+
+static bool
+lto_complain_wrong_lang_p (const struct cl_option *option ATTRIBUTE_UNUSED)
+{
+  /* The LTO front end inherits all the options from the first front
+     end that was used.  However, not all the original front end
+     options make sense in LTO.
+
+     A real solution would be to filter this in collect2, but collect2
+     does not have access to all the option attributes to know what to
+     filter.  So, in lto1 we silently accept inherited flags and do
+     nothing about it.  */
+  return false;
+}
+
+static void
+lto_init_options (unsigned int decoded_options_count ATTRIBUTE_UNUSED,
+		  struct cl_decoded_option *decoded_options ATTRIBUTE_UNUSED)
 {
   /* By default, C99-like requirements for complex multiply and divide.
      ???  Until the complex method is encoded in the IL this is the only
      safe choice.  This will pessimize Fortran code with LTO unless
      people specify a complex method manually or use -ffast-math.  */
   flag_complex_method = 2;
-
-  return CL_LTO;
 }
 
 /* Handle command-line option SCODE.  If the option takes an argument, it is
@@ -1115,6 +1133,10 @@  static void lto_init_ts (void)
 
 #undef LANG_HOOKS_NAME
 #define LANG_HOOKS_NAME "GNU GIMPLE"
+#undef LANG_HOOKS_OPTION_LANG_MASK
+#define LANG_HOOKS_OPTION_LANG_MASK lto_option_lang_mask
+#undef LANG_HOOKS_COMPLAIN_WRONG_LANG_P
+#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lto_complain_wrong_lang_p
 #undef LANG_HOOKS_INIT_OPTIONS
 #define LANG_HOOKS_INIT_OPTIONS lto_init_options
 #undef LANG_HOOKS_HANDLE_OPTION
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/opts-common.c gcc-mainline/gcc/opts-common.c
--- gcc-mainline-opt1/gcc/opts-common.c	2010-06-18 03:12:32.000000000 -0700
+++ gcc-mainline/gcc/opts-common.c	2010-06-20 08:03:58.000000000 -0700
@@ -245,10 +245,14 @@  decode_cmdline_option (const char **argv
     {
     case 1:
       decoded->orig_option_with_args_text = argv[0];
+      decoded->canonical_option[0] = argv[0];
+      decoded->canonical_option[1] = NULL;
       break;
     case 2:
       decoded->orig_option_with_args_text = concat (argv[0], " ",
 						    argv[1], NULL);
+      decoded->canonical_option[0] = argv[0];
+      decoded->canonical_option[1] = argv[1];
       break;
     default:
       gcc_unreachable ();
@@ -279,6 +283,8 @@  decode_cmdline_options_to_array (unsigne
   opt_array[0].opt_index = OPT_SPECIAL_program_name;
   opt_array[0].arg = argv[0];
   opt_array[0].orig_option_with_args_text = argv[0];
+  opt_array[0].canonical_option[0] = argv[0];
+  opt_array[0].canonical_option[1] = NULL;
   opt_array[0].value = 1;
   opt_array[0].errors = 0;
   num_decoded_options = 1;
@@ -293,6 +299,8 @@  decode_cmdline_options_to_array (unsigne
 	  opt_array[num_decoded_options].opt_index = OPT_SPECIAL_input_file;
 	  opt_array[num_decoded_options].arg = opt;
 	  opt_array[num_decoded_options].orig_option_with_args_text = opt;
+	  opt_array[num_decoded_options].canonical_option[0] = opt;
+	  opt_array[num_decoded_options].canonical_option[1] = NULL;
 	  opt_array[num_decoded_options].value = 1;
 	  opt_array[num_decoded_options].errors = 0;
 	  num_decoded_options++;
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/opts.c gcc-mainline/gcc/opts.c
--- gcc-mainline-opt1/gcc/opts.c	2010-06-17 14:44:07.000000000 -0700
+++ gcc-mainline/gcc/opts.c	2010-06-20 09:02:58.000000000 -0700
@@ -416,15 +416,7 @@  complain_wrong_lang (const char *text, c
 {
   char *ok_langs, *bad_lang;
 
-  /* The LTO front end inherits all the options from the first front
-     end that was used.  However, not all the original front end
-     options make sense in LTO.
-
-     A real solution would be to filter this in collect2, but collect2
-     does not have access to all the option attributes to know what to
-     filter.  So, in lto1 we silently accept inherited flags and do
-     nothing about it.  */
-  if (lang_mask & CL_LTO)
+  if (!lang_hooks.complain_wrong_lang_p (option))
     return;
 
   ok_langs = write_langs (option->flags);
@@ -715,7 +707,7 @@  decode_options (unsigned int argc, const
   if (first_time_p)
     {
       /* Perform language-specific options initialization.  */
-      initial_lang_mask = lang_mask = lang_hooks.init_options (argc, argv);
+      initial_lang_mask = lang_mask = lang_hooks.option_lang_mask ();
 
       lang_hooks.initialize_diagnostics (global_dc);
 
@@ -732,6 +724,9 @@  decode_options (unsigned int argc, const
 
   decode_cmdline_options_to_array (argc, argv, lang_mask,
 				   decoded_options, decoded_options_count);
+  if (first_time_p)
+    /* Perform language-specific options initialization.  */
+    lang_hooks.init_options (*decoded_options_count, *decoded_options);
 
   /* Scan to see what optimization level has been specified.  That will
      determine the default value of many flags.  */
diff -rupN --exclude=.svn gcc-mainline-opt1/gcc/opts.h gcc-mainline/gcc/opts.h
--- gcc-mainline-opt1/gcc/opts.h	2010-06-17 16:56:25.000000000 -0700
+++ gcc-mainline/gcc/opts.h	2010-06-20 08:02:11.000000000 -0700
@@ -117,6 +117,14 @@  struct cl_decoded_option
      -frecord-gcc-switches.  */
   const char *orig_option_with_args_text;
 
+  /* The canonical form of the option and its argument, for when it is
+     necessary to reconstruct argv elements (in particular, for
+     processing specs and passing options to subprocesses from the
+     driver).  The first element of this array is non-NULL; the second
+     is NULL if the canonical form uses only one argv element,
+     non-NULL otherwise.  */
+  const char *canonical_option[2];
+
   /* For a boolean option, 1 for the true case and 0 for the "no-"
      case.  For an unsigned integer option, the value of the
      argument.  1 in all other cases.  */