summaryrefslogtreecommitdiffstats
path: root/lib/ASTMatchers
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2017-06-08 22:00:38 +0000
committerPeter Wu <peter@lekensteyn.nl>2017-06-08 22:00:38 +0000
commit1fc30fcae813617a5beb272c5abedc11fcce2e31 (patch)
tree1c7857a6bdfde2791135df7622ce55af6a28e40c /lib/ASTMatchers
parent97a93ed9081459ae5590fc787e4163ae435a5028 (diff)
[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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@305020 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ASTMatchers')
-rw-r--r--lib/ASTMatchers/Dynamic/Marshallers.h10
-rw-r--r--lib/ASTMatchers/Dynamic/Parser.cpp12
-rw-r--r--lib/ASTMatchers/Dynamic/VariantValue.cpp32
3 files changed, 52 insertions, 2 deletions
diff --git a/lib/ASTMatchers/Dynamic/Marshallers.h b/lib/ASTMatchers/Dynamic/Marshallers.h
index fb6b349a81..1d4ba037fd 100644
--- a/lib/ASTMatchers/Dynamic/Marshallers.h
+++ b/lib/ASTMatchers/Dynamic/Marshallers.h
@@ -65,6 +65,16 @@ template <class T> struct ArgTypeTraits<ast_matchers::internal::Matcher<T> > {
}
};
+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) {
diff --git a/lib/ASTMatchers/Dynamic/Parser.cpp b/lib/ASTMatchers/Dynamic/Parser.cpp
index ce8d0a9a02..967da8ac32 100644
--- a/lib/ASTMatchers/Dynamic/Parser.cpp
+++ b/lib/ASTMatchers/Dynamic/Parser.cpp
@@ -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;
diff --git a/lib/ASTMatchers/Dynamic/VariantValue.cpp b/lib/ASTMatchers/Dynamic/VariantValue.cpp
index f0339ed479..a889e46fd6 100644
--- a/lib/ASTMatchers/Dynamic/VariantValue.cpp
+++ b/lib/ASTMatchers/Dynamic/VariantValue.cpp
@@ -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 VariantValue &Other) : Type(VT_Nothing) {
*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=(const VariantValue &Other) {
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 VariantMatcher &NewValue) {
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::getTypeAsString() const {
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";
}