From patchwork Wed Aug 11 00:45:22 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Joseph Myers X-Patchwork-Id: 61420 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id CE6F7B6EE8 for ; Wed, 11 Aug 2010 10:45:38 +1000 (EST) Received: (qmail 24987 invoked by alias); 11 Aug 2010 00:45:36 -0000 Received: (qmail 24967 invoked by uid 22791); 11 Aug 2010 00:45:34 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mail.codesourcery.com (HELO mail.codesourcery.com) (38.113.113.100) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Wed, 11 Aug 2010 00:45:28 +0000 Received: (qmail 9498 invoked from network); 11 Aug 2010 00:45:24 -0000 Received: from unknown (HELO digraph.polyomino.org.uk) (joseph@127.0.0.2) by mail.codesourcery.com with ESMTPA; 11 Aug 2010 00:45:24 -0000 Received: from jsm28 (helo=localhost) by digraph.polyomino.org.uk with local-esmtp (Exim 4.69) (envelope-from ) id 1OizRa-00010c-PY for gcc-patches@gcc.gnu.org; Wed, 11 Aug 2010 00:45:22 +0000 Date: Wed, 11 Aug 2010 00:45:22 +0000 (UTC) From: "Joseph S. Myers" To: gcc-patches@gcc.gnu.org Subject: Pass cl_decoded_option structures to more option handling interfaces Message-ID: MIME-Version: 1.0 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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? 2010-08-10 Joseph Myers * 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 * 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);