Skip to content

Commit b92f839

Browse files
author
Mike Stump
committed
Improve -fno-opt style option processing to not require an extra
option to make the -fno- form on the option. We also document the new form in the CommandLine documentation. llvm-svn: 63559
1 parent 4eda2cb commit b92f839

File tree

3 files changed

+42
-54
lines changed

3 files changed

+42
-54
lines changed

llvm/docs/CommandLine.html

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1447,6 +1447,16 @@
14471447
error. As with <b><tt>cl::CommaSeparated</tt></b></a>, this modifier
14481448
only makes sense with a <a href="#cl::list">cl::list</a> option.</li>
14491449

1450+
<li><a name="cl::AllowInverse">The <b><tt>cl::AllowInverse</tt></b></a>
1451+
modifier can be used on options that have the form <tt>-fopt</tt> to
1452+
automatically create a corresponding
1453+
<tt>-fno-opt</tt> option. The <tt>f</tt> can be any single
1454+
character, and the <tt>opt</tt> can be any one or more characters.
1455+
The value of the created option is the logical complement of the value
1456+
that would have been used if the base form of the option was used.
1457+
This modifier only makes sense with an option that uses
1458+
a <a href="#boolparser">bool parser</a>.</li>
1459+
14501460

14511461
</ul>
14521462

@@ -1745,7 +1755,11 @@
17451755
<li><a name="boolparser">The <b><tt>parser&lt;bool&gt;</tt> specialization</b></a>
17461756
is used to convert boolean strings to a boolean value. Currently accepted
17471757
strings are "<tt>true</tt>", "<tt>TRUE</tt>", "<tt>True</tt>", "<tt>1</tt>",
1748-
"<tt>false</tt>", "<tt>FALSE</tt>", "<tt>False</tt>", and "<tt>0</tt>".</li>
1758+
"<tt>false</tt>", "<tt>FALSE</tt>", "<tt>False</tt>", and "<tt>0</tt>". The
1759+
<b><tt>cl::AllowInverse</tt></b> modifier can be used on an option of the form
1760+
<tt>-fopt</tt> that uses the <tt>parser&lt;bool&gt;</tt> specialization
1761+
to create a corresponding option with the form <tt>-fno-opt</tt>. See
1762+
<a href="#cl::AllowInverse"><tt>cl::AllowInverse</tt></a> for details.</li>
17491763

17501764
<li><a name="boolOrDefaultparser">The <b><tt>parser&lt;boolOrDefault&gt;</tt>
17511765
specialization</b></a> is used for cases where the value is boolean,

llvm/include/llvm/Support/CommandLine.h

Lines changed: 25 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ enum MiscFlags { // Miscellaneous flags to adjust argument
126126
CommaSeparated = 0x200, // Should this cl::list split between commas?
127127
PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args?
128128
Sink = 0x800, // Should this cl::list eat all unknown options?
129-
MiscMask = 0xE00 // Union of the above flags.
129+
AllowInverse = 0x1000, // Can this option take a -Xno- form?
130+
MiscMask = 0x1E00 // Union of the above flags.
130131
};
131132

132133

