Author: Chris Cotter Date: 2023-03-01T11:51:46-05:00 New Revision: dcf5ad89dcc5cc69b9df3e5dd9be71c65642f519
URL: https://github.com/llvm/llvm-project/commit/dcf5ad89dcc5cc69b9df3e5dd9be71c65642f519 DIFF: https://github.com/llvm/llvm-project/commit/dcf5ad89dcc5cc69b9df3e5dd9be71c65642f519.diff LOG: [ASTMatcher] Add coroutineBodyStmt matcher The coroutineBodyStmt matcher matches CoroutineBodyStmt AST nodes. Differential Revision: https://reviews.llvm.org/D140794 Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/ASTMatchers/ASTMatchers.h clang/lib/ASTMatchers/ASTMatchersInternal.cpp clang/lib/ASTMatchers/Dynamic/Registry.cpp clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index d609f365bbcb5..ce37020aa86fb 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -258,6 +258,11 @@ Floating Point Support in Clang AST Matchers ------------ +- Add ``coroutineBodyStmt`` matcher. + +- The ``hasBody`` matcher now matches coroutine body nodes in + ``CoroutineBodyStmts``. + clang-format ------------ diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h index 98b727e6940b5..7a69f86844671 100644 --- a/clang/include/clang/ASTMatchers/ASTMatchers.h +++ b/clang/include/clang/ASTMatchers/ASTMatchers.h @@ -2450,6 +2450,17 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, DependentCoawaitExpr> extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoyieldExpr> coyieldExpr; +/// Matches coroutine body statements. +/// +/// coroutineBodyStmt() matches the coroutine below +/// \code +/// generator<int> gen() { +/// co_return; +/// } +/// \endcode +extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoroutineBodyStmt> + coroutineBodyStmt; + /// Matches nullptr literal. extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr> cxxNullPtrLiteralExpr; @@ -5460,9 +5471,10 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, return false; } -/// Matches a 'for', 'while', 'do' statement or a function definition that has -/// a given body. Note that in case of functions this matcher only matches the -/// definition itself and not the other declarations of the same function. +/// Matches a 'for', 'while', 'while' statement or a function or coroutine +/// definition that has a given body. Note that in case of functions or +/// coroutines this matcher only matches the definition itself and not the +/// other declarations of the same function or coroutine. /// /// Given /// \code @@ -5483,12 +5495,11 @@ AST_MATCHER_P(ArraySubscriptExpr, hasBase, /// with compoundStmt() /// matching '{}' /// but does not match 'void f();' -AST_POLYMORPHIC_MATCHER_P(hasBody, - AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt, - WhileStmt, - CXXForRangeStmt, - FunctionDecl), - internal::Matcher<Stmt>, InnerMatcher) { +AST_POLYMORPHIC_MATCHER_P( + hasBody, + AST_POLYMORPHIC_SUPPORTED_TYPES(DoStmt, ForStmt, WhileStmt, CXXForRangeStmt, + FunctionDecl, CoroutineBodyStmt), + internal::Matcher<Stmt>, InnerMatcher) { if (Finder->isTraversalIgnoringImplicitNodes() && isDefaultedHelper(&Node)) return false; const Stmt *const Statement = internal::GetBodyMatcher<NodeType>::get(Node); diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp index f1f73fc42075d..26e40c4ed36a5 100644 --- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -910,6 +910,8 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, SwitchCase> switchCase; const internal::VariadicDynCastAllOfMatcher<Stmt, CaseStmt> caseStmt; const internal::VariadicDynCastAllOfMatcher<Stmt, DefaultStmt> defaultStmt; const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundStmt> compoundStmt; +const internal::VariadicDynCastAllOfMatcher<Stmt, CoroutineBodyStmt> + coroutineBodyStmt; const internal::VariadicDynCastAllOfMatcher<Stmt, CXXCatchStmt> cxxCatchStmt; const internal::VariadicDynCastAllOfMatcher<Stmt, CXXTryStmt> cxxTryStmt; const internal::VariadicDynCastAllOfMatcher<Stmt, CXXThrowExpr> cxxThrowExpr; diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp index 0d436fa29a791..9bbb291df0639 100644 --- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp +++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp @@ -175,6 +175,7 @@ RegistryMaps::RegistryMaps() { REGISTER_MATCHER(containsDeclaration); REGISTER_MATCHER(continueStmt); REGISTER_MATCHER(coreturnStmt); + REGISTER_MATCHER(coroutineBodyStmt); REGISTER_MATCHER(coyieldExpr); REGISTER_MATCHER(cudaKernelCallExpr); REGISTER_MATCHER(cxxBaseSpecifier); diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index 922dbf20c247e..e6d2bb46dfcd3 100644 --- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -678,6 +678,48 @@ void check_match_co_yield() { EXPECT_TRUE(matchesConditionally(CoYieldCode, coyieldExpr(isExpansionInMainFile()), true, {"-std=c++20", "-I/"}, M)); + + StringRef NonCoroCode = R"cpp( +#include <coro_header> +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)); + + StringRef CoroWithDeclCode = R"cpp( +#include <coro_header> +void coro() { + int thevar; + co_return 1; +} +)cpp"; + EXPECT_TRUE(matchesConditionally( + CoroWithDeclCode, + coroutineBodyStmt(hasBody(compoundStmt( + has(declStmt(containsDeclaration(0, varDecl(hasName("thevar")))))))), + true, {"-std=c++20", "-I/"}, M)); + + StringRef CoroWithTryCatchDeclCode = R"cpp( +#include <coro_header> +void coro() try { + int thevar; + co_return 1; +} catch (...) {} +)cpp"; + EXPECT_TRUE(matchesConditionally( + CoroWithTryCatchDeclCode, + coroutineBodyStmt(hasBody(cxxTryStmt(has(compoundStmt(has( + declStmt(containsDeclaration(0, varDecl(hasName("thevar")))))))))), + true, {"-std=c++20", "-I/"}, M)); } TEST(Matcher, isClassMessage) { diff --git a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp index 2a02572913f6f..88e141052ae01 100644 --- a/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp +++ b/clang/unittests/ASTMatchers/Dynamic/ParserTest.cpp @@ -364,7 +364,8 @@ TEST(ParserTest, Errors) { "to build matcher: mapAnyOf.", ParseWithError("mapAnyOf(\"foo\")")); EXPECT_EQ("Input value has unresolved overloaded type: " - "Matcher<DoStmt|ForStmt|WhileStmt|CXXForRangeStmt|FunctionDecl>", + "Matcher<DoStmt|ForStmt|WhileStmt|CXXForRangeStmt|FunctionDecl|" + "CoroutineBodyStmt>", ParseMatcherWithError("hasBody(stmt())")); EXPECT_EQ( "1:1: Error parsing argument 1 for matcher decl.\n" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits