mirror of
https://github.com/RPCS3/llvm.git
synced 2024-11-27 21:50:29 +00:00
* Fix assertion failure caused by command line argument getting removed after
the map was freed. * Cleanup code a bit git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3121 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
2c04779ba7
commit
e8e258b1a7
@ -29,9 +29,16 @@ using std::cerr;
|
|||||||
// Return the global command line option vector. Making it a function scoped
|
// Return the global command line option vector. Making it a function scoped
|
||||||
// static ensures that it will be initialized correctly before its first use.
|
// static ensures that it will be initialized correctly before its first use.
|
||||||
//
|
//
|
||||||
|
static map<string,Option*> *CommandLineOptions = 0;
|
||||||
static map<string, Option*> &getOpts() {
|
static map<string, Option*> &getOpts() {
|
||||||
static map<string,Option*> CommandLineOptions;
|
if (CommandLineOptions == 0) CommandLineOptions = new map<string,Option*>();
|
||||||
return CommandLineOptions;
|
return *CommandLineOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Option *getOption(const string &Str) {
|
||||||
|
if (CommandLineOptions == 0) return 0;
|
||||||
|
map<string,Option*>::iterator I = CommandLineOptions->find(Str);
|
||||||
|
return I != CommandLineOptions->end() ? I->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static vector<Option*> &getPositionalOpts() {
|
static vector<Option*> &getPositionalOpts() {
|
||||||
@ -39,13 +46,26 @@ static vector<Option*> &getPositionalOpts() {
|
|||||||
return Positional;
|
return Positional;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddArgument(const string &ArgName, Option *Opt) {
|
static void AddArgument(const char *ArgName, Option *Opt) {
|
||||||
if (getOpts().find(ArgName) != getOpts().end()) {
|
if (getOption(ArgName)) {
|
||||||
cerr << "CommandLine Error: Argument '" << ArgName
|
cerr << "CommandLine Error: Argument '" << ArgName
|
||||||
<< "' defined more than once!\n";
|
<< "' defined more than once!\n";
|
||||||
} else {
|
} else {
|
||||||
// Add argument to the argument map!
|
// Add argument to the argument map!
|
||||||
getOpts().insert(std::make_pair(ArgName, Opt));
|
getOpts()[ArgName] = Opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveArgument - It's possible that the argument is no longer in the map if
|
||||||
|
// options have already been processed and the map has been deleted!
|
||||||
|
//
|
||||||
|
static void RemoveArgument(const char *ArgName, Option *Opt) {
|
||||||
|
if (CommandLineOptions == 0) return;
|
||||||
|
assert(getOption(ArgName) == Opt && "Arg not in map!");
|
||||||
|
CommandLineOptions->erase(ArgName);
|
||||||
|
if (CommandLineOptions->empty()) {
|
||||||
|
delete CommandLineOptions;
|
||||||
|
CommandLineOptions = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,25 +123,25 @@ static inline bool isPrefixedOrGrouping(const Option *O) {
|
|||||||
static Option *getOptionPred(std::string Name, unsigned &Length,
|
static Option *getOptionPred(std::string Name, unsigned &Length,
|
||||||
bool (*Pred)(const Option*)) {
|
bool (*Pred)(const Option*)) {
|
||||||
|
|
||||||
map<string, Option*>::iterator I = getOpts().find(Name);
|
Option *Op = getOption(Name);
|
||||||
if (I != getOpts().end() && Pred(I->second)) {
|
if (Op && Pred(Op)) {
|
||||||
Length = Name.length();
|
Length = Name.length();
|
||||||
return I->second;
|
return Op;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Name.size() == 1) return 0;
|
if (Name.size() == 1) return 0;
|
||||||
do {
|
do {
|
||||||
Name.erase(Name.end()-1, Name.end()); // Chop off the last character...
|
Name.erase(Name.end()-1, Name.end()); // Chop off the last character...
|
||||||
I = getOpts().find(Name);
|
Op = getOption(Name);
|
||||||
|
|
||||||
// Loop while we haven't found an option and Name still has at least two
|
// Loop while we haven't found an option and Name still has at least two
|
||||||
// characters in it (so that the next iteration will not be the empty
|
// characters in it (so that the next iteration will not be the empty
|
||||||
// string...
|
// string...
|
||||||
} while ((I == getOpts().end() || !Pred(I->second)) && Name.size() > 1);
|
} while ((Op == 0 || !Pred(Op)) && Name.size() > 1);
|
||||||
|
|
||||||
if (I != getOpts().end() && Pred(I->second)) {
|
if (Op && Pred(Op)) {
|
||||||
Length = Name.length();
|
Length = Name.length();
|
||||||
return I->second; // Found one!
|
return Op; // Found one!
|
||||||
}
|
}
|
||||||
return 0; // No option found!
|
return 0; // No option found!
|
||||||
}
|
}
|
||||||
@ -384,7 +404,8 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
|
|||||||
|
|
||||||
// Free all of the memory allocated to the map. Command line options may only
|
// Free all of the memory allocated to the map. Command line options may only
|
||||||
// be processed once!
|
// be processed once!
|
||||||
Opts.clear();
|
delete CommandLineOptions;
|
||||||
|
CommandLineOptions = 0;
|
||||||
PositionalOpts.clear();
|
PositionalOpts.clear();
|
||||||
|
|
||||||
// If we had an error processing our arguments, don't let the program execute
|
// If we had an error processing our arguments, don't let the program execute
|
||||||
@ -445,8 +466,7 @@ void Option::addArgument(const char *ArgStr) {
|
|||||||
|
|
||||||
void Option::removeArgument(const char *ArgStr) {
|
void Option::removeArgument(const char *ArgStr) {
|
||||||
if (ArgStr[0]) {
|
if (ArgStr[0]) {
|
||||||
assert(getOpts()[ArgStr] == this && "Arg not in map!");
|
RemoveArgument(ArgStr, this);
|
||||||
getOpts().erase(ArgStr);
|
|
||||||
} else if (getFormattingFlag() == Positional) {
|
} else if (getFormattingFlag() == Positional) {
|
||||||
vector<Option*>::iterator I =
|
vector<Option*>::iterator I =
|
||||||
std::find(getPositionalOpts().begin(), getPositionalOpts().end(), this);
|
std::find(getPositionalOpts().begin(), getPositionalOpts().end(), this);
|
||||||
|
@ -29,9 +29,16 @@ using std::cerr;
|
|||||||
// Return the global command line option vector. Making it a function scoped
|
// Return the global command line option vector. Making it a function scoped
|
||||||
// static ensures that it will be initialized correctly before its first use.
|
// static ensures that it will be initialized correctly before its first use.
|
||||||
//
|
//
|
||||||
|
static map<string,Option*> *CommandLineOptions = 0;
|
||||||
static map<string, Option*> &getOpts() {
|
static map<string, Option*> &getOpts() {
|
||||||
static map<string,Option*> CommandLineOptions;
|
if (CommandLineOptions == 0) CommandLineOptions = new map<string,Option*>();
|
||||||
return CommandLineOptions;
|
return *CommandLineOptions;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Option *getOption(const string &Str) {
|
||||||
|
if (CommandLineOptions == 0) return 0;
|
||||||
|
map<string,Option*>::iterator I = CommandLineOptions->find(Str);
|
||||||
|
return I != CommandLineOptions->end() ? I->second : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static vector<Option*> &getPositionalOpts() {
|
static vector<Option*> &getPositionalOpts() {
|
||||||
@ -39,13 +46,26 @@ static vector<Option*> &getPositionalOpts() {
|
|||||||
return Positional;
|
return Positional;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AddArgument(const string &ArgName, Option *Opt) {
|
static void AddArgument(const char *ArgName, Option *Opt) {
|
||||||
if (getOpts().find(ArgName) != getOpts().end()) {
|
if (getOption(ArgName)) {
|
||||||
cerr << "CommandLine Error: Argument '" << ArgName
|
cerr << "CommandLine Error: Argument '" << ArgName
|
||||||
<< "' defined more than once!\n";
|
<< "' defined more than once!\n";
|
||||||
} else {
|
} else {
|
||||||
// Add argument to the argument map!
|
// Add argument to the argument map!
|
||||||
getOpts().insert(std::make_pair(ArgName, Opt));
|
getOpts()[ArgName] = Opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveArgument - It's possible that the argument is no longer in the map if
|
||||||
|
// options have already been processed and the map has been deleted!
|
||||||
|
//
|
||||||
|
static void RemoveArgument(const char *ArgName, Option *Opt) {
|
||||||
|
if (CommandLineOptions == 0) return;
|
||||||
|
assert(getOption(ArgName) == Opt && "Arg not in map!");
|
||||||
|
CommandLineOptions->erase(ArgName);
|
||||||
|
if (CommandLineOptions->empty()) {
|
||||||
|
delete CommandLineOptions;
|
||||||
|
CommandLineOptions = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,25 +123,25 @@ static inline bool isPrefixedOrGrouping(const Option *O) {
|
|||||||
static Option *getOptionPred(std::string Name, unsigned &Length,
|
static Option *getOptionPred(std::string Name, unsigned &Length,
|
||||||
bool (*Pred)(const Option*)) {
|
bool (*Pred)(const Option*)) {
|
||||||
|
|
||||||
map<string, Option*>::iterator I = getOpts().find(Name);
|
Option *Op = getOption(Name);
|
||||||
if (I != getOpts().end() && Pred(I->second)) {
|
if (Op && Pred(Op)) {
|
||||||
Length = Name.length();
|
Length = Name.length();
|
||||||
return I->second;
|
return Op;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Name.size() == 1) return 0;
|
if (Name.size() == 1) return 0;
|
||||||
do {
|
do {
|
||||||
Name.erase(Name.end()-1, Name.end()); // Chop off the last character...
|
Name.erase(Name.end()-1, Name.end()); // Chop off the last character...
|
||||||
I = getOpts().find(Name);
|
Op = getOption(Name);
|
||||||
|
|
||||||
// Loop while we haven't found an option and Name still has at least two
|
// Loop while we haven't found an option and Name still has at least two
|
||||||
// characters in it (so that the next iteration will not be the empty
|
// characters in it (so that the next iteration will not be the empty
|
||||||
// string...
|
// string...
|
||||||
} while ((I == getOpts().end() || !Pred(I->second)) && Name.size() > 1);
|
} while ((Op == 0 || !Pred(Op)) && Name.size() > 1);
|
||||||
|
|
||||||
if (I != getOpts().end() && Pred(I->second)) {
|
if (Op && Pred(Op)) {
|
||||||
Length = Name.length();
|
Length = Name.length();
|
||||||
return I->second; // Found one!
|
return Op; // Found one!
|
||||||
}
|
}
|
||||||
return 0; // No option found!
|
return 0; // No option found!
|
||||||
}
|
}
|
||||||
@ -384,7 +404,8 @@ void cl::ParseCommandLineOptions(int &argc, char **argv,
|
|||||||
|
|
||||||
// Free all of the memory allocated to the map. Command line options may only
|
// Free all of the memory allocated to the map. Command line options may only
|
||||||
// be processed once!
|
// be processed once!
|
||||||
Opts.clear();
|
delete CommandLineOptions;
|
||||||
|
CommandLineOptions = 0;
|
||||||
PositionalOpts.clear();
|
PositionalOpts.clear();
|
||||||
|
|
||||||
// If we had an error processing our arguments, don't let the program execute
|
// If we had an error processing our arguments, don't let the program execute
|
||||||
@ -445,8 +466,7 @@ void Option::addArgument(const char *ArgStr) {
|
|||||||
|
|
||||||
void Option::removeArgument(const char *ArgStr) {
|
void Option::removeArgument(const char *ArgStr) {
|
||||||
if (ArgStr[0]) {
|
if (ArgStr[0]) {
|
||||||
assert(getOpts()[ArgStr] == this && "Arg not in map!");
|
RemoveArgument(ArgStr, this);
|
||||||
getOpts().erase(ArgStr);
|
|
||||||
} else if (getFormattingFlag() == Positional) {
|
} else if (getFormattingFlag() == Positional) {
|
||||||
vector<Option*>::iterator I =
|
vector<Option*>::iterator I =
|
||||||
std::find(getPositionalOpts().begin(), getPositionalOpts().end(), this);
|
std::find(getPositionalOpts().begin(), getPositionalOpts().end(), this);
|
||||||
|
Loading…
Reference in New Issue
Block a user