From: jsm28 Date: Fri, 26 Nov 2010 23:18:28 +0000 (+0000) Subject: * doc/options.texi (Enum, EnumValue): Document new record types. X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=commitdiff_plain;h=d62a5950068849e2419dfbeaca7e83e456e14cf9 * doc/options.texi (Enum, EnumValue): Document new record types. (Enum): Document new option flag. * opt-functions.awk * optc-gen.awk: Handle enumerated option arguments. * opth-gen.awk: Handle enumerated option arguments. * opts-common.c (enum_arg_ok_for_language, enum_arg_to_value, enum_value_to_arg): New. (decode_cmdline_option): Handle enumerated arguments. (read_cmdline_option): Handle CL_ERR_ENUM_ARG. (set_option, option_enabled, get_option_state): Handle CLVC_ENUM. * opts.c (print_filtered_help, print_specific_help): Take lang_mask arguments. (print_filtered_help): Handle printing values of enumerated options. Print possible arguments for enumerated options. (print_specific_help): Update call to print_filtered_help. (common_handle_option): Update calls to print_specific_help. Use value rather than arg for OPT_fdiagnostics_show_location_. Don't handle OPT_ffp_contract_, OPT_fexcess_precision_, OPT_fvisibility_, OPT_ftls_model_, OPT_fira_algorithm_ or OPT_fira_region_ here. * opts.h (enum cl_var_type): Add CLVC_ENUM. (struct cl_option): Add var_enum. (CL_ENUM_CANONICAL, CL_ENUM_DRIVER_ONLY, struct cl_enum_arg, struct cl_enum, cl_enums, cl_enums_count): New. (CL_ERR_ENUM_ARG): Define. (CL_ERR_NEGATIVE): Update value. (enum_value_to_arg): Declare. * common.opt (flag_ira_algorithm, flag_ira_region, flag_fp_contract_mode, flag_excess_precision_cmdline, default_visibility, flag_tls_default): Remove Variable entries. (help_enum_printed): New Variable. (fdiagnostics-show-location=): Use Enum. Add associated SourceInclude, Enum and EnumValue entries. (fexcess-precision=, ffp-contract=, fira-algorithm=, fira-region=, ftls-model=, fvisibility=): Use Enum, Var and Init. Add associated Enum and EnumValue entries. po: * exgettext: Handle UnknownError. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167190 138bc75d-0d04-0410-961f-82ee72b054a4 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 808afedd8b1..659ca468c5d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,42 @@ +2010-11-26 Joseph Myers + + * doc/options.texi (Enum, EnumValue): Document new record types. + (Enum): Document new option flag. + * opt-functions.awk + * optc-gen.awk: Handle enumerated option arguments. + * opth-gen.awk: Handle enumerated option arguments. + * opts-common.c (enum_arg_ok_for_language, enum_arg_to_value, + enum_value_to_arg): New. + (decode_cmdline_option): Handle enumerated arguments. + (read_cmdline_option): Handle CL_ERR_ENUM_ARG. + (set_option, option_enabled, get_option_state): Handle CLVC_ENUM. + * opts.c (print_filtered_help, print_specific_help): Take + lang_mask arguments. + (print_filtered_help): Handle printing values of enumerated + options. Print possible arguments for enumerated options. + (print_specific_help): Update call to print_filtered_help. + (common_handle_option): Update calls to print_specific_help. Use + value rather than arg for OPT_fdiagnostics_show_location_. Don't + handle OPT_ffp_contract_, OPT_fexcess_precision_, + OPT_fvisibility_, OPT_ftls_model_, OPT_fira_algorithm_ or + OPT_fira_region_ here. + * opts.h (enum cl_var_type): Add CLVC_ENUM. + (struct cl_option): Add var_enum. + (CL_ENUM_CANONICAL, CL_ENUM_DRIVER_ONLY, struct cl_enum_arg, + struct cl_enum, cl_enums, cl_enums_count): New. + (CL_ERR_ENUM_ARG): Define. + (CL_ERR_NEGATIVE): Update value. + (enum_value_to_arg): Declare. + * common.opt (flag_ira_algorithm, flag_ira_region, + flag_fp_contract_mode, flag_excess_precision_cmdline, + default_visibility, flag_tls_default): Remove Variable entries. + (help_enum_printed): New Variable. + (fdiagnostics-show-location=): Use Enum. Add associated + SourceInclude, Enum and EnumValue entries. + (fexcess-precision=, ffp-contract=, fira-algorithm=, fira-region=, + ftls-model=, fvisibility=): Use Enum, Var and Init. Add + associated Enum and EnumValue entries. + 2010-11-26 Joern Rennecke PR target/46623 diff --git a/gcc/common.opt b/gcc/common.opt index f4523db1cb5..57f5b0a27e9 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -42,15 +42,6 @@ int flag_complex_method = 1 Variable int flag_evaluation_order = 0 -; Set the default region and algorithm for the integrated register -; allocator. - -Variable -enum ira_algorithm flag_ira_algorithm = IRA_ALGORITHM_CB - -Variable -enum ira_region flag_ira_region = IRA_REGION_MIXED - ; Language specific warning pass for unused results. Variable bool flag_warn_unused_result = false @@ -58,15 +49,6 @@ bool flag_warn_unused_result = false Variable int *param_values -; Floating-point contraction mode, fast by default. -Variable -enum fp_contract_mode flag_fp_contract_mode = FP_CONTRACT_FAST - -; The excess precision specified on the command line, or defaulted by -; the front end. -Variable -enum excess_precision flag_excess_precision_cmdline = EXCESS_PRECISION_DEFAULT - ; Nonzero if we should write GIMPLE bytecode for link-time optimization. Variable int flag_generate_lto @@ -97,14 +79,6 @@ int flag_gen_aux_info = 0 Variable int flag_shlib -; The default visibility for all symbols (unless overridden). -Variable -enum symbol_visibility default_visibility = VISIBILITY_DEFAULT - -; Set to the default thread-local storage (tls) model to use. -Variable -enum tls_model flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC - ; These two are really VEC(char_p,heap) *. Variable @@ -187,6 +161,12 @@ enum graph_dump_types graph_dump_format = no_graph Variable char *help_printed +; Which enums have been printed by --help. 0 = not printed, no +; relevant options seen, 1 = relevant option seen, not yet printed, 2 +; = printed. +Variable +char *help_enum_printed + ; The number of columns for --help output. Variable unsigned int help_columns @@ -897,9 +877,22 @@ Common Report Var(flag_delete_null_pointer_checks) Init(1) Optimization Delete useless null pointer checks fdiagnostics-show-location= -Common Joined RejectNegative +Common Joined RejectNegative Enum(diagnostic_prefixing_rule) -fdiagnostics-show-location=[once|every-line] How often to emit source location at the beginning of line-wrapped diagnostics +; Required for these enum values. +SourceInclude +pretty-print.h + +Enum +Name(diagnostic_prefixing_rule) Type(int) + +EnumValue +Enum(diagnostic_prefixing_rule) String(once) Value(DIAGNOSTICS_SHOW_PREFIX_ONCE) + +EnumValue +Enum(diagnostic_prefixing_rule) String(every-line) Value(DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE) + fdiagnostics-show-option Common Var(flag_diagnostics_show_option) Init(1) Amend appropriate diagnostic messages with the command line option that controls them @@ -972,9 +965,18 @@ Common Report Var(flag_expensive_optimizations) Optimization Perform a number of minor, expensive optimizations fexcess-precision= -Common Joined RejectNegative +Common Joined RejectNegative Enum(excess_precision) Var(flag_excess_precision_cmdline) Init(EXCESS_PRECISION_DEFAULT) -fexcess-precision=[fast|standard] Specify handling of excess floating-point precision +Enum +Name(excess_precision) Type(enum excess_precision) UnknownError(unknown excess precision style %qs) + +EnumValue +Enum(excess_precision) String(fast) Value(EXCESS_PRECISION_FAST) + +EnumValue +Enum(excess_precision) String(standard) Value(EXCESS_PRECISION_STANDARD) + ffast-math Common @@ -999,9 +1001,22 @@ Common Report Var(flag_forward_propagate) Optimization Perform a forward propagation pass on RTL ffp-contract= -Common Joined RejectNegative +Common Joined RejectNegative Enum(fp_contract_mode) Var(flag_fp_contract_mode) Init(FP_CONTRACT_FAST) -ffp-contract=[off|on|fast] Perform floating-point expression contraction. +Enum +Name(fp_contract_mode) Type(enum fp_contract_mode) UnknownError(unknown floating point contraction style %qs) + +EnumValue +Enum(fp_contract_mode) String(off) Value(FP_CONTRACT_OFF) + +; Not implemented, fall back to conservative FP_CONTRACT_OFF. +EnumValue +Enum(fp_contract_mode) String(on) Value(FP_CONTRACT_OFF) + +EnumValue +Enum(fp_contract_mode) String(fast) Value(FP_CONTRACT_FAST) + ; Nonzero means don't put addresses of constant functions in registers. ; Used for compiling the Unix kernel, where strange substitutions are ; done on the assembly output. @@ -1183,13 +1198,34 @@ Perform structure layout optimizations based on profiling information. fira-algorithm= -Common Joined RejectNegative +Common Joined RejectNegative Enum(ira_algorithm) Var(flag_ira_algorithm) Init(IRA_ALGORITHM_CB) -fira-algorithm=[CB|priority] Set the used IRA algorithm +Enum +Name(ira_algorithm) Type(enum ira_algorithm) UnknownError(unknown IRA algorithm %qs) + +EnumValue +Enum(ira_algorithm) String(CB) Value(IRA_ALGORITHM_CB) + +EnumValue +Enum(ira_algorithm) String(priority) Value(IRA_ALGORITHM_PRIORITY) + fira-region= -Common Joined RejectNegative +Common Joined RejectNegative Enum(ira_region) Var(flag_ira_region) Init(IRA_REGION_MIXED) -fira-region=[one|all|mixed] Set regions for IRA +Enum +Name(ira_region) Type(enum ira_region) UnknownError(unknown IRA region %qs) + +EnumValue +Enum(ira_region) String(one) Value(IRA_REGION_ONE) + +EnumValue +Enum(ira_region) String(all) Value(IRA_REGION_ALL) + +EnumValue +Enum(ira_region) String(mixed) Value(IRA_REGION_MIXED) + fira-loop-pressure Common Report Var(flag_ira_loop_pressure) Use IRA based register pressure calculation @@ -1718,9 +1754,24 @@ Common Report Var(time_report) Report the time taken by each compiler pass ftls-model= -Common Joined RejectNegative +Common Joined RejectNegative Enum(tls_model) Var(flag_tls_default) Init(TLS_MODEL_GLOBAL_DYNAMIC) -ftls-model=[global-dynamic|local-dynamic|initial-exec|local-exec] Set the default thread-local storage code generation model +Enum +Name(tls_model) Type(enum tls_model) UnknownError(unknown TLS model %qs) + +EnumValue +Enum(tls_model) String(global-dynamic) Value(TLS_MODEL_GLOBAL_DYNAMIC) + +EnumValue +Enum(tls_model) String(local-dynamic) Value(TLS_MODEL_LOCAL_DYNAMIC) + +EnumValue +Enum(tls_model) String(initial-exec) Value(TLS_MODEL_INITIAL_EXEC) + +EnumValue +Enum(tls_model) String(local-exec) Value(TLS_MODEL_LOCAL_EXEC) + ftoplevel-reorder Common Report Var(flag_toplevel_reorder) Init(2) Optimization Reorder top level functions, variables, and asms @@ -1973,9 +2024,23 @@ Common Report Var(flag_verbose_asm) Add extra commentary to assembler output fvisibility= -Common Joined RejectNegative +Common Joined RejectNegative Enum(symbol_visibility) Var(default_visibility) Init(VISIBILITY_DEFAULT) -fvisibility=[default|internal|hidden|protected] Set the default symbol visibility +Enum +Name(symbol_visibility) Type(enum symbol_visibility) UnknownError(unrecognized visibility value %qs) + +EnumValue +Enum(symbol_visibility) String(default) Value(VISIBILITY_DEFAULT) + +EnumValue +Enum(symbol_visibility) String(internal) Value(VISIBILITY_INTERNAL) + +EnumValue +Enum(symbol_visibility) String(hidden) Value(VISIBILITY_HIDDEN) + +EnumValue +Enum(symbol_visibility) String(protected) Value(VISIBILITY_PROTECTED) fvpt Common Report Var(flag_value_profile_transformations) Optimization diff --git a/gcc/doc/options.texi b/gcc/doc/options.texi index 1bdf83dcf85..1c8f5d9f134 100644 --- a/gcc/doc/options.texi +++ b/gcc/doc/options.texi @@ -78,6 +78,63 @@ two fields: the string @samp{SourceInclude} and the name of the include file. @item +An enumeration record to define a set of strings that may be used as +arguments to an option or options. These records have three fields: +the string @samp{Enum}, a space-separated list of properties and help +text used to describe the set of strings in @option{--help} output. +Properties use the same format as option properties; the following are +valid: +@table @code +@item Name(@var{name}) +This property is required; @var{name} must be a name (suitable for use +in C identifiers) used to identify the set of strings in @code{Enum} +option properties. + +@item Type(@var{type}) +This property is required; @var{type} is the C type for variables set +by options using this enumeration together with @code{Var}. + +@item UnknownError(@var{message}) +The message @var{message} will be used as an error message if the +argument is invalid; for enumerations without @code{UnknownError}, a +generic error message is used. @var{message} should contain a single +@samp{%qs} format, which will be used to format the invalid argument. +@end table + +@item +An enumeration value record to define one of the strings in a set +given in an @samp{Enum} record. These records have two fields: the +string @samp{EnumValue} and a space-separated list of properties. +Properties use the same format as option properties; the following are +valid: +@table @code +@item Enum(@var{name}) +This property is required; @var{name} says which @samp{Enum} record +this @samp{EnumValue} record corresponds to. + +@item String(@var{string}) +This property is required; @var{string} is the string option argument +being described by this record. + +@item Value(@var{value}) +This property is required; it says what value (representable as +@code{int}) should be used for the given string. + +@item Canonical +This property is optional. If present, it says the present string is +the canonical one among all those with the given value. Other strings +yielding that value will be mapped to this one so specs do not need to +handle them. + +@item DriverOnly +This property is optional. If present, the present string will only +be accepted by the driver. This is used for cases such as +@option{-march=native} that are processed by the driver so that +@samp{gcc -v} shows how the options chosen depended on the system on +which the compiler was run. +@end table + +@item An option definition record. These records have the following fields: @enumerate @item @@ -227,6 +284,13 @@ If the option takes an argument and has the @code{UInteger} property, @var{var} is an integer variable that stores the value of the argument. @item +If the option takes an argument and has the @code{Enum} property, +@var{var} is a variable (type given in the @code{Type} property of the +@samp{Enum} record whose @code{Name} property has the same argument as +the @code{Enum} property of this option) that stores the value of the +argument. + +@item If the option has the @code{Defer} property, @var{var} is a pointer to a @code{VEC(cl_deferred_option,heap)} that stores the option for later processing. (@var{var} is declared with type @code{void *} and needs @@ -287,6 +351,12 @@ The main purpose of this property is to support synonymous options. The first option should use @samp{Mask(@var{name})} and the others should use @samp{Mask(@var{name}) MaskExists}. +@item Enum(@var{name}) +The option's argument is a string from the set of strings associated +with the corresponding @samp{Enum} record. The string is checked and +converted to the integer specified in the corresponding +@samp{EnumValue} record before being passed to option handlers. + @item Defer The option should be stored in a vector, specified with @code{Var}, for later processing. diff --git a/gcc/opt-functions.awk b/gcc/opt-functions.awk index 99bbb314475..9aff0e0046b 100644 --- a/gcc/opt-functions.awk +++ b/gcc/opt-functions.awk @@ -150,6 +150,10 @@ function var_type(flags) { if (flag_set_p("Defer", flags)) return "void *" + else if (flag_set_p("Enum.*", flags)) { + en = opt_args("Enum", flags); + return enum_type[en] " " + } else if (!flag_set_p("Joined.*", flags) && !flag_set_p("Separate", flags)) return "int " else if (flag_set_p("UInteger", flags)) @@ -176,33 +180,37 @@ function var_type_struct(flags) } # Given that an option has flags FLAGS, return an initializer for the -# "var_cond" and "var_value" fields of its cl_options[] entry. +# "var_enum", "var_type" and "var_value" fields of its cl_options[] entry. function var_set(flags) { if (flag_set_p("Defer", flags)) - return "CLVC_DEFER, 0" + return "0, CLVC_DEFER, 0" s = nth_arg(1, opt_args("Var", flags)) if (s != "") - return "CLVC_EQUAL, " s + return "0, CLVC_EQUAL, " s s = opt_args("Mask", flags); if (s != "") { vn = var_name(flags); if (vn) - return "CLVC_BIT_SET, OPTION_MASK_" s + return "0, CLVC_BIT_SET, OPTION_MASK_" s else - return "CLVC_BIT_SET, MASK_" s + return "0, CLVC_BIT_SET, MASK_" s } s = nth_arg(0, opt_args("InverseMask", flags)); if (s != "") { vn = var_name(flags); if (vn) - return "CLVC_BIT_CLEAR, OPTION_MASK_" s + return "0, CLVC_BIT_CLEAR, OPTION_MASK_" s else - return "CLVC_BIT_CLEAR, MASK_" s + return "0, CLVC_BIT_CLEAR, MASK_" s + } + if (flag_set_p("Enum.*", flags)) { + en = opt_args("Enum", flags); + return enum_index[en] ", CLVC_ENUM, 0" } if (var_type(flags) == "const char *") - return "CLVC_STRING, 0" - return "CLVC_BOOLEAN, 0" + return "0, CLVC_STRING, 0" + return "0, CLVC_BOOLEAN, 0" } # Given that an option called NAME has flags FLAGS, return an initializer diff --git a/gcc/optc-gen.awk b/gcc/optc-gen.awk index 3bf0b8eacbb..4aaa2a6041a 100644 --- a/gcc/optc-gen.awk +++ b/gcc/optc-gen.awk @@ -34,6 +34,7 @@ BEGIN { n_extra_target_vars = 0 n_extra_c_includes = 0 n_extra_h_includes = 0 + n_enums = 0 quote = "\042" comma = "," FS=SUBSEP @@ -80,6 +81,31 @@ BEGIN { else if ($1 == "SourceInclude") { extra_c_includes[n_extra_c_includes++] = $2; } + else if ($1 == "Enum") { + props = $2 + name = opt_args("Name", props) + type = opt_args("Type", props) + unknown_error = opt_args("UnknownError", props) + enum_names[n_enums] = name + enum_type[name] = type + enum_index[name] = n_enums + enum_unknown_error[name] = unknown_error + enum_help[name] = $3 + n_enums++ + } + else if ($1 == "EnumValue") { + props = $2 + enum_name = opt_args("Enum", props) + string = opt_args("String", props) + value = opt_args("Value", props) + val_flags = "0" + val_flags = val_flags \ + test_flag("Canonical", props, "| CL_ENUM_CANONICAL") \ + test_flag("DriverOnly", props, "| CL_ENUM_DRIVER_ONLY") + enum_data[enum_name] = enum_data[enum_name] \ + " { " quote string quote ", " value ", " val_flags \ + " },\n" + } else { name = opt_args("Mask", $1) if (name == "") { @@ -116,6 +142,56 @@ if (n_extra_c_includes > 0) { print "" } +for (i = 0; i < n_enums; i++) { + name = enum_names[i] + type = enum_type[name] + print "static const struct cl_enum_arg cl_enum_" name \ + "_data[] = " + print "{" + print enum_data[name] " { NULL, 0, 0 }" + print "};" + print "" + print "static void" + print "cl_enum_" name "_set (void *var, int value)" + print "{" + print " *((" type " *) var) = (" type ") value;" + print "}" + print "" + print "static int" + print "cl_enum_" name "_get (const void *var)" + print "{" + print " return (int) *((const " type " *) var);" + print "}" + print "" +} + +print "const struct cl_enum cl_enums[] =" +print "{" +for (i = 0; i < n_enums; i++) { + name = enum_names[i] + ehelp = enum_help[name] + if (ehelp == "") + ehelp = "NULL" + else + ehelp = quote ehelp quote + unknown_error = enum_unknown_error[name] + if (unknown_error == "") + unknown_error = "NULL" + else + unknown_error = quote unknown_error quote + print " {" + print " " ehelp "," + print " " unknown_error "," + print " cl_enum_" name "_data," + print " sizeof (" enum_type[name] ")," + print " cl_enum_" name "_set," + print " cl_enum_" name "_get" + print " }," +} +print "};" +print "const unsigned int cl_enums_count = " n_enums ";" +print "" + have_save = 0; if (n_extra_target_vars) have_save = 1 diff --git a/gcc/opth-gen.awk b/gcc/opth-gen.awk index 9fafb99d460..db32121f914 100644 --- a/gcc/opth-gen.awk +++ b/gcc/opth-gen.awk @@ -77,6 +77,31 @@ BEGIN { else if ($1 == "SourceInclude") { extra_c_includes[n_extra_c_includes++] = $2; } + else if ($1 == "Enum") { + props = $2 + name = opt_args("Name", props) + type = opt_args("Type", props) + unknown_error = opt_args("UnknownError", props) + enum_names[n_enums] = name + enum_type[name] = type + enum_index[name] = n_enums + enum_unknown_error[name] = unknown_error + enum_help[name] = $3 + n_enums++ + } + else if ($1 == "EnumValue") { + props = $2 + enum_name = opt_args("Enum", props) + string = opt_args("String", props) + value = opt_args("Value", props) + val_flags = "0" + val_flags = val_flags \ + test_flag("Canonical", props, "| CL_ENUM_CANONICAL") \ + test_flag("DriverOnly", props, "| CL_ENUM_DRIVER_ONLY") + enum_data[enum_name] = enum_data[enum_name] \ + " { " quote string quote ", " value ", " val_flags \ + " },\n" + } else { name = opt_args("Mask", $1) if (name == "") { diff --git a/gcc/opts-common.c b/gcc/opts-common.c index 9a574024d37..e6cb552df13 100644 --- a/gcc/opts-common.c +++ b/gcc/opts-common.c @@ -181,6 +181,70 @@ option_ok_for_language (const struct cl_option *option, return true; } +/* Return whether ENUM_ARG is OK for the language given by + LANG_MASK. */ + +static bool +enum_arg_ok_for_language (const struct cl_enum_arg *enum_arg, + unsigned int lang_mask) +{ + return (lang_mask & CL_DRIVER) || !(enum_arg->flags & CL_ENUM_DRIVER_ONLY); +} + +/* Look up ARG in ENUM_ARGS for language LANG_MASK, returning true and + storing the value in *VALUE if found, and returning false without + modifying *VALUE if not found. */ + +static bool +enum_arg_to_value (const struct cl_enum_arg *enum_args, + const char *arg, int *value, unsigned int lang_mask) +{ + unsigned int i; + + for (i = 0; enum_args[i].arg != NULL; i++) + if (strcmp (arg, enum_args[i].arg) == 0 + && enum_arg_ok_for_language (&enum_args[i], lang_mask)) + { + *value = enum_args[i].value; + return true; + } + + return false; +} + +/* Look of VALUE in ENUM_ARGS for language LANG_MASK and store the + corresponding string in *ARGP, returning true if the found string + was marked as canonical, false otherwise. If VALUE is not found + (which may be the case for uninitialized values if the relevant + option has not been passed), set *ARGP to NULL and return + false. */ + +bool +enum_value_to_arg (const struct cl_enum_arg *enum_args, + const char **argp, int value, unsigned int lang_mask) +{ + unsigned int i; + + for (i = 0; enum_args[i].arg != NULL; i++) + if (enum_args[i].value == value + && (enum_args[i].flags & CL_ENUM_CANONICAL) + && enum_arg_ok_for_language (&enum_args[i], lang_mask)) + { + *argp = enum_args[i].arg; + return true; + } + + for (i = 0; enum_args[i].arg != NULL; i++) + if (enum_args[i].value == value + && enum_arg_ok_for_language (&enum_args[i], lang_mask)) + { + *argp = enum_args[i].arg; + return false; + } + + *argp = NULL; + return false; +} /* Fill in the canonical option part of *DECODED with an option described by OPT_INDEX, ARG and VALUE. */ @@ -508,6 +572,24 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask, errors |= CL_ERR_UINT_ARG; } + /* If the switch takes an enumerated argument, convert it. */ + if (arg && (option->var_type == CLVC_ENUM)) + { + const struct cl_enum *e = &cl_enums[option->var_enum]; + + gcc_assert (value == 1); + if (enum_arg_to_value (e->values, arg, &value, lang_mask)) + { + const char *carg = NULL; + + if (enum_value_to_arg (e->values, &carg, value, lang_mask)) + arg = carg; + gcc_assert (carg != NULL); + } + else + errors |= CL_ERR_ENUM_ARG; + } + done: decoded->opt_index = opt_index; decoded->arg = arg; @@ -900,6 +982,36 @@ read_cmdline_option (struct gcc_options *opts, return; } + if (decoded->errors & CL_ERR_ENUM_ARG) + { + const struct cl_enum *e = &cl_enums[option->var_enum]; + unsigned int i; + size_t len; + char *s, *p; + + if (e->unknown_error) + error_at (loc, e->unknown_error, decoded->arg); + else + error_at (loc, "unrecognized argument in option %qs", opt); + + len = 0; + for (i = 0; e->values[i].arg != NULL; i++) + len += strlen (e->values[i].arg) + 1; + + s = XALLOCAVEC (char, len); + p = s; + for (i = 0; e->values[i].arg != NULL; i++) + { + size_t arglen = strlen (e->values[i].arg); + memcpy (p, e->values[i].arg, arglen); + p[arglen] = ' '; + p += arglen + 1; + } + p[-1] = 0; + inform (loc, "valid arguments to %qs are: %s", option->opt_text, s); + return; + } + gcc_assert (!decoded->errors); if (!handle_option (opts, opts_set, decoded, lang_mask, DK_UNSPECIFIED, @@ -959,6 +1071,16 @@ set_option (struct gcc_options *opts, struct gcc_options *opts_set, *(const char **) set_flag_var = ""; break; + case CLVC_ENUM: + { + const struct cl_enum *e = &cl_enums[option->var_enum]; + + e->set (flag_var, value); + if (set_flag_var) + e->set (set_flag_var, 1); + } + break; + case CLVC_DEFER: { VEC(cl_deferred_option,heap) *vec @@ -1020,6 +1142,7 @@ option_enabled (int opt_idx, void *opts) return (*(int *) flag_var & option->var_value) != 0; case CLVC_STRING: + case CLVC_ENUM: case CLVC_DEFER: break; } @@ -1060,6 +1183,11 @@ get_option_state (struct gcc_options *opts, int option, state->size = strlen ((const char *) state->data) + 1; break; + case CLVC_ENUM: + state->data = flag_var; + state->size = cl_enums[cl_options[option].var_enum].var_size; + break; + case CLVC_DEFER: return false; } diff --git a/gcc/opts.c b/gcc/opts.c index cd69fe1bd9f..cd41c2ab317 100644 --- a/gcc/opts.c +++ b/gcc/opts.c @@ -885,7 +885,8 @@ print_filtered_help (unsigned int include_flags, unsigned int exclude_flags, unsigned int any_flags, unsigned int columns, - struct gcc_options *opts) + struct gcc_options *opts, + unsigned int lang_mask) { unsigned int i; const char *help; @@ -918,6 +919,9 @@ print_filtered_help (unsigned int include_flags, if (!opts->x_help_printed) opts->x_help_printed = XCNEWVAR (char, cl_options_count); + if (!opts->x_help_enum_printed) + opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count); + for (i = 0; i < cl_options_count; i++) { char new_help[128]; @@ -999,6 +1003,20 @@ print_filtered_help (unsigned int include_flags, sizeof (new_help) - strlen (new_help), * (const char **) flag_var); } + else if (option->var_type == CLVC_ENUM) + { + const struct cl_enum *e = &cl_enums[option->var_enum]; + int value; + const char *arg = NULL; + + value = e->get (flag_var); + enum_value_to_arg (e->values, &arg, value, lang_mask); + if (arg == NULL) + arg = _("[default]"); + snprintf (new_help + strlen (new_help), + sizeof (new_help) - strlen (new_help), + arg); + } else sprintf (new_help + strlen (new_help), "%#x", * (int *) flag_var); @@ -1013,6 +1031,10 @@ print_filtered_help (unsigned int include_flags, wrap_help (help, opt, len, columns); displayed = true; + + if (option->var_type == CLVC_ENUM + && opts->x_help_enum_printed[option->var_enum] != 2) + opts->x_help_enum_printed[option->var_enum] = 1; } if (! found) @@ -1038,18 +1060,57 @@ print_filtered_help (unsigned int include_flags, printf (_(" All options with the desired characteristics have already been displayed\n")); putchar ('\n'); + + /* Print details of enumerated option arguments, if those + enumerations have help text headings provided. If no help text + is provided, presume that the possible values are listed in the + help text for the relevant options. */ + for (i = 0; i < cl_enums_count; i++) + { + unsigned int j, pos; + + if (opts->x_help_enum_printed[i] != 1) + continue; + if (cl_enums[i].help == NULL) + continue; + printf (" %s\n ", _(cl_enums[i].help)); + pos = 4; + for (j = 0; cl_enums[i].values[j].arg != NULL; j++) + { + unsigned int len = strlen (cl_enums[i].values[j].arg); + + if (pos > 4 && pos + 1 + len <= columns) + { + printf (" %s", cl_enums[i].values[j].arg); + pos += 1 + len; + } + else + { + if (pos > 4) + { + printf ("\n "); + pos = 4; + } + printf ("%s", cl_enums[i].values[j].arg); + pos += len; + } + } + printf ("\n\n"); + opts->x_help_enum_printed[i] = 2; + } } /* Display help for a specified type of option. The options must have ALL of the INCLUDE_FLAGS set ANY of the flags in the ANY_FLAGS set and NONE of the EXCLUDE_FLAGS set. The current option state is in - OPTS. */ + OPTS; LANG_MASK is used for interpreting enumerated option state. */ static void print_specific_help (unsigned int include_flags, unsigned int exclude_flags, unsigned int any_flags, - struct gcc_options *opts) + struct gcc_options *opts, + unsigned int lang_mask) { unsigned int all_langs_mask = (1U << cl_lang_count) - 1; const char * description = NULL; @@ -1145,7 +1206,7 @@ print_specific_help (unsigned int include_flags, printf ("%s%s:\n", description, descrip_extra); print_filtered_help (include_flags, exclude_flags, any_flags, - opts->x_help_columns, opts); + opts->x_help_columns, opts, lang_mask); } /* Handle target- and language-independent options. Return zero to @@ -1187,19 +1248,20 @@ common_handle_option (struct gcc_options *opts, /* First display any single language specific options. */ for (i = 0; i < cl_lang_count; i++) print_specific_help - (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts); + (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts, + lang_mask); /* Next display any multi language specific options. */ - print_specific_help (0, undoc_mask, all_langs_mask, opts); + print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask); /* Then display any remaining, non-language options. */ for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1) if (i != CL_DRIVER) - print_specific_help (i, undoc_mask, 0, opts); + print_specific_help (i, undoc_mask, 0, opts, lang_mask); opts->x_exit_after_options = true; break; } case OPT__target_help: - print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts); + print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts, lang_mask); opts->x_exit_after_options = true; /* Allow the target a chance to give the user some additional information. */ @@ -1321,7 +1383,8 @@ common_handle_option (struct gcc_options *opts, } if (include_flags) - print_specific_help (include_flags, exclude_flags, 0, opts); + print_specific_help (include_flags, exclude_flags, 0, opts, + lang_mask); opts->x_exit_after_options = true; break; } @@ -1405,13 +1468,7 @@ common_handle_option (struct gcc_options *opts, break; case OPT_fdiagnostics_show_location_: - if (!strcmp (arg, "once")) - diagnostic_prefixing_rule (dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE; - else if (!strcmp (arg, "every-line")) - diagnostic_prefixing_rule (dc) - = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE; - else - return false; + diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value; break; case OPT_fdiagnostics_show_option: @@ -1422,27 +1479,6 @@ common_handle_option (struct gcc_options *opts, /* Deferred. */ break; - case OPT_ffp_contract_: - if (!strcmp (arg, "on")) - /* Not implemented, fall back to conservative FP_CONTRACT_OFF. */ - opts->x_flag_fp_contract_mode = FP_CONTRACT_OFF; - else if (!strcmp (arg, "off")) - opts->x_flag_fp_contract_mode = FP_CONTRACT_OFF; - else if (!strcmp (arg, "fast")) - opts->x_flag_fp_contract_mode = FP_CONTRACT_FAST; - else - error_at (loc, "unknown floating point contraction style \"%s\"", arg); - break; - - case OPT_fexcess_precision_: - if (!strcmp (arg, "fast")) - opts->x_flag_excess_precision_cmdline = EXCESS_PRECISION_FAST; - else if (!strcmp (arg, "standard")) - opts->x_flag_excess_precision_cmdline = EXCESS_PRECISION_STANDARD; - else - error_at (loc, "unknown excess precision style \"%s\"", arg); - break; - case OPT_ffast_math: set_fast_math_flags (opts, value); break; @@ -1542,21 +1578,6 @@ common_handle_option (struct gcc_options *opts, dc->show_column = value; break; - case OPT_fvisibility_: - { - if (!strcmp(arg, "default")) - opts->x_default_visibility = VISIBILITY_DEFAULT; - else if (!strcmp(arg, "internal")) - opts->x_default_visibility = VISIBILITY_INTERNAL; - else if (!strcmp(arg, "hidden")) - opts->x_default_visibility = VISIBILITY_HIDDEN; - else if (!strcmp(arg, "protected")) - opts->x_default_visibility = VISIBILITY_PROTECTED; - else - error_at (loc, "unrecognized visibility value \"%s\"", arg); - } - break; - case OPT_frandom_seed: /* The real switch is -fno-random-seed. */ if (value) @@ -1621,39 +1642,6 @@ common_handle_option (struct gcc_options *opts, vect_set_verbosity_level (opts, value); break; - case OPT_ftls_model_: - if (!strcmp (arg, "global-dynamic")) - opts->x_flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC; - else if (!strcmp (arg, "local-dynamic")) - opts->x_flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC; - else if (!strcmp (arg, "initial-exec")) - opts->x_flag_tls_default = TLS_MODEL_INITIAL_EXEC; - else if (!strcmp (arg, "local-exec")) - opts->x_flag_tls_default = TLS_MODEL_LOCAL_EXEC; - else - warning_at (loc, 0, "unknown tls-model \"%s\"", arg); - break; - - case OPT_fira_algorithm_: - if (!strcmp (arg, "CB")) - opts->x_flag_ira_algorithm = IRA_ALGORITHM_CB; - else if (!strcmp (arg, "priority")) - opts->x_flag_ira_algorithm = IRA_ALGORITHM_PRIORITY; - else - warning_at (loc, 0, "unknown ira algorithm \"%s\"", arg); - break; - - case OPT_fira_region_: - if (!strcmp (arg, "one")) - opts->x_flag_ira_region = IRA_REGION_ONE; - else if (!strcmp (arg, "all")) - opts->x_flag_ira_region = IRA_REGION_ALL; - else if (!strcmp (arg, "mixed")) - opts->x_flag_ira_region = IRA_REGION_MIXED; - else - warning_at (loc, 0, "unknown ira region \"%s\"", arg); - break; - case OPT_g: set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set, loc); diff --git a/gcc/opts.h b/gcc/opts.h index fe7b8faef0d..c3907fd0048 100644 --- a/gcc/opts.h +++ b/gcc/opts.h @@ -42,6 +42,10 @@ enum cl_var_type { argument. */ CLVC_STRING, + /* The switch takes an enumerated argument (VAR_ENUM says what + enumeration) and FLAG_VAR points to that argument. */ + CLVC_ENUM, + /* The switch should be stored in the VEC pointed to by FLAG_VAR for later processing. */ CLVC_DEFER @@ -61,6 +65,7 @@ struct cl_option int neg_index; unsigned int flags; unsigned short flag_var_offset; + unsigned short var_enum; enum cl_var_type var_type; int var_value; }; @@ -111,6 +116,52 @@ extern const unsigned int cl_lang_count; #define CL_UINTEGER (1 << 29) /* Argument is an integer >=0. */ #define CL_UNDOCUMENTED (1 << 30) /* Do not output with --help. */ +/* Flags for an enumerated option argument. */ +#define CL_ENUM_CANONICAL (1 << 0) /* Canonical for this value. */ +#define CL_ENUM_DRIVER_ONLY (1 << 1) /* Only accepted in the driver. */ + +/* Structure describing an enumerated option argument. */ + +struct cl_enum_arg +{ + /* The argument text, or NULL at the end of the array. */ + const char *arg; + + /* The corresponding integer value. */ + int value; + + /* Flags associated with this argument. */ + unsigned int flags; +}; + +/* Structure describing an enumerated set of option arguments. */ + +struct cl_enum +{ + /* Help text, or NULL if the values should not be listed in --help + output. */ + const char *help; + + /* Error message for unknown arguments, or NULL to use a generic + error. */ + const char *unknown_error; + + /* Array of possible values. */ + const struct cl_enum_arg *values; + + /* The size of the type used to store a value. */ + size_t var_size; + + /* Function to set a variable of this type. */ + void (*set) (void *var, int value); + + /* Function to get the value of a variable of this type. */ + int (*get) (const void *var); +}; + +extern const struct cl_enum cl_enums[]; +extern const unsigned int cl_enums_count; + /* Possible ways in which a command-line option may be erroneous. These do not include not being known at all; an option index of OPT_SPECIAL_unknown is used for that. */ @@ -119,7 +170,8 @@ extern const unsigned int cl_lang_count; #define CL_ERR_MISSING_ARG (1 << 1) /* Argument required but missing. */ #define CL_ERR_WRONG_LANG (1 << 2) /* Option for wrong language. */ #define CL_ERR_UINT_ARG (1 << 3) /* Bad unsigned integer argument. */ -#define CL_ERR_NEGATIVE (1 << 4) /* Negative form of option +#define CL_ERR_ENUM_ARG (1 << 4) /* Bad enumerated argument. */ +#define CL_ERR_NEGATIVE (1 << 5) /* Negative form of option not permitted (together with OPT_SPECIAL_unknown). */ @@ -230,6 +282,9 @@ extern unsigned num_in_fnames; size_t find_opt (const char *input, int lang_mask); extern int integral_argument (const char *arg); +extern bool enum_value_to_arg (const struct cl_enum_arg *enum_args, + const char **argp, int value, + unsigned int lang_mask); extern void decode_cmdline_options_to_array (unsigned int argc, const char **argv, unsigned int lang_mask, diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog index da65bafec6b..d6d3a227450 100644 --- a/gcc/po/ChangeLog +++ b/gcc/po/ChangeLog @@ -1,3 +1,7 @@ +2010-11-26 Joseph Myers + + * exgettext: Handle UnknownError. + 2010-11-21 Joseph Myers * sv.po: Update. diff --git a/gcc/po/exgettext b/gcc/po/exgettext index f422c1e1acb..7642dc56aad 100644 --- a/gcc/po/exgettext +++ b/gcc/po/exgettext @@ -246,6 +246,17 @@ echo "scanning option files..." >&2 printf("#line %d \"%s\"\n", lineno, file) printf("_(\"%s\")\n", line) } + if ((field == 1) && /UnknownError/) { + line = $0 + sub(".*UnknownError\\(", "", line) + if (line ~ "^{") { + sub("^{", "", line) + sub("}\\).*", "", line) + } else + sub("\\).*", "", line) + printf("#line %d \"%s\"\n", lineno, file) + printf("_(\"%s\")\n", line) + } if ((field == 1) && /Warn\(/) { line = $0 sub(".*Warn\\(", "", line)