aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gold/ChangeLog11
-rw-r--r--gold/options.cc22
-rw-r--r--gold/options.h10
3 files changed, 42 insertions, 1 deletions
diff --git a/gold/ChangeLog b/gold/ChangeLog
index 4e64c1b..174eef8 100644
--- a/gold/ChangeLog
+++ b/gold/ChangeLog
@@ -1,5 +1,16 @@
2009-08-24 Cary Coutant <ccoutant@google.com>
+ * options.h (Command_line::Pre_options): New class.
+ (Command_line::pre_options): New member.
+ * options.cc (gold::options::ready_to_register): New variable.
+ (One_option::register_option): Do nothing if not registering options.
+ Assert if same short option registered twice.
+ (General_options::General_options): Turn off option registration when
+ done constructing.
+ (Command_line::Pre_options::Pre_options): New constructor.
+
+2009-08-24 Cary Coutant <ccoutant@google.com>
+
* options.h (General_options::no_keep_memory): Remove incorrect
short option.
diff --git a/gold/options.cc b/gold/options.cc
index f09dccb..bf420c6 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -47,6 +47,11 @@ Position_dependent_options::default_options_;
namespace options
{
+// This flag is TRUE if we should register the command-line options as they
+// are constructed. It is set after contruction of the options within
+// class Position_dependent_options.
+static bool ready_to_register = false;
+
// This global variable is set up as General_options is constructed.
static std::vector<const One_option*> registered_options;
@@ -60,6 +65,9 @@ static One_option* short_options[128];
void
One_option::register_option()
{
+ if (!ready_to_register)
+ return;
+
registered_options.push_back(this);
// We can't make long_options a static Option_map because we can't
@@ -75,7 +83,10 @@ One_option::register_option()
const int shortname_as_int = static_cast<int>(this->shortname);
gold_assert(shortname_as_int >= 0 && shortname_as_int < 128);
if (this->shortname != '\0')
- short_options[shortname_as_int] = this;
+ {
+ gold_assert(short_options[shortname_as_int] == NULL);
+ short_options[shortname_as_int] = this;
+ }
}
void
@@ -714,6 +725,8 @@ General_options::General_options()
do_demangle_(false), plugins_(),
incremental_disposition_(INCREMENTAL_CHECK), implicit_incremental_(false)
{
+ // Turn off option registration once construction is complete.
+ gold::options::ready_to_register = false;
}
General_options::Object_format
@@ -1039,6 +1052,13 @@ Command_line::Command_line()
{
}
+// Pre_options is the hook that sets the ready_to_register flag.
+
+Command_line::Pre_options::Pre_options()
+{
+ gold::options::ready_to_register = true;
+}
+
// Process the command line options. For process_one_option, i is the
// index of argv to process next, and must be an option (that is,
// start with a dash). The return value is the index of the next
diff --git a/gold/options.h b/gold/options.h
index 359866e..3f14529 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -1479,6 +1479,16 @@ class Command_line
Command_line(const Command_line&);
Command_line& operator=(const Command_line&);
+ // This is a dummy class to provide a constructor that runs before
+ // the constructor for the General_options. The Pre_options constructor
+ // is used as a hook to set the flag enabling the options to register
+ // themselves.
+ struct Pre_options {
+ Pre_options();
+ };
+
+ // This must come before options_!
+ Pre_options pre_options_;
General_options options_;
Position_dependent_options position_options_;
Script_options script_options_;