diff options
author | Gor Nishanov <GorNishanov@gmail.com> | 2017-05-24 15:44:57 +0000 |
---|---|---|
committer | Gor Nishanov <GorNishanov@gmail.com> | 2017-05-24 15:44:57 +0000 |
commit | 428da5f9a1ac02001f8744d640875d3aedb8064a (patch) | |
tree | 8aa045785fcc30517f2d40defa48d6fb23b63fc5 /test/CodeGenCoroutines | |
parent | aa8caaeedba138d49222e6baae4deaa1a3dfc78e (diff) |
[coroutines] Make generic lambda coroutines work
Summary:
1. Coroutine cannot be constexpr (added a check in SemaLambda.cpp not to mark coroutine as constexpr)
2. TransformCoroutineBodyStmt should transform ResultDecl and ReturnStmt
Reviewers: rsmith, GorNishanov
Reviewed By: GorNishanov
Subscribers: EricWF, cfe-commits
Differential Revision: https://reviews.llvm.org/D33498
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@303764 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCoroutines')
-rw-r--r-- | test/CodeGenCoroutines/coro-lambda.cpp | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/test/CodeGenCoroutines/coro-lambda.cpp b/test/CodeGenCoroutines/coro-lambda.cpp new file mode 100644 index 0000000000..cd3256dc07 --- /dev/null +++ b/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( |