[clang] 5548616 - [ASTMatcher] Add AST Matcher support for C++20 coroutine keywords
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Sun Mar 21 19:28:16 PDT 2021
Author: Chuanqi Xu
Date: 2021-03-22T10:27:46+08:00
New Revision: 55486161fa0bc29519bf53f0e6302b14d8de5578
URL: https://github.com/llvm/llvm-project/commit/55486161fa0bc29519bf53f0e6302b14d8de5578
DIFF: https://github.com/llvm/llvm-project/commit/55486161fa0bc29519bf53f0e6302b14d8de5578.diff
LOG: [ASTMatcher] Add AST Matcher support for C++20 coroutine keywords
Summary: Try to enable the support for C++20 coroutine keywords for AST
Matchers.
Reviewers: sammccall, njames93, aaron.ballman
Differential Revision: https://reviews.llvm.org/D96316
Added:
Modified:
clang/docs/LibASTMatchersReference.html
clang/include/clang/ASTMatchers/ASTMatchers.h
clang/lib/ASTMatchers/ASTMatchersInternal.cpp
clang/lib/ASTMatchers/Dynamic/Registry.cpp
clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
Removed:
################################################################################
diff --git a/clang/docs/LibASTMatchersReference.html b/clang/docs/LibASTMatchersReference.html
index 0d2570bcd58f..b8fb27b126fc 100644
--- a/clang/docs/LibASTMatchersReference.html
+++ b/clang/docs/LibASTMatchersReference.html
@@ -1337,6 +1337,16 @@ <h2 id="decl-matchers">Node Matchers</h2>
</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('coawaitExpr0')"><a name="coawaitExpr0Anchor">coawaitExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CoawaitExpr.html">CoawaitExpr</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="coawaitExpr0"><pre>Matches co_await expressions.
+
+Given
+ co_await 1;
+coawaitExpr()
+ matches 'co_await 1'
+</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('compoundLiteralExpr0')"><a name="compoundLiteralExpr0Anchor">compoundLiteralExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="compoundLiteralExpr0"><pre>Matches compound (i.e. non-scalar) literals
@@ -1383,6 +1393,26 @@ <h2 id="decl-matchers">Node Matchers</h2>
</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('coreturnStmt0')"><a name="coreturnStmt0Anchor">coreturnStmt</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CoreturnStmt.html">CoreturnStmt</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="coreturnStmt0"><pre>Matches co_return statements.
+
+Given
+ while (true) { co_return; }
+coreturnStmt()
+ matches 'co_return'
+</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('coyieldExpr0')"><a name="coyieldExpr0Anchor">coyieldExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CoyieldExpr.html">CoyieldExpr</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="coyieldExpr0"><pre>Matches co_yield expressions.
+
+Given
+ co_yield 1;
+coyieldExpr()
+ matches 'co_yield 1'
+</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('cudaKernelCallExpr0')"><a name="cudaKernelCallExpr0Anchor">cudaKernelCallExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CUDAKernelCallExpr.html">CUDAKernelCallExpr</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="cudaKernelCallExpr0"><pre>Matches CUDA kernel call expression.
@@ -1698,6 +1728,11 @@ <h2 id="decl-matchers">Node Matchers</h2>
</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('dependentCoawaitExpr0')"><a name="dependentCoawaitExpr0Anchor">dependentCoawaitExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DependentCoawaitExpr.html">DependentCoawaitExpr</a>>...</td></tr>
+<tr><td colspan="4" class="doc" id="dependentCoawaitExpr0"><pre>Matches co_await expressions where the type of the promise is dependent
+</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('designatedInitExpr0')"><a name="designatedInitExpr0Anchor">designatedInitExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DesignatedInitExpr.html">DesignatedInitExpr</a>>...</td></tr>
<tr><td colspan="4" class="doc" id="designatedInitExpr0"><pre>Matches C99 designated initializer expressions [C99 6.7.8].
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 64e8cecf4822..fd0e9d6d7c1f 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -2162,6 +2162,17 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
extern const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt>
continueStmt;
+/// Matches co_return statements.
+///
+/// Given
+/// \code
+/// while (true) { co_return; }
+/// \endcode
+/// coreturnStmt()
+/// matches 'co_return'
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoreturnStmt>
+ coreturnStmt;
+
/// Matches return statements.
///
/// Given
@@ -2379,6 +2390,30 @@ extern const internal::VariadicDynCastAllOfMatcher<Stmt, UserDefinedLiteral>
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
compoundLiteralExpr;
+/// Matches co_await expressions.
+///
+/// Given
+/// \code
+/// co_await 1;
+/// \endcode
+/// coawaitExpr()
+/// matches 'co_await 1'
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoawaitExpr>
+ coawaitExpr;
+/// Matches co_await expressions where the type of the promise is dependent
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, DependentCoawaitExpr>
+ dependentCoawaitExpr;
+/// Matches co_yield expressions.
+///
+/// Given
+/// \code
+/// co_yield 1;
+/// \endcode
+/// coyieldExpr()
+/// matches 'co_yield 1'
+extern const internal::VariadicDynCastAllOfMatcher<Stmt, CoyieldExpr>
+ coyieldExpr;
+
/// Matches nullptr literal.
extern const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
cxxNullPtrLiteralExpr;
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index b20a60425661..c2001070de55 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -883,6 +883,7 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, WhileStmt> whileStmt;
const internal::VariadicDynCastAllOfMatcher<Stmt, DoStmt> doStmt;
const internal::VariadicDynCastAllOfMatcher<Stmt, BreakStmt> breakStmt;
const internal::VariadicDynCastAllOfMatcher<Stmt, ContinueStmt> continueStmt;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CoreturnStmt> coreturnStmt;
const internal::VariadicDynCastAllOfMatcher<Stmt, ReturnStmt> returnStmt;
const internal::VariadicDynCastAllOfMatcher<Stmt, GotoStmt> gotoStmt;
const internal::VariadicDynCastAllOfMatcher<Stmt, LabelStmt> labelStmt;
@@ -915,6 +916,12 @@ const internal::VariadicDynCastAllOfMatcher<Stmt, CompoundLiteralExpr>
const internal::VariadicDynCastAllOfMatcher<Stmt, CXXNullPtrLiteralExpr>
cxxNullPtrLiteralExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, ChooseExpr> chooseExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CoawaitExpr>
+ coawaitExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, DependentCoawaitExpr>
+ dependentCoawaitExpr;
+const internal::VariadicDynCastAllOfMatcher<Stmt, CoyieldExpr>
+ coyieldExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, GNUNullExpr> gnuNullExpr;
const internal::VariadicDynCastAllOfMatcher<Stmt, GenericSelectionExpr>
genericSelectionExpr;
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index bfc46b7742d6..8e595deac2cd 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -166,11 +166,14 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(complexType);
REGISTER_MATCHER(compoundLiteralExpr);
REGISTER_MATCHER(compoundStmt);
+ REGISTER_MATCHER(coawaitExpr);
REGISTER_MATCHER(conditionalOperator);
REGISTER_MATCHER(constantArrayType);
REGISTER_MATCHER(constantExpr);
REGISTER_MATCHER(containsDeclaration);
REGISTER_MATCHER(continueStmt);
+ REGISTER_MATCHER(coreturnStmt);
+ REGISTER_MATCHER(coyieldExpr);
REGISTER_MATCHER(cudaKernelCallExpr);
REGISTER_MATCHER(cxxBindTemporaryExpr);
REGISTER_MATCHER(cxxBoolLiteral);
@@ -214,6 +217,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(decltypeType);
REGISTER_MATCHER(deducedTemplateSpecializationType);
REGISTER_MATCHER(defaultStmt);
+ REGISTER_MATCHER(dependentCoawaitExpr);
REGISTER_MATCHER(dependentSizedArrayType);
REGISTER_MATCHER(designatedInitExpr);
REGISTER_MATCHER(designatorCountIs);
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 9909cec2065c..bf4b0912c661 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -510,6 +510,83 @@ void foo()
varDecl(hasName("lPtrDecay"))))))));
}
+TEST(Matcher, MatchesCoroutine) {
+ FileContentMappings M;
+ M.push_back(std::make_pair("/coro_header", R"cpp(
+namespace std {
+namespace experimental {
+
+template <class... Args>
+struct void_t_imp {
+ using type = void;
+};
+template <class... Args>
+using void_t = typename void_t_imp<Args...>::type;
+
+template <class T, class = void>
+struct traits_sfinae_base {};
+
+template <class T>
+struct traits_sfinae_base<T, void_t<typename T::promise_type>> {
+ using promise_type = typename T::promise_type;
+};
+
+template <class Ret, class... Args>
+struct coroutine_traits : public traits_sfinae_base<Ret> {};
+}} // namespace std::experimental
+struct awaitable {
+ bool await_ready() noexcept;
+ template <typename F>
+ void await_suspend(F) noexcept;
+ void await_resume() noexcept;
+} a;
+struct promise {
+ void get_return_object();
+ awaitable initial_suspend();
+ awaitable final_suspend() noexcept;
+ awaitable yield_value(int); // expected-note 2{{candidate}}
+ void return_value(int); // expected-note 2{{here}}
+ void unhandled_exception();
+};
+template <typename... T>
+struct std::experimental::coroutine_traits<void, T...> { using promise_type = promise; };
+namespace std {
+namespace experimental {
+template <class PromiseType = void>
+struct coroutine_handle {
+ static coroutine_handle from_address(void *) noexcept;
+};
+}} // namespace std::experimental
+)cpp"));
+ StringRef CoReturnCode = R"cpp(
+#include <coro_header>
+void check_match_co_return() {
+ co_return 1;
+}
+)cpp";
+ EXPECT_TRUE(matchesConditionally(CoReturnCode,
+ coreturnStmt(isExpansionInMainFile()),
+ true, {"-std=c++20", "-I/"}, M));
+ StringRef CoAwaitCode = R"cpp(
+#include <coro_header>
+void check_match_co_await() {
+ co_await a;
+}
+)cpp";
+ EXPECT_TRUE(matchesConditionally(CoAwaitCode,
+ coawaitExpr(isExpansionInMainFile()),
+ true, {"-std=c++20", "-I/"}, M));
+ StringRef CoYieldCode = R"cpp(
+#include <coro_header>
+void check_match_co_yield() {
+ co_yield 1.0;
+}
+)cpp";
+ EXPECT_TRUE(matchesConditionally(CoYieldCode,
+ coyieldExpr(isExpansionInMainFile()),
+ true, {"-std=c++20", "-I/"}, M));
+}
+
TEST(Matcher, isClassMessage) {
EXPECT_TRUE(matchesObjC(
"@interface NSString +(NSString *) stringWithFormat; @end "
More information about the cfe-commits
mailing list