</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 colspan="4" class="doc" id="equalsNode0"><pre>Matches if a node equals another node.
+
+Decl has pointer identity in the AST.
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FloatingLiteral.html">FloatingLiteral</a>></td><td class="name" onclick="toggle('equals1')"><a name="equals1Anchor">equals</a></td><td>ValueT Value</td></tr>
<tr><td colspan="4" class="doc" id="equals1"><pre>Matches literals that are equal to the given value.
</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 colspan="4" class="doc" id="equalsNode1"><pre>Matches if a node equals another node.
+
+Stmt has pointer identity in the AST.
+
+</pre></td></tr>
+
+
<tr><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1TagDecl.html">TagDecl</a>></td><td class="name" onclick="toggle('isDefinition0')"><a name="isDefinition0Anchor">isDefinition</a></td><td></td></tr>
<tr><td colspan="4" class="doc" id="isDefinition0"><pre>Matches if a declaration has a body attached.
return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
}
+/// \brief Overloads for the \c equalsNode matcher.
+/// FIXME: Implement for other node types.
+/// @{
+
+/// \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;
+}
+/// \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;
+}
+
+/// @}
+
} // end namespace ast_matchers
} // end namespace clang
"X", recordDecl(has(recordDecl(hasName("X::Z")).bind("Z"))), "Z")));
}
+template <typename T>
+class VerifyAncestorHasChildIsEqual : public BoundNodesCallback {
+public:
+ virtual bool run(const BoundNodes *Nodes) { return false; }
+
+ virtual bool run(const BoundNodes *Nodes, ASTContext *Context) {
+ const T *Node = Nodes->getNodeAs<T>("");
+ return verify(*Nodes, *Context, Node);
+ }
+
+ bool verify(const BoundNodes &Nodes, ASTContext &Context, const Stmt *Node) {
+ return selectFirst<const T>(
+ "", match(stmt(hasParent(stmt(has(stmt(equalsNode(Node)))).bind(""))),
+ *Node, Context)) != NULL;
+ }
+ bool verify(const BoundNodes &Nodes, ASTContext &Context, const Decl *Node) {
+ return selectFirst<const T>(
+ "", match(decl(hasParent(decl(has(decl(equalsNode(Node)))).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>()));
+}
+
class VerifyStartOfTranslationUnit : public MatchFinder::MatchCallback {
public:
VerifyStartOfTranslationUnit() : Called(false) {}