From 086a18414ad6c07d0ee79990a971fdc7387af7c1 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 24 Mar 2008 03:48:29 +0000 Subject: [PATCH] * options.cc: Include "demangle.h". (parse_optional_string): New function. (parse_long_option): Handle takes_optional_argument. (parse_short_option): Update dash_z initializer. Handle takes_optional_argument. (General_options::General_options): Initialize do_demangle_. (General_options::finalize): Set do_demangle_. Handle demangling style. * options.h (parse_optional_string): Declare. (struct One_option): Add optional_arg field. Update constructor. Update call constructor calls. Add takes_optional_argument function. (DEFINE_var): Add optional_arg__ parameter. Change all callers. (DEFINE_optional_string): Define. (General_options::demangle): Change from DEFINE_bool to DEFINE_optional_string. (General_options::no_demangle): New function. (General_options::do_demangle): New function. (General_options::set_do_demangle): New function. (General_options::execstack_status_): Move definition to end of class definition. (General_options::static_): Likewise. (General_options::do_demangle_): New field. * object.cc (big_endian>::get_symbol_location_info): Call Options::do_demangle, not Options::demangle. * symtab.cc (demangle): Likewise. --- gold/ChangeLog | 29 ++++++++++++++++++ gold/object.cc | 2 +- gold/options.cc | 41 +++++++++++++++++++++++-- gold/options.h | 81 +++++++++++++++++++++++++++++++++++++------------ gold/symtab.cc | 2 +- 5 files changed, 131 insertions(+), 24 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 07bfd19feed..f1cd70e8140 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,32 @@ +2008-03-23 Ian Lance Taylor + + * options.cc: Include "demangle.h". + (parse_optional_string): New function. + (parse_long_option): Handle takes_optional_argument. + (parse_short_option): Update dash_z initializer. Handle + takes_optional_argument. + (General_options::General_options): Initialize do_demangle_. + (General_options::finalize): Set do_demangle_. Handle demangling + style. + * options.h (parse_optional_string): Declare. + (struct One_option): Add optional_arg field. Update constructor. + Update call constructor calls. Add takes_optional_argument + function. + (DEFINE_var): Add optional_arg__ parameter. Change all callers. + (DEFINE_optional_string): Define. + (General_options::demangle): Change from DEFINE_bool to + DEFINE_optional_string. + (General_options::no_demangle): New function. + (General_options::do_demangle): New function. + (General_options::set_do_demangle): New function. + (General_options::execstack_status_): Move definition to end of + class definition. + (General_options::static_): Likewise. + (General_options::do_demangle_): New field. + * object.cc (big_endian>::get_symbol_location_info): Call + Options::do_demangle, not Options::demangle. + * symtab.cc (demangle): Likewise. + 2008-03-22 Ian Lance Taylor * gold.h: Include and diff --git a/gold/object.cc b/gold/object.cc index ed7917bf4cf..6c81f231bc6 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -1229,7 +1229,7 @@ Sized_relobj::get_symbol_location_info( else { info->enclosing_symbol_name = symbol_names + sym.get_st_name(); - if (parameters->options().demangle()) + if (parameters->options().do_demangle()) { char* demangled_name = cplus_demangle( info->enclosing_symbol_name.c_str(), diff --git a/gold/options.cc b/gold/options.cc index 916ccf4d188..46d84cf5536 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -28,6 +28,7 @@ #include #include "filenames.h" #include "libiberty.h" +#include "demangle.h" #include "debug.h" #include "script.h" @@ -190,6 +191,12 @@ parse_string(const char* option_name, const char* arg, const char** retval) *retval = arg; } +void +parse_optional_string(const char*, const char* arg, const char** retval) +{ + *retval = arg; +} + void parse_dirlist(const char*, const char* arg, Dir_list* retval) { @@ -466,6 +473,8 @@ parse_long_option(int argc, const char** argv, bool equals_only, { if (equals) *arg = equals + 1; + else if (retval->takes_optional_argument()) + *arg = retval->default_value; else if (*i < argc && !equals_only) *arg = argv[(*i)++]; else @@ -496,7 +505,8 @@ parse_short_option(int argc, const char** argv, int pos_in_argv_i, // We handle -z as a special case. static gold::options::One_option dash_z("", gold::options::DASH_Z, - 'z', "", "-z", "Z-OPTION", NULL); + 'z', "", "-z", "Z-OPTION", false, + NULL); gold::options::One_option* retval = NULL; if (this_argv[pos_in_argv_i] == 'z') retval = &dash_z; @@ -524,6 +534,8 @@ parse_short_option(int argc, const char** argv, int pos_in_argv_i, ++(*i); if (this_argv[pos_in_argv_i + 1] != '\0') *arg = this_argv + pos_in_argv_i + 1; + else if (retval->takes_optional_argument()) + *arg = retval->default_value; else if (*i < argc) *arg = argv[(*i)++]; else @@ -550,7 +562,8 @@ namespace gold { General_options::General_options() - : execstack_status_(General_options::EXECSTACK_FROM_INPUT), static_(false) + : execstack_status_(General_options::EXECSTACK_FROM_INPUT), static_(false), + do_demangle_(false) { } @@ -629,6 +642,30 @@ General_options::finalize() else if (this->noexecstack()) this->set_execstack_status(EXECSTACK_NO); + // Handle the optional argument for --demangle. + if (this->user_set_demangle()) + { + this->set_do_demangle(true); + const char* style = this->demangle(); + if (*style != '\0') + { + enum demangling_styles style_code; + + style_code = cplus_demangle_name_to_style(style); + if (style_code == unknown_demangling) + gold_fatal("unknown demangling style '%s'", style); + cplus_demangle_set_style(style_code); + } + } + else if (this->user_set_no_demangle()) + this->set_do_demangle(false); + else + { + // Testing COLLECT_NO_DEMANGLE makes our default demangling + // behaviour identical to that of gcc's linker wrapper. + this->set_do_demangle(getenv("COLLECT_NO_DEMANGLE") == NULL); + } + // If --thread_count is specified, it applies to // --thread-count-{initial,middle,final}, though it doesn't override // them. diff --git a/gold/options.h b/gold/options.h index ee48d112490..a9b546bb2bd 100644 --- a/gold/options.h +++ b/gold/options.h @@ -80,6 +80,10 @@ parse_double(const char* option_name, const char* arg, double* retval); extern void parse_string(const char* option_name, const char* arg, const char** retval); +extern void +parse_optional_string(const char* option_name, const char* arg, + const char** retval); + extern void parse_dirlist(const char* option_name, const char* arg, Dir_list* retval); @@ -114,6 +118,9 @@ enum Dashes // HELPARG is how you define the argument to the option. // --help output is "-shortname HELPARG, --longname HELPARG: HELPSTRING" // HELPARG should be NULL iff the option is a bool and takes no arg. +// OPTIONAL_ARG is true if this option takes an optional argument. An +// optional argument must be specifid as --OPTION=VALUE, not +// --OPTION VALUE. // READER provides parse_to_value, which is a function that will convert // a char* argument into the proper type and store it in some variable. // A One_option struct initializes itself with the global list of options @@ -126,12 +133,13 @@ struct One_option const char* default_value; const char* helpstring; const char* helparg; + bool optional_arg; Struct_var* reader; One_option(const char* ln, Dashes d, char sn, const char* dv, - const char* hs, const char* ha, Struct_var* r) + const char* hs, const char* ha, bool oa, Struct_var* r) : longname(ln), dashes(d), shortname(sn), default_value(dv ? dv : ""), - helpstring(hs), helparg(ha), reader(r) + helpstring(hs), helparg(ha), optional_arg(oa), reader(r) { // In longname, we convert all underscores to dashes, since GNU // style uses dashes in option names. longname is likely to have @@ -153,6 +161,11 @@ struct One_option takes_argument() const { return this->helparg != NULL; } + // Whether the argument is optional. + bool + takes_optional_argument() const + { return this->optional_arg; } + // Register this option with the global list of options. void register_option(); @@ -190,7 +203,7 @@ struct Struct_special : public Struct_var Struct_special(const char* varname, Dashes dashes, char shortname, Parse_function parse_function, const char* helpstring, const char* helparg) - : option(varname, dashes, shortname, "", helpstring, helparg, this), + : option(varname, dashes, shortname, "", helpstring, helparg, false, this), parse(parse_function) { } @@ -212,7 +225,7 @@ struct Struct_special : public Struct_var // type__ for built-in types, and "const type__ &" otherwise. #define DEFINE_var(varname__, dashes__, shortname__, default_value__, \ default_value_as_string__, helpstring__, helparg__, \ - type__, param_type__, parse_fn__) \ + optional_arg__, type__, param_type__, parse_fn__) \ public: \ param_type__ \ varname__() const \ @@ -227,7 +240,7 @@ struct Struct_special : public Struct_var { \ Struct_##varname__() \ : option(#varname__, dashes__, shortname__, default_value_as_string__, \ - helpstring__, helparg__, this), \ + helpstring__, helparg__, optional_arg__, this), \ user_set_via_option(false), value(default_value__) \ { } \ \ @@ -256,12 +269,12 @@ struct Struct_special : public Struct_var helpstring__, no_helpstring__) \ DEFINE_var(varname__, dashes__, shortname__, default_value__, \ default_value__ ? "true" : "false", helpstring__, NULL, \ - bool, bool, options::parse_bool) \ + false, bool, bool, options::parse_bool) \ struct Struct_no_##varname__ : public options::Struct_var \ { \ Struct_no_##varname__() : option("no-" #varname__, dashes__, '\0', \ default_value__ ? "false" : "true", \ - no_helpstring__, NULL, this) \ + no_helpstring__, NULL, false, this) \ { } \ \ void \ @@ -276,25 +289,25 @@ struct Struct_special : public Struct_var #define DEFINE_uint(varname__, dashes__, shortname__, default_value__, \ helpstring__, helparg__) \ DEFINE_var(varname__, dashes__, shortname__, default_value__, \ - #default_value__, helpstring__, helparg__, \ + #default_value__, helpstring__, helparg__, false, \ int, int, options::parse_uint) #define DEFINE_uint64(varname__, dashes__, shortname__, default_value__, \ helpstring__, helparg__) \ DEFINE_var(varname__, dashes__, shortname__, default_value__, \ - #default_value__, helpstring__, helparg__, \ + #default_value__, helpstring__, helparg__, false, \ uint64_t, uint64_t, options::parse_uint64) #define DEFINE_double(varname__, dashes__, shortname__, default_value__, \ helpstring__, helparg__) \ DEFINE_var(varname__, dashes__, shortname__, default_value__, \ - #default_value__, helpstring__, helparg__, \ + #default_value__, helpstring__, helparg__, false, \ double, double, options::parse_double) #define DEFINE_string(varname__, dashes__, shortname__, default_value__, \ helpstring__, helparg__) \ DEFINE_var(varname__, dashes__, shortname__, default_value__, \ - default_value__, helpstring__, helparg__, \ + default_value__, helpstring__, helparg__, false, \ const char*, const char*, options::parse_string) // This is like DEFINE_string, but we convert each occurrence to a @@ -303,7 +316,7 @@ struct Struct_special : public Struct_var #define DEFINE_dirlist(varname__, dashes__, shortname__, \ helpstring__, helparg__) \ DEFINE_var(varname__, dashes__, shortname__, , \ - "", helpstring__, helparg__, options::Dir_list, \ + "", helpstring__, helparg__, false, options::Dir_list, \ const options::Dir_list&, options::parse_dirlist) \ void \ add_to_##varname__(const char* new_value) \ @@ -318,7 +331,7 @@ struct Struct_special : public Struct_var #define DEFINE_enum(varname__, dashes__, shortname__, default_value__, \ helpstring__, helparg__, ...) \ DEFINE_var(varname__, dashes__, shortname__, default_value__, \ - default_value__, helpstring__, helparg__, \ + default_value__, helpstring__, helparg__, false, \ const char*, const char*, parse_choices_##varname__) \ private: \ static void parse_choices_##varname__(const char* option_name, \ @@ -349,6 +362,15 @@ struct Struct_special : public Struct_var }; \ Struct_##varname__ varname__##_initializer_ +// An option that takes an optional string argument. If the option is +// used with no argument, the value will be the default, and +// user_set_via_option will be true. +#define DEFINE_optional_string(varname__, dashes__, shortname__, \ + default_value__, \ + helpstring__, helparg__) \ + DEFINE_var(varname__, dashes__, shortname__, default_value__, \ + default_value__, helpstring__, helparg__, true, \ + const char*, const char*, options::parse_optional_string) // A directory to search. For each directory we record whether it is // in the sysroot. We need to know this so that, if a linker script @@ -465,10 +487,13 @@ class General_options DEFINE_special(defsym, options::TWO_DASHES, '\0', N_("Define a symbol"), N_("SYMBOL=EXPRESSION")); - DEFINE_bool(demangle, options::TWO_DASHES, '\0', - getenv("COLLECT_NO_DEMANGLE") == NULL, - N_("Demangle C++ symbols in log messages"), - N_("Do not demangle C++ symbols in log messages")); + DEFINE_optional_string(demangle, options::TWO_DASHES, '\0', NULL, + N_("Demangle C++ symbols in log messages"), + N_("[=STYLE]")); + + DEFINE_bool(no_demangle, options::TWO_DASHES, '\0', false, + N_("Do not demangle C++ symbols in log messages"), + NULL); DEFINE_bool(detect_odr_violations, options::TWO_DASHES, '\0', false, N_("Try to detect violations of the One Definition Rule"), @@ -666,6 +691,13 @@ class General_options is_stack_executable() const { return this->execstack_status_ == EXECSTACK_YES; } + // The --demangle option takes an optional string, and there is also + // a --no-demangle option. This is the best way to decide whether + // to demangle or not. + bool + do_demangle() const + { return this->do_demangle_; } + private: // Don't copy this structure. General_options(const General_options&); @@ -682,12 +714,14 @@ class General_options EXECSTACK_NO }; - Execstack execstack_status_; void set_execstack_status(Execstack value) - { execstack_status_ = value; } + { this->execstack_status_ = value; } + + void + set_do_demangle(bool value) + { this->do_demangle_ = value; } - bool static_; void set_static(bool value) { static_ = value; } @@ -700,6 +734,13 @@ class General_options // Apply any sysroot to the directory lists. void add_sysroot(); + + // Whether to mark the stack as executable. + Execstack execstack_status_; + // Whether to do a static link. + bool static_; + // Whether to do demangling. + bool do_demangle_; }; // The position-dependent options. We use this to store the state of diff --git a/gold/symtab.cc b/gold/symtab.cc index b32dcb474f6..eef3a4b67dc 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -79,7 +79,7 @@ Symbol::init_fields(const char* name, const char* version, static std::string demangle(const char* name) { - if (!parameters->options().demangle()) + if (!parameters->options().do_demangle()) return name; // cplus_demangle allocates memory for the result it returns, -- 2.30.2