baloghadamsoftware updated this revision to Diff 54642.
baloghadamsoftware added a comment.
Updated according to the comments.
http://reviews.llvm.org/D19357
Files:
docs/LibASTMatchersReference.html
include/clang/ASTMatchers/ASTMatchers.h
lib/ASTMatchers/Dynamic/Registry.cpp
unittests/ASTMatchers/ASTMatchersTest.cpp
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
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: 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<FunctionDecl>,
+ InnerMatcher) {
+ const auto &Parents = Finder->getASTContext().getParents(Node);
+
+ llvm::SmallVector<ast_type_traits::DynTypedNode, 8> Stack(Parents.begin(),
+ Parents.end());
+ while(!Stack.empty()) {
+ const auto &CurNode = Stack.back();
+ Stack.pop_back();
+ if(const auto *FuncDeclNode = CurNode.get<FunctionDecl>()) {
+ if(InnerMatcher.matches(*FuncDeclNode, Finder, Builder)) {
+ return true;
+ }
+ } else if(const auto *LambdaExprNode = CurNode.get<LambdaExpr>()) {
+ 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: docs/LibASTMatchersReference.html
===================================================================
--- docs/LibASTMatchersReference.html
+++ docs/LibASTMatchersReference.html
@@ -4923,6 +4923,20 @@
</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('forFunction0')"><a name="forFunction0Anchor">forFunction</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>> InnerMatcher</td></tr>
+<tr><td colspan="4" class="doc" id="forFunction0"><pre>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'
+</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('sizeOfExpr0')"><a name="sizeOfExpr0Anchor">sizeOfExpr</a></td><td>Matcher<<a href="http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>> InnerMatcher</td></tr>
<tr><td colspan="4" class="doc" id="sizeOfExpr0"><pre>Same as unaryExprOrTypeTraitExpr, but only matching
sizeof.
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits