From e0652d113ae77cb181c7164569e34af1f53612da Mon Sep 17 00:00:00 2001 From: Manuel Klimek Date: Tue, 27 May 2014 12:31:10 +0000 Subject: [PATCH] Make equalsNode work with pointers to subtypes. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209652 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LibASTMatchersReference.html | 4 ++-- include/clang/ASTMatchers/ASTMatchers.h | 8 +++---- .../clang/ASTMatchers/ASTMatchersInternal.h | 14 +++++++++++ unittests/ASTMatchers/ASTMatchersTest.cpp | 24 ++++++++++++------- 4 files changed, 36 insertions(+), 14 deletions(-) diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index 90351e0602..c308635e31 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -1601,7 +1601,7 @@ and reference to that variable declaration within a compound statement. -Matcher<Decl>equalsNodeDecl* Other +Matcher<Decl>equalsNodeDecl *Node
Matches if a node equals another node.
 
 Decl has pointer identity in the AST.
@@ -1900,7 +1900,7 @@ and reference to that variable declaration within a compound statement.
 
-Matcher<Stmt>equalsNodeStmt* Other +Matcher<Stmt>equalsNodeStmt *Node
Matches if a node equals another node.
 
 Stmt has pointer identity in the AST.
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 3636def66d..3d67767688 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -3504,15 +3504,15 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
 /// \brief Matches if a node equals another node.
 ///
 /// \c Decl has pointer identity in the AST.
-AST_MATCHER_P_OVERLOAD(Decl, equalsNode, Decl*, Other, 0) {
-  return &Node == Other;
+inline internal::Matcher equalsNode(const Decl *Node) {
+  return makeMatcher(new internal::EqualsNodeMatcher(Node));
 }
 /// \brief Matches if a node equals another node.
 ///
 /// \c Stmt has pointer identity in the AST.
 ///
-AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, Stmt*, Other, 1) {
-  return &Node == Other;
+inline internal::Matcher equalsNode(const Stmt *Node) {
+  return makeMatcher(new internal::EqualsNodeMatcher(Node));
 }
 
 /// @}
diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h
index ed20dee088..c0dd7b876e 100644
--- a/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1387,6 +1387,20 @@ private:
   const ValueT ExpectedValue;
 };
 
+template 
+class EqualsNodeMatcher : public SingleNodeMatcherInterface {
+public:
+  explicit EqualsNodeMatcher(const T *ExpectedNode)
+      : ExpectedNode(ExpectedNode) {}
+
+  bool matchesNode(const T &Node) const override {
+    return &Node == ExpectedNode;
+  }
+
+private:
+  const T *ExpectedNode;
+};
+
 /// \brief A VariadicDynCastAllOfMatcher object is a
 /// variadic functor that takes a number of Matcher and returns a
 /// Matcher that matches TargetT nodes that are matched by all of the
diff --git a/unittests/ASTMatchers/ASTMatchersTest.cpp b/unittests/ASTMatchers/ASTMatchersTest.cpp
index 9d9b2a15b7..691719c04e 100644
--- a/unittests/ASTMatchers/ASTMatchersTest.cpp
+++ b/unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -4158,24 +4158,32 @@ public:
   }
 
   bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
+    // Use the original typed pointer to verify we can pass pointers to subtypes
+    // to equalsNode.
+    const T *TypedNode = cast(Node);
     return selectFirst(
-        "", match(stmt(hasParent(stmt(has(stmt(equalsNode(Node)))).bind(""))),
-                  *Node, Context)) != NULL;
+               "", match(stmt(hasParent(
+                             stmt(has(stmt(equalsNode(TypedNode)))).bind(""))),
+                         *Node, Context)) != NULL;
   }
   bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
+    // Use the original typed pointer to verify we can pass pointers to subtypes
+    // to equalsNode.
+    const T *TypedNode = cast(Node);
     return selectFirst(
-        "", match(decl(hasParent(decl(has(decl(equalsNode(Node)))).bind(""))),
-                  *Node, Context)) != NULL;
+               "", match(decl(hasParent(
+                             decl(has(decl(equalsNode(TypedNode)))).bind(""))),
+                         *Node, Context)) != NULL;
   }
 };
 
 TEST(IsEqualTo, MatchesNodesByIdentity) {
   EXPECT_TRUE(matchAndVerifyResultTrue(
       "class X { class Y {}; };", recordDecl(hasName("::X::Y")).bind(""),
-      new VerifyAncestorHasChildIsEqual()));
-  EXPECT_TRUE(
-      matchAndVerifyResultTrue("void f() { if(true) {} }", ifStmt().bind(""),
-                               new VerifyAncestorHasChildIsEqual()));
+      new VerifyAncestorHasChildIsEqual()));
+  EXPECT_TRUE(matchAndVerifyResultTrue(
+      "void f() { if (true) if(true) {} }", ifStmt().bind(""),
+      new VerifyAncestorHasChildIsEqual()));
 }
 
 class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
-- 
2.40.0