[PATCH] D33498: [coroutines] Make generic lambda coroutines work
Gor Nishanov via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed May 24 08:30:42 PDT 2017
GorNishanov created this revision.
Herald added a subscriber: EricWF.
1. Coroutine cannot be constexpr (added a check in SemaLambda.cpp not to mark coroutine as constexpr)
2. TransformCoroutineBodyStmt should transform ResultDecl and ReturnStmt
https://reviews.llvm.org/D33498
Files:
lib/Sema/SemaLambda.cpp
lib/Sema/TreeTransform.h
test/CodeGenCoroutines/coro-lambda.cpp
Index: test/CodeGenCoroutines/coro-lambda.cpp
===================================================================
--- /dev/null
+++ test/CodeGenCoroutines/coro-lambda.cpp
@@ -0,0 +1,58 @@
+// Verify that we synthesized the coroutine for a lambda inside of a function template.
+// RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -fexceptions -fcxx-exceptions -disable-llvm-passes | FileCheck %s
+
+namespace std::experimental {
+template <typename R, typename... T> struct coroutine_traits {
+ using promise_type = typename R::promise_type;
+};
+
+template <class Promise = void> struct coroutine_handle;
+template <> struct coroutine_handle<void> {
+ static coroutine_handle from_address(void *) noexcept;
+ coroutine_handle() = default;
+ template <class PromiseType>
+ coroutine_handle(coroutine_handle<PromiseType>) noexcept;
+};
+template <class Promise> struct coroutine_handle : coroutine_handle<void> {
+ coroutine_handle() = default;
+ static coroutine_handle from_address(void *) noexcept;
+};
+}
+
+struct suspend_always {
+ bool await_ready() noexcept;
+ void await_suspend(std::experimental::coroutine_handle<>) noexcept;
+ void await_resume() noexcept;
+};
+
+struct Task {
+ struct promise_type {
+ Task get_return_object();
+ void return_void() {}
+ suspend_always initial_suspend() noexcept;
+ suspend_always final_suspend() noexcept;
+ void unhandled_exception() noexcept;
+ };
+};
+
+template <typename _AwrT> auto SyncAwait(_AwrT &&A) {
+ if (!A.await_ready()) {
+ auto AwaitAsync = [&]() -> Task {
+ try { (void)(co_await A); } catch (...) {}
+ };
+ Task t = AwaitAsync();
+ }
+ return A.await_resume();
+}
+
+void f() {
+ suspend_always test;
+ SyncAwait(test);
+}
+
+// Verify that we synthesized the coroutine for a lambda inside SyncAwait
+// CHECK-LABEL: define linkonce_odr void @_ZZ9SyncAwaitIR14suspend_alwaysEDaOT_ENKUlvE_clEv(
+// CHECK: alloca %"struct.Task::promise_type"
+// CHECK: call token @llvm.coro.id(
+// CHECK: call i8 @llvm.coro.suspend(
+// CHECK: call i1 @llvm.coro.end(
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -6945,6 +6945,19 @@
if (DeallocRes.isInvalid())
return StmtError();
Builder.Deallocate = DeallocRes.get();
+
+ assert(S->getResultDecl() && "ResultDecl must already be built");
+ StmtResult ResultDecl = getDerived().TransformStmt(S->getResultDecl());
+ if (ResultDecl.isInvalid())
+ return StmtError();
+ Builder.ResultDecl = ResultDecl.get();
+
+ if (auto *ReturnStmt = S->getReturnStmt()) {
+ StmtResult Res = getDerived().TransformStmt(ReturnStmt);
+ if (Res.isInvalid())
+ return StmtError();
+ Builder.ReturnStmt = Res.get();
+ }
}
return getDerived().RebuildCoroutineBodyStmt(Builder);
Index: lib/Sema/SemaLambda.cpp
===================================================================
--- lib/Sema/SemaLambda.cpp
+++ lib/Sema/SemaLambda.cpp
@@ -1591,6 +1591,7 @@
// its constexpr-ness, supressing diagnostics while doing so.
if (getLangOpts().CPlusPlus1z && !CallOperator->isInvalidDecl() &&
!CallOperator->isConstexpr() &&
+ !isa<CoroutineBodyStmt>(CallOperator->getBody()) &&
!Class->getDeclContext()->isDependentContext()) {
TentativeAnalysisScope DiagnosticScopeGuard(*this);
CallOperator->setConstexpr(
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33498.100097.patch
Type: text/x-patch
Size: 3497 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20170524/963cdffb/attachment.bin>
More information about the cfe-commits
mailing list