r305020 - [ASTMatchers] Add support for boolean literals
Peter Wu via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 8 15:00:39 PDT 2017
Author: lekensteyn
Date: Thu Jun 8 17:00:38 2017
New Revision: 305020
URL: http://llvm.org/viewvc/llvm-project?rev=305020&view=rev
Log:
[ASTMatchers] Add support for boolean literals
Summary:
Recognize boolean literals for future extensions ("equals(true)").
Note that a specific VariantValue constructor is added to resolve
ambiguity (like "Value = 5") between unsigned and bool.
Reviewed By: aaron.ballman
Differential Revision: https://reviews.llvm.org/D33093
Modified:
cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h
cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h
cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h
cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp
cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp
cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp
cfe/trunk/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
Modified: cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h?rev=305020&r1=305019&r2=305020&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/Dynamic/Parser.h Thu Jun 8 17:00:38 2017
@@ -19,8 +19,9 @@
/// \code
/// Grammar for the expressions supported:
/// <Expression> := <Literal> | <NamedValue> | <MatcherExpression>
-/// <Literal> := <StringLiteral> | <Unsigned>
+/// <Literal> := <StringLiteral> | <Boolean> | <Unsigned>
/// <StringLiteral> := "quoted string"
+/// <Boolean> := true | false
/// <Unsigned> := [0-9]+
/// <NamedValue> := <Identifier>
/// <MatcherExpression> := <Identifier>(<ArgumentList>) |
Modified: cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h?rev=305020&r1=305019&r2=305020&view=diff
==============================================================================
--- cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h (original)
+++ cfe/trunk/include/clang/ASTMatchers/Dynamic/VariantValue.h Thu Jun 8 17:00:38 2017
@@ -35,6 +35,7 @@ class ArgKind {
public:
enum Kind {
AK_Matcher,
+ AK_Boolean,
AK_Unsigned,
AK_String
};
@@ -241,6 +242,7 @@ struct VariantMatcher::TypedMatcherOps f
/// copy/assignment.
///
/// Supported types:
+/// - \c bool
/// - \c unsigned
/// - \c llvm::StringRef
/// - \c VariantMatcher (\c DynTypedMatcher / \c Matcher<T>)
@@ -253,14 +255,23 @@ public:
VariantValue &operator=(const VariantValue &Other);
/// \brief Specific constructors for each supported type.
+ VariantValue(bool Boolean);
VariantValue(unsigned Unsigned);
VariantValue(StringRef String);
VariantValue(const VariantMatcher &Matchers);
+ /// \brief Constructs an \c unsigned value (disambiguation from bool).
+ VariantValue(int Signed) : VariantValue(static_cast<unsigned>(Signed)) {}
+
/// \brief Returns true iff this is not an empty value.
explicit operator bool() const { return hasValue(); }
bool hasValue() const { return Type != VT_Nothing; }
+ /// \brief Boolean value functions.
+ bool isBoolean() const;
+ bool getBoolean() const;
+ void setBoolean(bool Boolean);
+
/// \brief Unsigned value functions.
bool isUnsigned() const;
unsigned getUnsigned() const;
@@ -303,6 +314,7 @@ private:
/// \brief All supported value types.
enum ValueType {
VT_Nothing,
+ VT_Boolean,
VT_Unsigned,
VT_String,
VT_Matcher
@@ -311,6 +323,7 @@ private:
/// \brief All supported value types.
union AllValues {
unsigned Unsigned;
+ bool Boolean;
std::string *String;
VariantMatcher *Matcher;
};
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h?rev=305020&r1=305019&r2=305020&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h Thu Jun 8 17:00:38 2017
@@ -65,6 +65,16 @@ template <class T> struct ArgTypeTraits<
}
};
+template <> struct ArgTypeTraits<bool> {
+ static bool is(const VariantValue &Value) { return Value.isBoolean(); }
+ static bool get(const VariantValue &Value) {
+ return Value.getBoolean();
+ }
+ static ArgKind getKind() {
+ return ArgKind(ArgKind::AK_Boolean);
+ }
+};
+
template <> struct ArgTypeTraits<unsigned> {
static bool is(const VariantValue &Value) { return Value.isUnsigned(); }
static unsigned get(const VariantValue &Value) {
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp?rev=305020&r1=305019&r2=305020&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/Parser.cpp Thu Jun 8 17:00:38 2017
@@ -153,8 +153,16 @@ private:
break;
++TokenLength;
}
- Result.Kind = TokenInfo::TK_Ident;
- Result.Text = Code.substr(0, TokenLength);
+ if (TokenLength == 4 && Code.startswith("true")) {
+ Result.Kind = TokenInfo::TK_Literal;
+ Result.Value = true;
+ } else if (TokenLength == 5 && Code.startswith("false")) {
+ Result.Kind = TokenInfo::TK_Literal;
+ Result.Value = false;
+ } else {
+ Result.Kind = TokenInfo::TK_Ident;
+ Result.Text = Code.substr(0, TokenLength);
+ }
Code = Code.drop_front(TokenLength);
} else {
Result.Kind = TokenInfo::TK_InvalidChar;
Modified: cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp?rev=305020&r1=305019&r2=305020&view=diff
==============================================================================
--- cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp (original)
+++ cfe/trunk/lib/ASTMatchers/Dynamic/VariantValue.cpp Thu Jun 8 17:00:38 2017
@@ -24,6 +24,8 @@ std::string ArgKind::asString() const {
switch (getArgKind()) {
case AK_Matcher:
return (Twine("Matcher<") + MatcherKind.asStringRef() + ">").str();
+ case AK_Boolean:
+ return "boolean";
case AK_Unsigned:
return "unsigned";
case AK_String:
@@ -247,6 +249,10 @@ VariantValue::VariantValue(const Variant
*this = Other;
}
+VariantValue::VariantValue(bool Boolean) : Type(VT_Nothing) {
+ setBoolean(Boolean);
+}
+
VariantValue::VariantValue(unsigned Unsigned) : Type(VT_Nothing) {
setUnsigned(Unsigned);
}
@@ -265,6 +271,9 @@ VariantValue &VariantValue::operator=(co
if (this == &Other) return *this;
reset();
switch (Other.Type) {
+ case VT_Boolean:
+ setBoolean(Other.getBoolean());
+ break;
case VT_Unsigned:
setUnsigned(Other.getUnsigned());
break;
@@ -290,6 +299,7 @@ void VariantValue::reset() {
delete Value.Matcher;
break;
// Cases that do nothing.
+ case VT_Boolean:
case VT_Unsigned:
case VT_Nothing:
break;
@@ -297,6 +307,21 @@ void VariantValue::reset() {
Type = VT_Nothing;
}
+bool VariantValue::isBoolean() const {
+ return Type == VT_Boolean;
+}
+
+bool VariantValue::getBoolean() const {
+ assert(isBoolean());
+ return Value.Boolean;
+}
+
+void VariantValue::setBoolean(bool NewValue) {
+ reset();
+ Type = VT_Boolean;
+ Value.Boolean = NewValue;
+}
+
bool VariantValue::isUnsigned() const {
return Type == VT_Unsigned;
}
@@ -344,6 +369,12 @@ void VariantValue::setMatcher(const Vari
bool VariantValue::isConvertibleTo(ArgKind Kind, unsigned *Specificity) const {
switch (Kind.getArgKind()) {
+ case ArgKind::AK_Boolean:
+ if (!isBoolean())
+ return false;
+ *Specificity = 1;
+ return true;
+
case ArgKind::AK_Unsigned:
if (!isUnsigned())
return false;
@@ -383,6 +414,7 @@ std::string VariantValue::getTypeAsStrin
switch (Type) {
case VT_String: return "String";
case VT_Matcher: return getMatcher().getTypeAsString();
+ case VT_Boolean: return "Boolean";
case VT_Unsigned: return "Unsigned";
case VT_Nothing: return "Nothing";
}
Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp?rev=305020&r1=305019&r2=305020&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/ParserTest.cpp Thu Jun 8 17:00:38 2017
@@ -75,6 +75,15 @@ public:
ExpectedMatchersTy ExpectedMatchers;
};
+TEST(ParserTest, ParseBoolean) {
+ MockSema Sema;
+ Sema.parse("true");
+ Sema.parse("false");
+ EXPECT_EQ(2U, Sema.Values.size());
+ EXPECT_EQ(true, Sema.Values[0].getBoolean());
+ EXPECT_EQ(false, Sema.Values[1].getBoolean());
+}
+
TEST(ParserTest, ParseUnsigned) {
MockSema Sema;
Sema.parse("0");
Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp?rev=305020&r1=305019&r2=305020&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp Thu Jun 8 17:00:38 2017
@@ -75,12 +75,14 @@ TEST(VariantValueTest, Assignment) {
EXPECT_TRUE(Value.isString());
EXPECT_EQ("A", Value.getString());
EXPECT_TRUE(Value.hasValue());
+ EXPECT_FALSE(Value.isBoolean());
EXPECT_FALSE(Value.isUnsigned());
EXPECT_FALSE(Value.isMatcher());
EXPECT_EQ("String", Value.getTypeAsString());
Value = VariantMatcher::SingleMatcher(recordDecl());
EXPECT_TRUE(Value.hasValue());
+ EXPECT_FALSE(Value.isBoolean());
EXPECT_FALSE(Value.isUnsigned());
EXPECT_FALSE(Value.isString());
EXPECT_TRUE(Value.isMatcher());
@@ -88,15 +90,25 @@ TEST(VariantValueTest, Assignment) {
EXPECT_FALSE(Value.getMatcher().hasTypedMatcher<UnaryOperator>());
EXPECT_EQ("Matcher<Decl>", Value.getTypeAsString());
+ Value = true;
+ EXPECT_TRUE(Value.isBoolean());
+ EXPECT_EQ(true, Value.getBoolean());
+ EXPECT_TRUE(Value.hasValue());
+ EXPECT_FALSE(Value.isUnsigned());
+ EXPECT_FALSE(Value.isMatcher());
+ EXPECT_FALSE(Value.isString());
+
Value = 17;
EXPECT_TRUE(Value.isUnsigned());
EXPECT_EQ(17U, Value.getUnsigned());
+ EXPECT_FALSE(Value.isBoolean());
EXPECT_TRUE(Value.hasValue());
EXPECT_FALSE(Value.isMatcher());
EXPECT_FALSE(Value.isString());
Value = VariantValue();
EXPECT_FALSE(Value.hasValue());
+ EXPECT_FALSE(Value.isBoolean());
EXPECT_FALSE(Value.isUnsigned());
EXPECT_FALSE(Value.isString());
EXPECT_FALSE(Value.isMatcher());
More information about the cfe-commits
mailing list