Index: docs/LibASTMatchersReference.html =================================================================== --- docs/LibASTMatchersReference.html +++ docs/LibASTMatchersReference.html @@ -4923,6 +4923,20 @@ +Matcher<Stmt>forFunctionMatcher<FunctionDecl> InnerMatcher +
Matches declaration of the function the statemenet belongs to
+
+Given:
+F& operator=(const F& o) {
+  std::copy_if(o.begin(), o.end(), begin(), [](V v) { return v > 0; });
+  return *this;
+}
+returnStmt(forFunction(hasName("operator=")))
+  matches 'return *this'
+  but does match 'return > 0'
+
+ + Matcher<Stmt>sizeOfExprMatcher<UnaryExprOrTypeTraitExpr> InnerMatcher
Same as unaryExprOrTypeTraitExpr, but only matching
 sizeof.
Index: include/clang/ASTMatchers/ASTMatchers.h
===================================================================
--- include/clang/ASTMatchers/ASTMatchers.h
+++ include/clang/ASTMatchers/ASTMatchers.h
@@ -5108,6 +5108,45 @@
       gnuNullExpr(), cxxNullPtrLiteralExpr(),
       integerLiteral(equals(0), hasParent(expr(hasType(pointerType())))));
 }
+
+/// \brief Matches declaration of the function the statemenet belongs to
+///
+/// Given:
+/// \code
+/// F& operator=(const F& o) {
+///   std::copy_if(o.begin(), o.end(), begin(), [](V v) { return v > 0; });
+///   return *this;
+/// }
+/// \endcode
+/// returnStmt(forFunction(hasName("operator=")))
+///   matches 'return *this'
+///   but does match 'return > 0'
+AST_MATCHER_P(Stmt, forFunction, internal::Matcher,
+              InnerMatcher) {
+  const auto &Parents = Finder->getASTContext().getParents(Node);
+
+  llvm::SmallVector Stack(Parents.begin(),
+                                                            Parents.end());
+  while(!Stack.empty()) {
+    const auto &CurNode = Stack.back();
+    Stack.pop_back();
+    if(const auto *FuncDeclNode = CurNode.get()) {
+      if(InnerMatcher.matches(*FuncDeclNode, Finder, Builder)) {
+        return true;
+      }
+    } else if(const auto *LambdaExprNode = CurNode.get()) {
+      if(InnerMatcher.matches(*LambdaExprNode->getCallOperator(),
+                              Finder, Builder)) {
+        return true;
+      }
+    } else {
+      for(const auto &Parent: Finder->getASTContext().getParents(CurNode))
+        Stack.push_back(Parent);
+    }
+  }
+  return false;
+}
+
 } // end namespace ast_matchers
 } // end namespace clang
 
Index: lib/ASTMatchers/Dynamic/Registry.cpp
===================================================================
--- lib/ASTMatchers/Dynamic/Registry.cpp
+++ lib/ASTMatchers/Dynamic/Registry.cpp
@@ -184,6 +184,7 @@
   REGISTER_MATCHER(forEachDescendant);
   REGISTER_MATCHER(forEachSwitchCase);
   REGISTER_MATCHER(forField);
+  REGISTER_MATCHER(forFunction);
   REGISTER_MATCHER(forStmt);
   REGISTER_MATCHER(friendDecl);
   REGISTER_MATCHER(functionDecl);
Index: unittests/ASTMatchers/ASTMatchersTest.cpp
===================================================================
--- unittests/ASTMatchers/ASTMatchersTest.cpp
+++ unittests/ASTMatchers/ASTMatchersTest.cpp
@@ -5568,5 +5568,40 @@
   EXPECT_FALSE(matches("void F() { return; }", RetVal));
 }
 
+TEST(StatementMatcher, ForFunction) {
+  const auto CppString1 =
+    "struct PosVec {"
+    "  PosVec& operator=(const PosVec&) {"
+    "    auto x = [] { return 1; };"
+    "    return *this;"
+    "  }"
+    "};";
+  const auto CppString2 =
+    "void F() {"
+    "  struct S {"
+    "    void F2() {"
+    "       return;"
+    "    }"
+    "  };"
+    "}";
+  EXPECT_TRUE(
+    matches(
+      CppString1,
+      returnStmt(forFunction(hasName("operator=")),
+                 has(unaryOperator(hasOperatorName("*"))))));
+  EXPECT_TRUE(
+    notMatches(
+      CppString1,
+      returnStmt(forFunction(hasName("operator=")),
+                 has(integerLiteral()))));
+  EXPECT_TRUE(
+    matches(
+      CppString1,
+      returnStmt(forFunction(hasName("operator()")),
+                 has(integerLiteral()))));
+  EXPECT_TRUE(matches(CppString2, returnStmt(forFunction(hasName("F2")))));
+  EXPECT_TRUE(notMatches(CppString2, returnStmt(forFunction(hasName("F")))));
+}
+
 } // end namespace ast_matchers
 } // end namespace clang