Message ID | Pine.LNX.4.64.1008110044450.32339@digraph.polyomino.org.uk |
---|---|
State | New |
Headers | show |
On Wed, Aug 11, 2010 at 2:45 AM, Joseph S. Myers <joseph@codesourcery.com> wrote: > In the course of preparing the patch that makes the driver use the > shared option processing machinery to handle its own options, I found > that in various cases it is useful for the option handlers in the > driver to have direct access to the cl_decoded_option structure > instead of just the parts of it currently passed to handlers as > separate arguments - specifically, having the canonical form of an > option-plus-arguments is useful for the driver code saving options for > subsequent spec processing. > > This patch accordingly arranges for various handlers to take > cl_decoded_option structures. Where they then pass on the separate > arguments to other functions, they assert that options with more than > one argument are not involved (at present such options can only arise > through SWITCH_TAKES_ARG/WORD_SWITCH_TAKES_ARG, but with the move of > all driver options to the .opt machinery such options will be > describable in .opt files in future), since the separate arguments are > not sufficient to describe such options. > > handle_option is called recursively to handle options implied by other > options, in the context of -Werror=some-option in particular. These > recursive calls do not naturally have a cl_decoded_option structure; I > added handle_generated_option, which reconstructs such a structure > from the separate arguments, for use of those calls. > > Bootstrapped with no regressions on x86_64-unknown-linux-gnu. OK to > commit? Ok. Thanks, Richard. > 2010-08-10 Joseph Myers <joseph@codesourcery.com> > > * opts.h (struct cl_option_handler_func): Make handler take > cl_decoded_option structure as parameter, not individual elements. > (struct cl_option_handlers): Make callbacks take cl_decoded_option > structure as parameter, not individual elements. > (handle_option): Take cl_decoded_option structure as parameter, > not individual elements. > (handle_generated_option): Declare. > * opts-common.c (handle_option): Take cl_decoded_option structure > as parameter, not individual elements. Update calls to callback > and handler functions. > (handle_generated_option): New. > (read_cmdline_option): Update calls to callback functions and > handle_option. > * opts.c (common_handle_option, complain_wrong_lang, > unknown_option_callback, post_handling_callback, > lang_handle_option, target_handle_option): Take cl_decoded_option > structure as parameter, not individual elements. > (lang_handle_option, target_handle_option, common_handle_option): > Assert option has at most one argument. > (enable_warning_as_error): Call handle_generated_option instead of > handle_option. Do not pass -Werror argument as argument of > generated option. > > c-family: > 2010-08-10 Joseph Myers <joseph@codesourcery.com> > > * c-opts.c (c_common_handle_option): Call handle_generated_option > instead of handle_option. > > Index: gcc/opts-common.c > =================================================================== > --- gcc/opts-common.c (revision 162909) > +++ gcc/opts-common.c (working copy) > @@ -496,17 +496,19 @@ done: > free (options); > } > > -/* Handle option OPT_INDEX, and argument ARG, for the language > - indicated by LANG_MASK, using the handlers in HANDLERS. VALUE is > - the option value as for the value field of cl_decoded_option. KIND > - is the diagnostic_t if this is a diagnostics option, DK_UNSPECIFIED > - otherwise. Returns false if the switch was invalid. */ > +/* Handle option DECODED for the language indicated by LANG_MASK, > + using the handlers in HANDLERS. KIND is the diagnostic_t if this > + is a diagnostics option, DK_UNSPECIFIED otherwise. Returns false > + if the switch was invalid. */ > > bool > -handle_option (size_t opt_index, const char *arg, int value, > +handle_option (const struct cl_decoded_option *decoded, > unsigned int lang_mask, int kind, > const struct cl_option_handlers *handlers) > { > + size_t opt_index = decoded->opt_index; > + const char *arg = decoded->arg; > + int value = decoded->value; > const struct cl_option *option = &cl_options[opt_index]; > size_t i; > > @@ -516,17 +518,68 @@ handle_option (size_t opt_index, const c > for (i = 0; i < handlers->num_handlers; i++) > if (option->flags & handlers->handlers[i].mask) > { > - if (!handlers->handlers[i].handler (opt_index, arg, value, > + if (!handlers->handlers[i].handler (decoded, > lang_mask, kind, handlers)) > return false; > else > - handlers->post_handling_callback (opt_index, arg, value, > + handlers->post_handling_callback (decoded, > handlers->handlers[i].mask); > } > > return true; > } > > +/* Like handle_option, but OPT_INDEX, ARG and VALUE describe the > + option instead of DECODED. This is used for callbacks when one > + option implies another instead of an option being decoded from the > + command line. */ > + > +bool > +handle_generated_option (size_t opt_index, const char *arg, int value, > + unsigned int lang_mask, int kind, > + const struct cl_option_handlers *handlers) > +{ > + const struct cl_option *option = &cl_options[opt_index]; > + struct cl_decoded_option decoded; > + > + decoded.opt_index = opt_index; > + decoded.arg = arg; > + decoded.canonical_option[2] = NULL; > + decoded.canonical_option[3] = NULL; > + decoded.value = value; > + decoded.errors = 0; > + > + if (arg) > + { > + if (option->flags & CL_SEPARATE) > + { > + decoded.orig_option_with_args_text = concat (option->opt_text, " ", > + arg, NULL); > + decoded.canonical_option[0] = option->opt_text; > + decoded.canonical_option[1] = arg; > + decoded.canonical_option_num_elements = 2; > + } > + else > + { > + gcc_assert (option->flags & CL_JOINED); > + decoded.orig_option_with_args_text = concat (option->opt_text, arg, > + NULL); > + decoded.canonical_option[0] = decoded.orig_option_with_args_text; > + decoded.canonical_option[1] = NULL; > + decoded.canonical_option_num_elements = 1; > + } > + } > + else > + { > + decoded.orig_option_with_args_text = option->opt_text; > + decoded.canonical_option[0] = option->opt_text; > + decoded.canonical_option[1] = NULL; > + decoded.canonical_option_num_elements = 1; > + } > + > + return handle_option (&decoded, lang_mask, kind, handlers); > +} > + > /* Handle the switch DECODED for the language indicated by LANG_MASK, > using the handlers in *HANDLERS. */ > > @@ -540,10 +593,8 @@ read_cmdline_option (struct cl_decoded_o > > if (decoded->opt_index == OPT_SPECIAL_unknown) > { > - opt = decoded->arg; > - > - if (handlers->unknown_option_callback (opt)) > - error ("unrecognized command line option %qs", opt); > + if (handlers->unknown_option_callback (decoded)) > + error ("unrecognized command line option %qs", decoded->arg); > return; > } > > @@ -559,7 +610,7 @@ read_cmdline_option (struct cl_decoded_o > > if (decoded->errors & CL_ERR_WRONG_LANG) > { > - handlers->wrong_lang_callback (opt, option, lang_mask); > + handlers->wrong_lang_callback (decoded, lang_mask); > return; > } > > @@ -581,8 +632,7 @@ read_cmdline_option (struct cl_decoded_o > > gcc_assert (!decoded->errors); > > - if (!handle_option (decoded->opt_index, decoded->arg, decoded->value, > - lang_mask, DK_UNSPECIFIED, handlers)) > + if (!handle_option (decoded, lang_mask, DK_UNSPECIFIED, handlers)) > error ("unrecognized command line option %qs", opt); > } > > Index: gcc/c-family/c-opts.c > =================================================================== > --- gcc/c-family/c-opts.c (revision 162909) > +++ gcc/c-family/c-opts.c (working copy) > @@ -437,8 +437,8 @@ c_common_handle_option (size_t scode, co > case OPT_Wall: > warn_unused = value; > set_Wformat (value); > - handle_option (OPT_Wimplicit, NULL, value, c_family_lang_mask, kind, > - handlers); > + handle_generated_option (OPT_Wimplicit, NULL, value, > + c_family_lang_mask, kind, handlers); > warn_char_subscripts = value; > warn_missing_braces = value; > warn_parentheses = value; > @@ -539,11 +539,11 @@ c_common_handle_option (size_t scode, co > case OPT_Wimplicit: > gcc_assert (value == 0 || value == 1); > if (warn_implicit_int == -1) > - handle_option (OPT_Wimplicit_int, NULL, value, > - c_family_lang_mask, kind, handlers); > + handle_generated_option (OPT_Wimplicit_int, NULL, value, > + c_family_lang_mask, kind, handlers); > if (warn_implicit_function_declaration == -1) > - handle_option (OPT_Wimplicit_function_declaration, NULL, value, > - c_family_lang_mask, kind, handlers); > + handle_generated_option (OPT_Wimplicit_function_declaration, NULL, > + value, c_family_lang_mask, kind, handlers); > break; > > case OPT_Wimport: > Index: gcc/opts.c > =================================================================== > --- gcc/opts.c (revision 162909) > +++ gcc/opts.c (working copy) > @@ -372,12 +372,12 @@ bool flag_warn_unused_result = false; > const char **in_fnames; > unsigned num_in_fnames; > > -static bool common_handle_option (size_t scode, const char *arg, int value, > +static bool common_handle_option (const struct cl_decoded_option *decoded, > unsigned int lang_mask, int kind, > const struct cl_option_handlers *handlers); > static void handle_param (const char *); > static char *write_langs (unsigned int lang_mask); > -static void complain_wrong_lang (const char *, const struct cl_option *, > +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); > @@ -410,11 +410,14 @@ write_langs (unsigned int mask) > return result; > } > > -/* Complain that switch OPT_INDEX does not apply to this front end. */ > +/* Complain that switch DECODED does not apply to this front end (mask > + LANG_MASK). */ > static void > -complain_wrong_lang (const char *text, const struct cl_option *option, > +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, *bad_lang; > > if (!lang_hooks.complain_wrong_lang_p (option)) > @@ -461,12 +464,14 @@ void print_ignored_options (void) > input_location = saved_loc; > } > > -/* Handle an unknown option ARG, returning true if an error should be > +/* Handle an unknown option DECODED, returning true if an error should be > given. */ > > static bool > -unknown_option_callback (const char *opt) > +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] == '-') > { > /* We don't generate warnings for unknown -Wno-* options unless > @@ -478,17 +483,16 @@ unknown_option_callback (const char *opt > return true; > } > > -/* Note that an option (index OPT_INDEX, argument ARG, value VALUE) > - has been successfully handled with a handler for mask MASK. */ > +/* Note that an option DECODED has been successfully handled with a > + handler for mask MASK. */ > > static void > -post_handling_callback (size_t opt_index ATTRIBUTE_UNUSED, > - const char *arg ATTRIBUTE_UNUSED, > - int value ATTRIBUTE_UNUSED, > +post_handling_callback (const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED, > unsigned int mask ATTRIBUTE_UNUSED) > { > #ifdef ENABLE_LTO > - lto_register_user_option (opt_index, arg, value, mask); > + lto_register_user_option (decoded->opt_index, decoded->arg, > + decoded->value, mask); > #endif > } > > @@ -496,23 +500,27 @@ post_handling_callback (size_t opt_index > handle_option. */ > > static bool > -lang_handle_option (size_t opt_index, const char *arg, int value, > +lang_handle_option (const struct cl_decoded_option *decoded, > unsigned int lang_mask ATTRIBUTE_UNUSED, int kind, > const struct cl_option_handlers *handlers) > { > - return lang_hooks.handle_option (opt_index, arg, value, kind, handlers); > + gcc_assert (decoded->canonical_option_num_elements <= 2); > + return lang_hooks.handle_option (decoded->opt_index, decoded->arg, > + decoded->value, kind, handlers); > } > > /* Handle a back-end option; arguments and return value as for > handle_option. */ > > static bool > -target_handle_option (size_t opt_index, const char *arg, int value, > - unsigned int lang_mask ATTRIBUTE_UNUSED, int kind, > - const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) > +target_handle_option (const struct cl_decoded_option *decoded, > + unsigned int lang_mask ATTRIBUTE_UNUSED, int kind, > + const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) > { > + gcc_assert (decoded->canonical_option_num_elements <= 2); > gcc_assert (kind == DK_UNSPECIFIED); > - return targetm.handle_option (opt_index, arg, value); > + return targetm.handle_option (decoded->opt_index, decoded->arg, > + decoded->value); > } > > /* Handle FILENAME from the command line. */ > @@ -1386,16 +1394,21 @@ print_specific_help (unsigned int includ > /* Handle target- and language-independent options. Return zero to > generate an "unknown option" message. Only options that need > extra handling need to be listed here; if you simply want > - VALUE assigned to a variable, it happens automatically. */ > + DECODED->value assigned to a variable, it happens automatically. */ > > static bool > -common_handle_option (size_t scode, const char *arg, int value, > +common_handle_option (const struct cl_decoded_option *decoded, > unsigned int lang_mask, int kind ATTRIBUTE_UNUSED, > const struct cl_option_handlers *handlers) > { > + size_t scode = decoded->opt_index; > + const char *arg = decoded->arg; > + int value = decoded->value; > static bool verbose = false; > enum opt_code code = (enum opt_code) scode; > > + gcc_assert (decoded->canonical_option_num_elements <= 2); > + > switch (code) > { > case OPT__param: > @@ -2357,8 +2370,8 @@ enable_warning_as_error (const char *arg > > /* -Werror=foo implies -Wfoo. */ > if (option->var_type == CLVC_BOOLEAN) > - handle_option (option_index, arg, value, lang_mask, (int)kind, > - handlers); > + handle_generated_option (option_index, NULL, value, lang_mask, > + (int)kind, handlers); > > if (warning_as_error_callback) > warning_as_error_callback (option_index); > Index: gcc/opts.h > =================================================================== > --- gcc/opts.h (revision 162909) > +++ gcc/opts.h (working copy) > @@ -142,7 +142,7 @@ struct cl_decoded_option > struct cl_option_handler_func > { > /* The function called to handle the option. */ > - bool (*handler) (size_t opt_index, const char *arg, int value, > + bool (*handler) (const struct cl_decoded_option *decoded, > unsigned int lang_mask, int kind, > const struct cl_option_handlers *handlers); > > @@ -159,17 +159,16 @@ struct cl_option_handlers > error for it, and possibly store information to diagnose the > option at a later point. Return true if an error should be > given, false otherwise. */ > - bool (*unknown_option_callback) (const char *opt); > + bool (*unknown_option_callback) (const struct cl_decoded_option *decoded); > > /* Callback to handle, and possibly diagnose, an option for another > language. */ > - void (*wrong_lang_callback) (const char *text, > - const struct cl_option *option, > + void (*wrong_lang_callback) (const struct cl_decoded_option *decoded, > unsigned int lang_mask); > > /* Callback to call after the successful handling of any option. */ > - void (*post_handling_callback) (size_t opt_index, const char *arg, > - int value, unsigned int mask); > + void (*post_handling_callback) (const struct cl_decoded_option *decoded, > + unsigned int mask); > > /* The number of individual handlers. */ > size_t num_handlers; > @@ -200,9 +199,12 @@ extern void decode_options (unsigned int > extern int option_enabled (int opt_idx); > extern bool get_option_state (int, struct cl_option_state *); > extern void set_option (int opt_index, int value, const char *arg, int); > -bool handle_option (size_t opt_index, const char *arg, int value, > +bool handle_option (const struct cl_decoded_option *decoded, > unsigned int lang_mask, int kind, > const struct cl_option_handlers *handlers); > +bool handle_generated_option (size_t opt_index, const char *arg, int value, > + unsigned int lang_mask, int kind, > + const struct cl_option_handlers *handlers); > extern void read_cmdline_option (struct cl_decoded_option *decoded, > unsigned int lang_mask, > const struct cl_option_handlers *handlers); > > -- > Joseph S. Myers > joseph@codesourcery.com >
Index: gcc/opts-common.c =================================================================== --- gcc/opts-common.c (revision 162909) +++ gcc/opts-common.c (working copy) @@ -496,17 +496,19 @@ done: free (options); } -/* Handle option OPT_INDEX, and argument ARG, for the language - indicated by LANG_MASK, using the handlers in HANDLERS. VALUE is - the option value as for the value field of cl_decoded_option. KIND - is the diagnostic_t if this is a diagnostics option, DK_UNSPECIFIED - otherwise. Returns false if the switch was invalid. */ +/* Handle option DECODED for the language indicated by LANG_MASK, + using the handlers in HANDLERS. KIND is the diagnostic_t if this + is a diagnostics option, DK_UNSPECIFIED otherwise. Returns false + if the switch was invalid. */ bool -handle_option (size_t opt_index, const char *arg, int value, +handle_option (const struct cl_decoded_option *decoded, unsigned int lang_mask, int kind, const struct cl_option_handlers *handlers) { + size_t opt_index = decoded->opt_index; + const char *arg = decoded->arg; + int value = decoded->value; const struct cl_option *option = &cl_options[opt_index]; size_t i; @@ -516,17 +518,68 @@ handle_option (size_t opt_index, const c for (i = 0; i < handlers->num_handlers; i++) if (option->flags & handlers->handlers[i].mask) { - if (!handlers->handlers[i].handler (opt_index, arg, value, + if (!handlers->handlers[i].handler (decoded, lang_mask, kind, handlers)) return false; else - handlers->post_handling_callback (opt_index, arg, value, + handlers->post_handling_callback (decoded, handlers->handlers[i].mask); } return true; } +/* Like handle_option, but OPT_INDEX, ARG and VALUE describe the + option instead of DECODED. This is used for callbacks when one + option implies another instead of an option being decoded from the + command line. */ + +bool +handle_generated_option (size_t opt_index, const char *arg, int value, + unsigned int lang_mask, int kind, + const struct cl_option_handlers *handlers) +{ + const struct cl_option *option = &cl_options[opt_index]; + struct cl_decoded_option decoded; + + decoded.opt_index = opt_index; + decoded.arg = arg; + decoded.canonical_option[2] = NULL; + decoded.canonical_option[3] = NULL; + decoded.value = value; + decoded.errors = 0; + + if (arg) + { + if (option->flags & CL_SEPARATE) + { + decoded.orig_option_with_args_text = concat (option->opt_text, " ", + arg, NULL); + decoded.canonical_option[0] = option->opt_text; + decoded.canonical_option[1] = arg; + decoded.canonical_option_num_elements = 2; + } + else + { + gcc_assert (option->flags & CL_JOINED); + decoded.orig_option_with_args_text = concat (option->opt_text, arg, + NULL); + decoded.canonical_option[0] = decoded.orig_option_with_args_text; + decoded.canonical_option[1] = NULL; + decoded.canonical_option_num_elements = 1; + } + } + else + { + decoded.orig_option_with_args_text = option->opt_text; + decoded.canonical_option[0] = option->opt_text; + decoded.canonical_option[1] = NULL; + decoded.canonical_option_num_elements = 1; + } + + return handle_option (&decoded, lang_mask, kind, handlers); +} + /* Handle the switch DECODED for the language indicated by LANG_MASK, using the handlers in *HANDLERS. */ @@ -540,10 +593,8 @@ read_cmdline_option (struct cl_decoded_o if (decoded->opt_index == OPT_SPECIAL_unknown) { - opt = decoded->arg; - - if (handlers->unknown_option_callback (opt)) - error ("unrecognized command line option %qs", opt); + if (handlers->unknown_option_callback (decoded)) + error ("unrecognized command line option %qs", decoded->arg); return; } @@ -559,7 +610,7 @@ read_cmdline_option (struct cl_decoded_o if (decoded->errors & CL_ERR_WRONG_LANG) { - handlers->wrong_lang_callback (opt, option, lang_mask); + handlers->wrong_lang_callback (decoded, lang_mask); return; } @@ -581,8 +632,7 @@ read_cmdline_option (struct cl_decoded_o gcc_assert (!decoded->errors); - if (!handle_option (decoded->opt_index, decoded->arg, decoded->value, - lang_mask, DK_UNSPECIFIED, handlers)) + if (!handle_option (decoded, lang_mask, DK_UNSPECIFIED, handlers)) error ("unrecognized command line option %qs", opt); } Index: gcc/c-family/c-opts.c =================================================================== --- gcc/c-family/c-opts.c (revision 162909) +++ gcc/c-family/c-opts.c (working copy) @@ -437,8 +437,8 @@ c_common_handle_option (size_t scode, co case OPT_Wall: warn_unused = value; set_Wformat (value); - handle_option (OPT_Wimplicit, NULL, value, c_family_lang_mask, kind, - handlers); + handle_generated_option (OPT_Wimplicit, NULL, value, + c_family_lang_mask, kind, handlers); warn_char_subscripts = value; warn_missing_braces = value; warn_parentheses = value; @@ -539,11 +539,11 @@ c_common_handle_option (size_t scode, co case OPT_Wimplicit: gcc_assert (value == 0 || value == 1); if (warn_implicit_int == -1) - handle_option (OPT_Wimplicit_int, NULL, value, - c_family_lang_mask, kind, handlers); + handle_generated_option (OPT_Wimplicit_int, NULL, value, + c_family_lang_mask, kind, handlers); if (warn_implicit_function_declaration == -1) - handle_option (OPT_Wimplicit_function_declaration, NULL, value, - c_family_lang_mask, kind, handlers); + handle_generated_option (OPT_Wimplicit_function_declaration, NULL, + value, c_family_lang_mask, kind, handlers); break; case OPT_Wimport: Index: gcc/opts.c =================================================================== --- gcc/opts.c (revision 162909) +++ gcc/opts.c (working copy) @@ -372,12 +372,12 @@ bool flag_warn_unused_result = false; const char **in_fnames; unsigned num_in_fnames; -static bool common_handle_option (size_t scode, const char *arg, int value, +static bool common_handle_option (const struct cl_decoded_option *decoded, unsigned int lang_mask, int kind, const struct cl_option_handlers *handlers); static void handle_param (const char *); static char *write_langs (unsigned int lang_mask); -static void complain_wrong_lang (const char *, const struct cl_option *, +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); @@ -410,11 +410,14 @@ write_langs (unsigned int mask) return result; } -/* Complain that switch OPT_INDEX does not apply to this front end. */ +/* Complain that switch DECODED does not apply to this front end (mask + LANG_MASK). */ static void -complain_wrong_lang (const char *text, const struct cl_option *option, +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, *bad_lang; if (!lang_hooks.complain_wrong_lang_p (option)) @@ -461,12 +464,14 @@ void print_ignored_options (void) input_location = saved_loc; } -/* Handle an unknown option ARG, returning true if an error should be +/* Handle an unknown option DECODED, returning true if an error should be given. */ static bool -unknown_option_callback (const char *opt) +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] == '-') { /* We don't generate warnings for unknown -Wno-* options unless @@ -478,17 +483,16 @@ unknown_option_callback (const char *opt return true; } -/* Note that an option (index OPT_INDEX, argument ARG, value VALUE) - has been successfully handled with a handler for mask MASK. */ +/* Note that an option DECODED has been successfully handled with a + handler for mask MASK. */ static void -post_handling_callback (size_t opt_index ATTRIBUTE_UNUSED, - const char *arg ATTRIBUTE_UNUSED, - int value ATTRIBUTE_UNUSED, +post_handling_callback (const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED, unsigned int mask ATTRIBUTE_UNUSED) { #ifdef ENABLE_LTO - lto_register_user_option (opt_index, arg, value, mask); + lto_register_user_option (decoded->opt_index, decoded->arg, + decoded->value, mask); #endif } @@ -496,23 +500,27 @@ post_handling_callback (size_t opt_index handle_option. */ static bool -lang_handle_option (size_t opt_index, const char *arg, int value, +lang_handle_option (const struct cl_decoded_option *decoded, unsigned int lang_mask ATTRIBUTE_UNUSED, int kind, const struct cl_option_handlers *handlers) { - return lang_hooks.handle_option (opt_index, arg, value, kind, handlers); + gcc_assert (decoded->canonical_option_num_elements <= 2); + return lang_hooks.handle_option (decoded->opt_index, decoded->arg, + decoded->value, kind, handlers); } /* Handle a back-end option; arguments and return value as for handle_option. */ static bool -target_handle_option (size_t opt_index, const char *arg, int value, - unsigned int lang_mask ATTRIBUTE_UNUSED, int kind, - const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) +target_handle_option (const struct cl_decoded_option *decoded, + unsigned int lang_mask ATTRIBUTE_UNUSED, int kind, + const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED) { + gcc_assert (decoded->canonical_option_num_elements <= 2); gcc_assert (kind == DK_UNSPECIFIED); - return targetm.handle_option (opt_index, arg, value); + return targetm.handle_option (decoded->opt_index, decoded->arg, + decoded->value); } /* Handle FILENAME from the command line. */ @@ -1386,16 +1394,21 @@ print_specific_help (unsigned int includ /* Handle target- and language-independent options. Return zero to generate an "unknown option" message. Only options that need extra handling need to be listed here; if you simply want - VALUE assigned to a variable, it happens automatically. */ + DECODED->value assigned to a variable, it happens automatically. */ static bool -common_handle_option (size_t scode, const char *arg, int value, +common_handle_option (const struct cl_decoded_option *decoded, unsigned int lang_mask, int kind ATTRIBUTE_UNUSED, const struct cl_option_handlers *handlers) { + size_t scode = decoded->opt_index; + const char *arg = decoded->arg; + int value = decoded->value; static bool verbose = false; enum opt_code code = (enum opt_code) scode; + gcc_assert (decoded->canonical_option_num_elements <= 2); + switch (code) { case OPT__param: @@ -2357,8 +2370,8 @@ enable_warning_as_error (const char *arg /* -Werror=foo implies -Wfoo. */ if (option->var_type == CLVC_BOOLEAN) - handle_option (option_index, arg, value, lang_mask, (int)kind, - handlers); + handle_generated_option (option_index, NULL, value, lang_mask, + (int)kind, handlers); if (warning_as_error_callback) warning_as_error_callback (option_index); Index: gcc/opts.h =================================================================== --- gcc/opts.h (revision 162909) +++ gcc/opts.h (working copy) @@ -142,7 +142,7 @@ struct cl_decoded_option struct cl_option_handler_func { /* The function called to handle the option. */ - bool (*handler) (size_t opt_index, const char *arg, int value, + bool (*handler) (const struct cl_decoded_option *decoded, unsigned int lang_mask, int kind, const struct cl_option_handlers *handlers); @@ -159,17 +159,16 @@ struct cl_option_handlers error for it, and possibly store information to diagnose the option at a later point. Return true if an error should be given, false otherwise. */ - bool (*unknown_option_callback) (const char *opt); + bool (*unknown_option_callback) (const struct cl_decoded_option *decoded); /* Callback to handle, and possibly diagnose, an option for another language. */ - void (*wrong_lang_callback) (const char *text, - const struct cl_option *option, + void (*wrong_lang_callback) (const struct cl_decoded_option *decoded, unsigned int lang_mask); /* Callback to call after the successful handling of any option. */ - void (*post_handling_callback) (size_t opt_index, const char *arg, - int value, unsigned int mask); + void (*post_handling_callback) (const struct cl_decoded_option *decoded, + unsigned int mask); /* The number of individual handlers. */ size_t num_handlers; @@ -200,9 +199,12 @@ extern void decode_options (unsigned int extern int option_enabled (int opt_idx); extern bool get_option_state (int, struct cl_option_state *); extern void set_option (int opt_index, int value, const char *arg, int); -bool handle_option (size_t opt_index, const char *arg, int value, +bool handle_option (const struct cl_decoded_option *decoded, unsigned int lang_mask, int kind, const struct cl_option_handlers *handlers); +bool handle_generated_option (size_t opt_index, const char *arg, int value, + unsigned int lang_mask, int kind, + const struct cl_option_handlers *handlers); extern void read_cmdline_option (struct cl_decoded_option *decoded, unsigned int lang_mask, const struct cl_option_handlers *handlers);