OSDN Git Service

* doc/options.texi (Enum, EnumValue): Document new record types.
authorjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Nov 2010 23:18:28 +0000 (23:18 +0000)
committerjsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 26 Nov 2010 23:18:28 +0000 (23:18 +0000)
(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

gcc/ChangeLog
gcc/common.opt
gcc/doc/options.texi
gcc/opt-functions.awk
gcc/optc-gen.awk
gcc/opth-gen.awk
gcc/opts-common.c
gcc/opts.c
gcc/opts.h
gcc/po/ChangeLog
gcc/po/exgettext

index 808afed..659ca46 100644 (file)
@@ -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
index f4523db..57f5b0a 100644 (file)
@@ -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
index 1bdf83d..1c8f5d9 100644 (file)
@@ -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.
index 99bbb31..9aff0e0 100644 (file)
@@ -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
index 3bf0b8e..4aaa2a6 100644 (file)
@@ -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
index 9fafb99..db32121 100644 (file)
@@ -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 == "") {
index 9a57402..e6cb552 100644 (file)
@@ -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;
     }
index cd69fe1..cd41c2a 100644 (file)
@@ -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);
index fe7b8fa..c3907fd 100644 (file)
@@ -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,
index da65baf..d6d3a22 100644 (file)
@@ -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.
index f422c1e..7642dc5 100644 (file)
@@ -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)