diff options
-rw-r--r-- | clang/include/clang/AST/ASTTypeTraits.h | 4 | ||||
-rw-r--r-- | clang/unittests/ASTMatchers/ASTMatchersTest.cpp | 33 |
2 files changed, 34 insertions, 3 deletions
diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h index b920767a10a..abc88571eb6 100644 --- a/clang/include/clang/AST/ASTTypeTraits.h +++ b/clang/include/clang/AST/ASTTypeTraits.h @@ -212,8 +212,8 @@ public: return getMemoizationData() < Other.getMemoizationData(); } bool operator==(const DynTypedNode &Other) const { - // Nodes with different types cannot be equal. - if (!NodeKind.isSame(Other.NodeKind)) + if (!NodeKind.isBaseOf(Other.NodeKind) && + !Other.NodeKind.isBaseOf(NodeKind)) return false; // FIXME: Implement for other types. diff --git a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp index f1b792139d9..787f81992d9 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTest.cpp @@ -4260,7 +4260,6 @@ TEST(EqualsBoundNodeMatcher, Type) { } TEST(EqualsBoundNodeMatcher, UsingForEachDescendant) { - EXPECT_TRUE(matchAndVerifyResultTrue( "int f() {" " if (1) {" @@ -4294,5 +4293,37 @@ TEST(EqualsBoundNodeMatcher, FiltersMatchedCombinations) { new VerifyIdIsBoundTo<VarDecl>("d", 5))); } +TEST(EqualsBoundNodeMatcher, UnlessDescendantsOfAncestorsMatch) { + EXPECT_TRUE(matchAndVerifyResultTrue( + "struct StringRef { int size() const; const char* data() const; };" + "void f(StringRef v) {" + " v.data();" + "}", + memberCallExpr( + callee(methodDecl(hasName("data"))), + on(declRefExpr(to(varDecl(hasType(recordDecl(hasName("StringRef")))) + .bind("var")))), + unless(hasAncestor(stmt(hasDescendant(memberCallExpr( + callee(methodDecl(anyOf(hasName("size"), hasName("length")))), + on(declRefExpr(to(varDecl(equalsBoundNode("var"))))))))))) + .bind("data"), + new VerifyIdIsBoundTo<Expr>("data", 1))); + + EXPECT_FALSE(matches( + "struct StringRef { int size() const; const char* data() const; };" + "void f(StringRef v) {" + " v.data();" + " v.size();" + "}", + memberCallExpr( + callee(methodDecl(hasName("data"))), + on(declRefExpr(to(varDecl(hasType(recordDecl(hasName("StringRef")))) + .bind("var")))), + unless(hasAncestor(stmt(hasDescendant(memberCallExpr( + callee(methodDecl(anyOf(hasName("size"), hasName("length")))), + on(declRefExpr(to(varDecl(equalsBoundNode("var"))))))))))) + .bind("data"))); +} + } // end namespace ast_matchers } // end namespace clang |