Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -1814,6 +1814,21 @@ +
Matches if the given method declaration declares a move assignment +operator. + +Given +struct A { + A &operator=(const A &); + A &operator=(A &&); +}; + +cxxMethodDecl(isMoveAssignmentOperator()) matches the second method but not +the first one. +
Matches if the given method declaration overrides another method. Index: include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- include/clang/ASTMatchers/ASTMatchers.h +++ include/clang/ASTMatchers/ASTMatchers.h @@ -3558,6 +3558,21 @@ return Node.isCopyAssignmentOperator(); } +/// \brief Matches if the given method declaration declares a move assignment +/// operator. +/// +/// Given +/// \code +/// struct S { +/// S(const S &); // #1 +/// S& operator=(S &&); // #2 +/// }; +/// \endcode +/// cxxMethodDecl(isMoveAssignmentOperator()) will match #2, but not #1. +AST_MATCHER(CXXMethodDecl, isMoveAssignmentOperator) { + return Node.isMoveAssignmentOperator(); +} + /// \brief Matches if the given method declaration overrides another method. /// /// Given Index: lib/ASTMatchers/Dynamic/Registry.cpp =================================================================== --- lib/ASTMatchers/Dynamic/Registry.cpp +++ lib/ASTMatchers/Dynamic/Registry.cpp @@ -291,6 +291,7 @@ REGISTER_MATCHER(isInTemplateInstantiation); REGISTER_MATCHER(isListInitialization); REGISTER_MATCHER(isMemberInitializer); + REGISTER_MATCHER(isMoveAssignmentOperator); REGISTER_MATCHER(isMoveConstructor); REGISTER_MATCHER(isNoThrow); REGISTER_MATCHER(isOverride); Index: unittests/ASTMatchers/ASTMatchersTest.cpp =================================================================== --- unittests/ASTMatchers/ASTMatchersTest.cpp +++ unittests/ASTMatchers/ASTMatchersTest.cpp @@ -2049,6 +2049,21 @@ cxxMethodDecl(isCopyAssignmentOperator()))); } +TEST(Matcher, MatchesMoveAssignmentOperator) { + EXPECT_TRUE(notMatches("class X { X &operator=(X); };", + cxxMethodDecl(isMoveAssignmentOperator()))); + EXPECT_TRUE(matches("class X { X &operator=(X &&); };", + cxxMethodDecl(isMoveAssignmentOperator()))); + EXPECT_TRUE(matches("class X { X &operator=(const X &&); };", + cxxMethodDecl(isMoveAssignmentOperator()))); + EXPECT_TRUE(matches("class X { X &operator=(volatile X &&); };", + cxxMethodDecl(isMoveAssignmentOperator()))); + EXPECT_TRUE(matches("class X { X &operator=(const volatile X &&); };", + cxxMethodDecl(isMoveAssignmentOperator()))); + EXPECT_TRUE(notMatches("class X { X &operator=(X &); };", + cxxMethodDecl(isMoveAssignmentOperator()))); +} + TEST(Matcher, MatchesConstMethod) { EXPECT_TRUE( matches("struct A { void foo() const; };", cxxMethodDecl(isConst())));