Add "equalsNode" for types and "isCopyAssignmentOperator" matchers.

Summary: This matchers are going to be used in modernize-use-default, but are generic enough to be placed in ASTMatchers.h.

Reviewers: klimek

Subscribers: alexfh, cfe-commits, klimek

Differential Revision: http://reviews.llvm.org/D14152

llvm-svn: 251693
This commit is contained in:
Angel Garcia Gomez 2015-10-30 09:35:51 +00:00
parent d98bcc713d
commit 4647ed74ac
2 changed files with 52 additions and 1 deletions

View File

@ -3385,6 +3385,23 @@ AST_MATCHER(CXXMethodDecl, isConst) {
return Node.isConst();
}
/// \brief Matches if the given method declaration declares a copy assignment
/// operator.
///
/// Given
/// \code
/// struct A {
/// A &operator=(const A &);
/// A &operator=(A &&);
/// };
/// \endcode
///
/// cxxMethodDecl(isCopyAssignmentOperator()) matches the first method but not
/// the second one.
AST_MATCHER(CXXMethodDecl, isCopyAssignmentOperator) {
return Node.isCopyAssignmentOperator();
}
/// \brief Matches if the given method declaration overrides another method.
///
/// Given
@ -4307,10 +4324,15 @@ AST_MATCHER_P_OVERLOAD(Decl, equalsNode, const Decl*, Other, 0) {
/// \brief Matches if a node equals another node.
///
/// \c Stmt has pointer identity in the AST.
///
AST_MATCHER_P_OVERLOAD(Stmt, equalsNode, const Stmt*, Other, 1) {
return &Node == Other;
}
/// \brief Matches if a node equals another node.
///
/// \c Type has pointer identity in the AST.
AST_MATCHER_P_OVERLOAD(Type, equalsNode, const Type*, Other, 2) {
return &Node == Other;
}
/// @}

View File

@ -1890,6 +1890,21 @@ TEST(Matcher, MatchesPureMethod) {
EXPECT_TRUE(notMatches("class X { int f(); };", cxxMethodDecl(isPure())));
}
TEST(Matcher, MatchesCopyAssignmentOperator) {
EXPECT_TRUE(matches("class X { X &operator=(X); };",
cxxMethodDecl(isCopyAssignmentOperator())));
EXPECT_TRUE(matches("class X { X &operator=(X &); };",
cxxMethodDecl(isCopyAssignmentOperator())));
EXPECT_TRUE(matches("class X { X &operator=(const X &); };",
cxxMethodDecl(isCopyAssignmentOperator())));
EXPECT_TRUE(matches("class X { X &operator=(volatile X &); };",
cxxMethodDecl(isCopyAssignmentOperator())));
EXPECT_TRUE(matches("class X { X &operator=(const volatile X &); };",
cxxMethodDecl(isCopyAssignmentOperator())));
EXPECT_TRUE(notMatches("class X { X &operator=(X &&); };",
cxxMethodDecl(isCopyAssignmentOperator())));
}
TEST(Matcher, MatchesConstMethod) {
EXPECT_TRUE(
matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));
@ -4671,6 +4686,16 @@ public:
decl(has(decl(equalsNode(TypedNode)))).bind(""))),
*Node, Context)) != nullptr;
}
bool verify(const BoundNodes &Nodes, ASTContext &Context, const Type *Node) {
// Use the original typed pointer to verify we can pass pointers to subtypes
// to equalsNode.
const T *TypedNode = cast<T>(Node);
const auto *Dec = Nodes.getNodeAs<FieldDecl>("decl");
return selectFirst<T>(
"", match(fieldDecl(hasParent(decl(has(fieldDecl(
hasType(type(equalsNode(TypedNode)).bind(""))))))),
*Dec, Context)) != nullptr;
}
};
TEST(IsEqualTo, MatchesNodesByIdentity) {
@ -4680,6 +4705,10 @@ TEST(IsEqualTo, MatchesNodesByIdentity) {
EXPECT_TRUE(matchAndVerifyResultTrue(
"void f() { if (true) if(true) {} }", ifStmt().bind(""),
new VerifyAncestorHasChildIsEqual<IfStmt>()));
EXPECT_TRUE(matchAndVerifyResultTrue(
"class X { class Y {} y; };",
fieldDecl(hasName("y"), hasType(type().bind(""))).bind("decl"),
new VerifyAncestorHasChildIsEqual<Type>()));
}
TEST(MatchFinder, CheckProfiling) {