diff --git a/docs/CommandLine.html b/docs/CommandLine.html
index 97df9f787cd..013ff27d192 100644
--- a/docs/CommandLine.html
+++ b/docs/CommandLine.html
@@ -1447,6 +1447,16 @@ unrecognized option strings to it as values instead of signaling an
error. As with cl::CommaSeparated, this modifier
only makes sense with a cl::list option.
+
The cl::AllowInverse
+modifier can be used on options that have the form -fopt to
+automatically create a corresponding
+-fno-opt option. The f can be any single
+character, and the opt can be any one or more characters.
+The value of the created option is the logical complement of the value
+that would have been used if the base form of the option was used.
+This modifier only makes sense with an option that uses
+a bool parser.
+
@@ -1745,7 +1755,11 @@ for any data type.
The parser<bool> specialization
is used to convert boolean strings to a boolean value. Currently accepted
strings are "true", "TRUE", "True", "1",
-"false", "FALSE", "False", and "0".
+"false", "FALSE", "False", and "0". The
+cl::AllowInverse modifier can be used on an option of the form
+-fopt that uses the parser<bool> specialization
+to create a corresponding option with the form -fno-opt. See
+cl::AllowInverse for details.
The parser<boolOrDefault>
specialization is used for cases where the value is boolean,
diff --git a/include/llvm/Support/CommandLine.h b/include/llvm/Support/CommandLine.h
index 9b218dab031..def5ce75014 100644
--- a/include/llvm/Support/CommandLine.h
+++ b/include/llvm/Support/CommandLine.h
@@ -126,7 +126,8 @@ enum MiscFlags { // Miscellaneous flags to adjust argument
CommaSeparated = 0x200, // Should this cl::list split between commas?
PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args?
Sink = 0x800, // Should this cl::list eat all unknown options?
- MiscMask = 0xE00 // Union of the above flags.
+ AllowInverse = 0x1000, // Can this option take a -Xno- form?
+ MiscMask = 0x1E00 // Union of the above flags.
};
@@ -302,12 +303,6 @@ struct LocationClass {
template
LocationClass location(Ty &L) { return LocationClass(L); }
-// opposite_of - Allow the user to specify which other option this
-// option is the opposite of.
-//
-template
-LocationClass opposite_of(Ty &O) { return location(O.getValue()); }
-
//===----------------------------------------------------------------------===//
// Enum valued command line option
@@ -542,10 +537,33 @@ struct basic_parser : public basic_parser_impl {
//
template<>
class parser : public basic_parser {
+ bool IsInvertable; // Should we synthezise a -xno- style option?
+ const char *ArgStr;
public:
+ void getExtraOptionNames(std::vector &OptionNames) {
+ if (IsInvertable) {
+ char *s = new char [strlen(ArgStr) + 3 + 1];
+ s[0] = ArgStr[0];
+ s[1] = 'n';
+ s[2] = 'o';
+ s[3] = '-';
+ strcpy(&s[4], ArgStr+1);
+ OptionNames.push_back(s);
+ }
+ }
+
// parse - Return true on error.
bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val);
+ template
+ void initialize(Opt &O) {
+ if (O.getMiscFlags() & llvm::cl::AllowInverse)
+ IsInvertable = true;
+ else
+ IsInvertable = false;
+ ArgStr = O.ArgStr;
+ }
+
enum ValueExpected getValueExpectedFlagDefault() const {
return ValueOptional;
}
@@ -582,30 +600,6 @@ public:
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser);
-//--------------------------------------------------
-// parser
-class boolInverse { };
-template<>
-class parser : public basic_parser {
-public:
- typedef bool parser_data_type;
- // parse - Return true on error.
- bool parse(Option &O, const char *ArgName, const std::string &Arg,
- bool &Val);
-
- enum ValueExpected getValueExpectedFlagDefault() const {
- return ValueOptional;
- }
-
- // getValueName - Do not print = at all.
- virtual const char *getValueName() const { return 0; }
-
- // An out-of-line virtual method to provide a 'home' for this class.
- virtual void anchor();
-};
-
-EXTERN_TEMPLATE_INSTANTIATION(class basic_parser);
-
//--------------------------------------------------
// parser
//
@@ -947,9 +941,6 @@ EXTERN_TEMPLATE_INSTANTIATION(class opt);
EXTERN_TEMPLATE_INSTANTIATION(class opt);
EXTERN_TEMPLATE_INSTANTIATION(class opt);
-class boolInverse;
-typedef opt > inverse_opt;
-
//===----------------------------------------------------------------------===//
// list_storage class
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index e06f324c871..2c56e0ffb87 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -40,7 +40,6 @@ using namespace cl;
//
TEMPLATE_INSTANTIATION(class basic_parser);
TEMPLATE_INSTANTIATION(class basic_parser);
-TEMPLATE_INSTANTIATION(class basic_parser);
TEMPLATE_INSTANTIATION(class basic_parser);
TEMPLATE_INSTANTIATION(class basic_parser);
TEMPLATE_INSTANTIATION(class basic_parser);
@@ -56,7 +55,6 @@ void Option::anchor() {}
void basic_parser_impl::anchor() {}
void parser::anchor() {}
void parser::anchor() {}
-void parser::anchor() {}
void parser::anchor() {}
void parser::anchor() {}
void parser::anchor() {}
@@ -874,6 +872,8 @@ bool parser::parse(Option &O, const char *ArgName,
return O.error(": '" + Arg +
"' is invalid value for boolean argument! Try 0 or 1");
}
+ if (IsInvertable && strncmp(ArgName+1, "no-", 3) == 0)
+ Value = !Value;
return false;
}
@@ -894,23 +894,6 @@ bool parser::parse(Option &O, const char *ArgName,
return false;
}
-// parser implementation
-//
-bool parser::parse(Option &O, const char *ArgName,
- const std::string &Arg, bool &Value) {
- if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
- Arg == "1") {
- Value = false;
- } else if (Arg == "false" || Arg == "FALSE"
- || Arg == "False" || Arg == "0") {
- Value = true;
- } else {
- return O.error(": '" + Arg +
- "' is invalid value for boolean argument! Try 0 or 1");
- }
- return false;
-}
-
// parser implementation
//
bool parser::parse(Option &O, const char *ArgName,