diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -855,6 +855,8 @@ AST Matchers ------------ +- Add ``coroutineBodyStmt`` matcher. + clang-format ------------ - Add ``RemoveSemicolon`` option for removing ``;`` after a non-empty function definition. diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2449,6 +2449,17 @@ extern const internal::VariadicDynCastAllOfMatcher coyieldExpr; +/// Matches coroutine body statements. +/// +/// coroutineBodyStmt() matches the coroutine below +/// \code +/// generator gen() { +/// co_return; +/// } +/// \endcode +extern const internal::VariadicDynCastAllOfMatcher + coroutineBodyStmt; + /// Matches nullptr literal. extern const internal::VariadicDynCastAllOfMatcher cxxNullPtrLiteralExpr; diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -909,6 +909,7 @@ const internal::VariadicDynCastAllOfMatcher caseStmt; const internal::VariadicDynCastAllOfMatcher defaultStmt; const internal::VariadicDynCastAllOfMatcher compoundStmt; +const internal::VariadicDynCastAllOfMatcher coroutineBodyStmt; const internal::VariadicDynCastAllOfMatcher cxxCatchStmt; const internal::VariadicDynCastAllOfMatcher cxxTryStmt; const internal::VariadicDynCastAllOfMatcher cxxThrowExpr; diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -168,6 +168,7 @@ REGISTER_MATCHER(complexType); REGISTER_MATCHER(compoundLiteralExpr); REGISTER_MATCHER(compoundStmt); + REGISTER_MATCHER(coroutineBodyStmt); REGISTER_MATCHER(coawaitExpr); REGISTER_MATCHER(conditionalOperator); REGISTER_MATCHER(constantArrayType); diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -678,6 +678,26 @@ EXPECT_TRUE(matchesConditionally(CoYieldCode, coyieldExpr(isExpansionInMainFile()), true, {"-std=c++20", "-I/"}, M)); + + StringRef NonCoroCode = R"cpp( +#include +void non_coro_function() { +} +)cpp"; + + EXPECT_TRUE(matchesConditionally(CoReturnCode, + coroutineBodyStmt(), + true, {"-std=c++20", "-I/"}, M)); + EXPECT_TRUE(matchesConditionally(CoAwaitCode, + coroutineBodyStmt(), + true, {"-std=c++20", "-I/"}, M)); + EXPECT_TRUE(matchesConditionally(CoYieldCode, + coroutineBodyStmt(), + true, {"-std=c++20", "-I/"}, M)); + + EXPECT_FALSE(matchesConditionally(NonCoroCode, + coroutineBodyStmt(), + true, {"-std=c++20", "-I/"}, M)); } TEST(Matcher, isClassMessage) {