diff options
author | Peter Wu <peter@lekensteyn.nl> | 2017-06-08 22:00:38 +0000 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2017-06-08 22:00:38 +0000 |
commit | 1fc30fcae813617a5beb272c5abedc11fcce2e31 (patch) | |
tree | 1c7857a6bdfde2791135df7622ce55af6a28e40c /lib/ASTMatchers | |
parent | 97a93ed9081459ae5590fc787e4163ae435a5028 (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.h | 10 | ||||
-rw-r--r-- | lib/ASTMatchers/Dynamic/Parser.cpp | 12 | ||||
-rw-r--r-- | lib/ASTMatchers/Dynamic/VariantValue.cpp | 32 |
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"; } |