diff options
author | Manuel Klimek <klimek@google.com> | 2014-05-27 12:31:10 +0000 |
---|---|---|
committer | Manuel Klimek <klimek@google.com> | 2014-05-27 12:31:10 +0000 |
commit | e0652d113ae77cb181c7164569e34af1f53612da (patch) | |
tree | e5879c989ed9ac8fdc0eb47809278ae10f43b264 | |
parent | 80678be7b0a70843ac2cd2dae0efbe274df0782e (diff) | |
download | clang-e0652d113ae77cb181c7164569e34af1f53612da.tar.gz clang-e0652d113ae77cb181c7164569e34af1f53612da.tar.bz2 clang-e0652d113ae77cb181c7164569e34af1f53612da.tar.xz |
Make equalsNode work with pointers to subtypes.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@209652 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | docs/LibASTMatchersReference.html | 4 | ||||
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchers.h | 8 | ||||
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchersInternal.h | 14 | ||||
-rw-r--r-- | 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. </pre></td></tr> -<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('equalsNode0')"><a name="equalsNode0Anchor">equalsNode</a></td><td>Decl* Other</td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>></td><td class="name" onclick="toggle('equalsNode0')"><a name="equalsNode0Anchor">equalsNode</a></td><td>Decl *Node</td></tr> <tr><td colspan="4" class="doc" id="equalsNode0"><pre>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. </pre></td></tr> -<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('equalsNode1')"><a name="equalsNode1Anchor">equalsNode</a></td><td>Stmt* Other</td></tr> +<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('equalsNode1')"><a name="equalsNode1Anchor">equalsNode</a></td><td>Stmt *Node</td></tr> <tr><td colspan="4" class="doc" id="equalsNode1"><pre>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<Decl> equalsNode(const Decl *Node) { + return makeMatcher(new internal::EqualsNodeMatcher<Decl>(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<Stmt> equalsNode(const Stmt *Node) { + return makeMatcher(new internal::EqualsNodeMatcher<Stmt>(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 <typename T> +class EqualsNodeMatcher : public SingleNodeMatcherInterface<T> { +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<SourceT, TargetT> object is a /// variadic functor that takes a number of Matcher<TargetT> and returns a /// Matcher<SourceT> 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<T>(Node); return selectFirst<const T>( - "", 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<T>(Node); return selectFirst<const T>( - "", 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<Decl>())); - EXPECT_TRUE( - matchAndVerifyResultTrue("void f() { if(true) {} }", ifStmt().bind(""), - new VerifyAncestorHasChildIsEqual<Stmt>())); + new VerifyAncestorHasChildIsEqual<CXXRecordDecl>())); + EXPECT_TRUE(matchAndVerifyResultTrue( + "void f() { if (true) if(true) {} }", ifStmt().bind(""), + new VerifyAncestorHasChildIsEqual<IfStmt>())); } class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback { |