summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2010-11-26 23:18:28 +0000
committerJoseph Myers <jsm28@gcc.gnu.org>2010-11-26 23:18:28 +0000
commite6d4b9841c35629de91c36ba40ed247fef749037 (patch)
tree36e9808ac190cda7d402aca282c7bbe11cbf8b71
parent8a1ffe230e5f07f6eef4bd30088f4245783109ec (diff)
downloadgcc-e6d4b9841c35629de91c36ba40ed247fef749037.tar.gz
options.texi (Enum, EnumValue): Document new record types.
* 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. From-SVN: r167190
-rw-r--r--gcc/ChangeLog39
-rw-r--r--gcc/common.opt131
-rw-r--r--gcc/doc/options.texi70
-rw-r--r--gcc/opt-functions.awk26
-rw-r--r--gcc/optc-gen.awk76
-rw-r--r--gcc/opth-gen.awk25
-rw-r--r--gcc/opts-common.c128
-rw-r--r--gcc/opts.c158
-rw-r--r--gcc/opts.h57
-rw-r--r--gcc/po/ChangeLog4
-rw-r--r--gcc/po/exgettext11
11 files changed, 597 insertions, 128 deletions
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 <joseph@codesourcery.com>
+
+ * 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 <amylaar@spamcop.net>
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 <joseph@codesourcery.com>
+
+ * exgettext: Handle UnknownError.
+
2010-11-21 Joseph Myers <joseph@codesourcery.com>
* 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)