summaryrefslogtreecommitdiffstats
path: root/test/CodeGenCoroutines
diff options
context:
space:
mode:
authorGor Nishanov <GorNishanov@gmail.com>2017-05-24 15:44:57 +0000
committerGor Nishanov <GorNishanov@gmail.com>2017-05-24 15:44:57 +0000
commit428da5f9a1ac02001f8744d640875d3aedb8064a (patch)
tree8aa045785fcc30517f2d40defa48d6fb23b63fc5 /test/CodeGenCoroutines
parentaa8caaeedba138d49222e6baae4deaa1a3dfc78e (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.cpp58
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(