summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2014-05-27 12:31:10 +0000
committerManuel Klimek <klimek@google.com>2014-05-27 12:31:10 +0000
commite0652d113ae77cb181c7164569e34af1f53612da (patch)
treee5879c989ed9ac8fdc0eb47809278ae10f43b264
parent80678be7b0a70843ac2cd2dae0efbe274df0782e (diff)
downloadclang-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.html4
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h8
-rw-r--r--include/clang/ASTMatchers/ASTMatchersInternal.h14
-rw-r--r--unittests/ASTMatchers/ASTMatchersTest.cpp24
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&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</td><td class="name" onclick="toggle('equalsNode0')"><a name="equalsNode0Anchor">equalsNode</a></td><td>Decl* Other</td></tr>
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>&gt;</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&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</td><td class="name" onclick="toggle('equalsNode1')"><a name="equalsNode1Anchor">equalsNode</a></td><td>Stmt* Other</td></tr>
+<tr><td>Matcher&lt<a href="http://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>&gt;</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 {