njames93 created this revision. njames93 added reviewers: aaron.ballman, klimek. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Extend hasReturnValue to match the last statement in a gnu statement expression if the last statement is an expression. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D76196 Files: clang/docs/LibASTMatchersReference.html clang/include/clang/ASTMatchers/ASTMatchers.h clang/include/clang/ASTMatchers/ASTMatchersInternal.h clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
Index: clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp =================================================================== --- clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -3004,6 +3004,10 @@ EXPECT_TRUE(matches("int F() { int a, b; return a + b; }", RetVal)); EXPECT_FALSE(matches("int F() { int a; return a; }", RetVal)); EXPECT_FALSE(matches("void F() { return; }", RetVal)); + StatementMatcher RetStmtExprVal = stmtExpr(hasReturnValue(binaryOperator())); + EXPECT_TRUE(matches("void F() { ({int a, b; a + b;}); }", RetStmtExprVal)); + EXPECT_FALSE(matches("void F() { ({int a; a;}); }", RetStmtExprVal)); + EXPECT_FALSE(matches("void F() { ({int a;}); }", RetStmtExprVal)); } TEST(StatementMatcher, ForFunction) { Index: clang/include/clang/ASTMatchers/ASTMatchersInternal.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchersInternal.h +++ clang/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -1852,6 +1852,17 @@ return Node.getSubStmt(); } +inline const Expr *getReturnValue(const ReturnStmt &Node) { + return Node.getRetValue(); +} + +inline const Expr *getReturnValue(const StmtExpr &Node) { + const CompoundStmt *CS = Node.getSubStmt(); + if (!CS) + return nullptr; + return llvm::dyn_cast_or_null<Expr>(CS->body_back()); +} + /// If \p Loc is (transitively) expanded from macro \p MacroName, returns the /// location (in the chain of expansions) at which \p MacroName was /// expanded. Since the macro may have been expanded inside a series of Index: clang/include/clang/ASTMatchers/ASTMatchers.h =================================================================== --- clang/include/clang/ASTMatchers/ASTMatchers.h +++ clang/include/clang/ASTMatchers/ASTMatchers.h @@ -6712,21 +6712,27 @@ return false; } -/// Matches the return value expression of a return statement +/// Matches the return value expression of a return statement or GNU statement +/// expression. /// /// Given /// \code +/// auto i = ({foo(); *ptr;}) /// return a + b; /// \endcode /// hasReturnValue(binaryOperator()) /// matches 'return a + b' /// with binaryOperator() /// matching 'a + b' -AST_MATCHER_P(ReturnStmt, hasReturnValue, internal::Matcher<Expr>, - InnerMatcher) { - if (const auto *RetValue = Node.getRetValue()) - return InnerMatcher.matches(*RetValue, Finder, Builder); - return false; +/// hasReturnValue(unaryOperator()) +/// matches ({foo(); *ptr;}) +/// with unaryOperator() +/// matching '*ptr' +AST_POLYMORPHIC_MATCHER_P(hasReturnValue, + AST_POLYMORPHIC_SUPPORTED_TYPES(ReturnStmt, StmtExpr), + internal::Matcher<Expr>, InnerMatcher) { + const Expr *Ret = internal::getReturnValue(Node); + return Ret && InnerMatcher.matches(*Ret, Finder, Builder); } /// Matches CUDA kernel call expression. Index: clang/docs/LibASTMatchersReference.html =================================================================== --- clang/docs/LibASTMatchersReference.html +++ clang/docs/LibASTMatchersReference.html @@ -7164,14 +7164,20 @@ <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ReturnStmt.html">ReturnStmt</a>></td><td class="name" onclick="toggle('hasReturnValue0')"><a name="hasReturnValue0Anchor">hasReturnValue</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> -<tr><td colspan="4" class="doc" id="hasReturnValue0"><pre>Matches the return value expression of a return statement +<tr><td colspan="4" class="doc" id="hasReturnValue0"><pre>Matches the return value expression of a return statement or GNU statement +expression. Given + auto i = ({foo(); *ptr;}) return a + b; hasReturnValue(binaryOperator()) matches 'return a + b' with binaryOperator() matching 'a + b' +hasReturnValue(unaryOperator()) + matches ({foo(); *ptr;}) +with unaryOperator() + matching '*ptr' </pre></td></tr> @@ -7188,6 +7194,24 @@ </pre></td></tr> +<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1StmtExpr.html">StmtExpr</a>></td><td class="name" onclick="toggle('hasReturnValue1')"><a name="hasReturnValue1Anchor">hasReturnValue</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr> +<tr><td colspan="4" class="doc" id="hasReturnValue1"><pre>Matches the return value expression of a return statement or GNU statement +expression. + +Given + auto i = ({foo(); *ptr;}) + return a + b; +hasReturnValue(binaryOperator()) + matches 'return a + b' +with binaryOperator() + matching 'a + b' +hasReturnValue(unaryOperator()) + matches ({foo(); *ptr;}) +with unaryOperator() + matching '*ptr' +</pre></td></tr> + + <tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Stmt.html">Stmt</a>></td><td class="name" onclick="toggle('alignOfExpr0')"><a name="alignOfExpr0Anchor">alignOfExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html">UnaryExprOrTypeTraitExpr</a>> InnerMatcher</td></tr> <tr><td colspan="4" class="doc" id="alignOfExpr0"><pre>Same as unaryExprOrTypeTraitExpr, but only matching alignof.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits