diff --git a/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h b/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h --- a/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h +++ b/clang/include/clang/ASTMatchers/Dynamic/VariantValue.h @@ -251,6 +251,7 @@ VariantValue(double Double); VariantValue(unsigned Unsigned); VariantValue(StringRef String); + VariantValue(ASTNodeKind NodeKind); VariantValue(const VariantMatcher &Matchers); /// Constructs an \c unsigned value (disambiguation from bool). @@ -280,6 +281,10 @@ const std::string &getString() const; void setString(StringRef String); + bool isNodeKind() const; + const ASTNodeKind &getNodeKind() const; + void setNodeKind(ASTNodeKind NodeKind); + /// Matcher value functions. bool isMatcher() const; const VariantMatcher &getMatcher() const; @@ -316,7 +321,8 @@ VT_Double, VT_Unsigned, VT_String, - VT_Matcher + VT_Matcher, + VT_NodeKind }; /// All supported value types. @@ -326,6 +332,7 @@ bool Boolean; std::string *String; VariantMatcher *Matcher; + ASTNodeKind *NodeKind; }; ValueType Type; diff --git a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp --- a/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp +++ b/clang/lib/ASTMatchers/Dynamic/VariantValue.cpp @@ -268,6 +268,10 @@ setString(String); } +VariantValue::VariantValue(ASTNodeKind NodeKind) : Type(VT_Nothing) { + setNodeKind(NodeKind); +} + VariantValue::VariantValue(const VariantMatcher &Matcher) : Type(VT_Nothing) { setMatcher(Matcher); } @@ -290,6 +294,9 @@ case VT_String: setString(Other.getString()); break; + case VT_NodeKind: + setNodeKind(Other.getNodeKind()); + break; case VT_Matcher: setMatcher(Other.getMatcher()); break; @@ -308,6 +315,9 @@ case VT_Matcher: delete Value.Matcher; break; + case VT_NodeKind: + delete Value.NodeKind; + break; // Cases that do nothing. case VT_Boolean: case VT_Double: @@ -378,6 +388,19 @@ Value.String = new std::string(NewValue); } +bool VariantValue::isNodeKind() const { return Type == VT_NodeKind; } + +const ASTNodeKind &VariantValue::getNodeKind() const { + assert(isNodeKind()); + return *Value.NodeKind; +} + +void VariantValue::setNodeKind(ASTNodeKind NewValue) { + reset(); + Type = VT_NodeKind; + Value.NodeKind = new ASTNodeKind(NewValue); +} + bool VariantValue::isMatcher() const { return Type == VT_Matcher; } @@ -449,6 +472,8 @@ case VT_Boolean: return "Boolean"; case VT_Double: return "Double"; case VT_Unsigned: return "Unsigned"; + case VT_NodeKind: + return getNodeKind().asStringRef().str(); case VT_Nothing: return "Nothing"; } llvm_unreachable("Invalid Type"); diff --git a/clang/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp b/clang/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp --- a/clang/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp +++ b/clang/unittests/ASTMatchers/Dynamic/VariantValueTest.cpp @@ -184,6 +184,25 @@ .getTypedMatcher())); } +TEST(VariantValueTest, NodeKind) { + VariantValue Value = ASTNodeKind::getFromNodeKind(); + EXPECT_TRUE(Value.isNodeKind()); + EXPECT_TRUE(Value.getNodeKind().isSame(ASTNodeKind::getFromNodeKind())); + + Value = ASTNodeKind::getFromNodeKind(); + EXPECT_TRUE(Value.isNodeKind()); + EXPECT_TRUE(Value.getNodeKind().isSame( + ASTNodeKind::getFromNodeKind())); + + Value.setNodeKind(ASTNodeKind::getFromNodeKind()); + EXPECT_TRUE(Value.isNodeKind()); + EXPECT_TRUE( + Value.getNodeKind().isSame(ASTNodeKind::getFromNodeKind())); + + Value = 42; + EXPECT_TRUE(!Value.isNodeKind()); +} + } // end anonymous namespace } // end namespace dynamic } // end namespace ast_matchers