@@ -302,12 +303,6 @@ struct LocationClass {
302303
template<class Ty>
303304
LocationClass<Ty> location(Ty &L) { return LocationClass<Ty>(L); }
304305

305-
// opposite_of - Allow the user to specify which other option this
306-
// option is the opposite of.
307-
//
308-
template<class Ty>
309-
LocationClass<bool> opposite_of(Ty &O) { return location(O.getValue()); }
310-
311306

312307
//===----------------------------------------------------------------------===//
313308
// Enum valued command line option
@@ -542,10 +537,33 @@ struct basic_parser : public basic_parser_impl {
542537
//
543538
template<>
544539
class parser<bool> : public basic_parser<bool> {
540+
bool IsInvertable; // Should we synthezise a -xno- style option?
541+
const char *ArgStr;
545542
public:
543+
void getExtraOptionNames(std::vector<const char*> &OptionNames) {
544+
if (IsInvertable) {
545+
char *s = new char [strlen(ArgStr) + 3 + 1];
546+
s[0] = ArgStr[0];
547+
s[1] = 'n';
548+
s[2] = 'o';
549+
s[3] = '-';
550+
strcpy(&s[4], ArgStr+1);
551+
OptionNames.push_back(s);
552+
}
553+
}
554+
546555
// parse - Return true on error.
547556
bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val);
548557

558+
template <class Opt>
559+
void initialize(Opt &O) {
560+
if (O.getMiscFlags() & llvm::cl::AllowInverse)
561+
IsInvertable = true;
562+
else
563+
IsInvertable = false;
564+
ArgStr = O.ArgStr;
565+
}
566+
549567
enum ValueExpected getValueExpectedFlagDefault() const {
550568
return ValueOptional;
551569
}
@@ -582,30 +600,6 @@ class parser<boolOrDefault> : public basic_parser<boolOrDefault> {
582600

583601
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
584602

585-
//--------------------------------------------------
586-
// parser<boolInverse>
587-
class boolInverse { };
588-
template<>
589-
class parser<boolInverse> : public basic_parser<bool> {
590-
public:
591-
typedef bool parser_data_type;
592-
// parse - Return true on error.
593-
bool parse(Option &O, const char *ArgName, const std::string &Arg,
594-
bool &Val);
595-
596-
enum ValueExpected getValueExpectedFlagDefault() const {
597-
return ValueOptional;
598-
}
599-
600-
// getValueName - Do not print =<value> at all.
601-
virtual const char *getValueName() const { return 0; }
602-
603-
// An out-of-line virtual method to provide a 'home' for this class.
604-
virtual void anchor();
605-
};
606-
607-
EXTERN_TEMPLATE_INSTANTIATION(class basic_parser<bool>);
608-
609603
//--------------------------------------------------
610604
// parser<int>
611605
//
@@ -947,9 +941,6 @@ EXTERN_TEMPLATE_INSTANTIATION(class opt<int>);
947941
EXTERN_TEMPLATE_INSTANTIATION(class opt<std::string>);
948942
EXTERN_TEMPLATE_INSTANTIATION(class opt<bool>);
949943

950-
class boolInverse;
951-
typedef opt<bool, true, parser<boolInverse> > inverse_opt;
952-
953944
//===----------------------------------------------------------------------===//
954945
// list_storage class
955946

llvm/lib/Support/CommandLine.cpp

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ using namespace cl;
4040
//
4141
TEMPLATE_INSTANTIATION(class basic_parser<bool>);
4242
TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
43-
TEMPLATE_INSTANTIATION(class basic_parser<boolInverse>);
4443
TEMPLATE_INSTANTIATION(class basic_parser<int>);
4544
TEMPLATE_INSTANTIATION(class basic_parser<unsigned>);
4645
TEMPLATE_INSTANTIATION(class basic_parser<double>);
@@ -56,7 +55,6 @@ void Option::anchor() {}
5655
void basic_parser_impl::anchor() {}
5756
void parser<bool>::anchor() {}
5857
void parser<boolOrDefault>::anchor() {}
59-
void parser<boolInverse>::anchor() {}
6058
void parser<int>::anchor() {}
6159
void parser<unsigned>::anchor() {}
6260
void parser<double>::anchor() {}
@@ -874,6 +872,8 @@ bool parser<bool>::parse(Option &O, const char *ArgName,
874872
return O.error(": '" + Arg +
875873
"' is invalid value for boolean argument! Try 0 or 1");
876874
}
875+
if (IsInvertable && strncmp(ArgName+1, "no-", 3) == 0)
876+
Value = !Value;
877877
return false;
878878
}
879879

@@ -894,23 +894,6 @@ bool parser<boolOrDefault>::parse(Option &O, const char *ArgName,
894894
return false;
895895
}
896896

897-
// parser<boolInverse> implementation
898-
//
899-
bool parser<boolInverse>::parse(Option &O, const char *ArgName,
900-
const std::string &Arg, bool &Value) {
901-
if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
902-
Arg == "1") {
903-
Value = false;
904-
} else if (Arg == "false" || Arg == "FALSE"
905-
|| Arg == "False" || Arg == "0") {
906-
Value = true;
907-
} else {
908-
return O.error(": '" + Arg +
909-
"' is invalid value for boolean argument! Try 0 or 1");
910-
}
911-
return false;
912-
}
913-
914897
// parser<int> implementation
915898
//
916899
bool parser<int>::parse(Option &O, const char *ArgName,

0 commit comments

Comments
 (0)