[docs] Add LICENSE.txt to the root of the mono-repo
[llvm-project.git] / clang / test / CodeGenCoroutines / coro-symmetric-transfer-02-exp-namespace.cpp
blob16030b104e63baa529a35f727412623d1ebcb651
1 // RUN: %clang_cc1 -no-opaque-pointers -triple x86_64-unknown-linux-gnu -fcoroutines-ts -std=c++14 -O1 -emit-llvm %s -o - -disable-llvm-passes | FileCheck %s
3 #include "Inputs/coroutine-exp-namespace.h"
5 namespace coro = std::experimental::coroutines_v1;
7 struct Task {
8 struct promise_type {
9 Task get_return_object() noexcept {
10 return Task{coro::coroutine_handle<promise_type>::from_promise(*this)};
13 void return_void() noexcept {}
15 struct final_awaiter {
16 bool await_ready() noexcept { return false; }
17 coro::coroutine_handle<> await_suspend(coro::coroutine_handle<promise_type> h) noexcept {
18 h.destroy();
19 return {};
21 void await_resume() noexcept {}
24 void unhandled_exception() noexcept {}
26 final_awaiter final_suspend() noexcept { return {}; }
28 coro::suspend_always initial_suspend() noexcept { return {}; }
30 template <typename Awaitable>
31 auto await_transform(Awaitable &&awaitable) {
32 return awaitable.co_viaIfAsync();
36 using handle_t = coro::coroutine_handle<promise_type>;
38 class Awaiter {
39 public:
40 explicit Awaiter(handle_t coro) noexcept;
41 Awaiter(Awaiter &&other) noexcept;
42 Awaiter(const Awaiter &) = delete;
43 ~Awaiter();
45 bool await_ready() noexcept { return false; }
46 handle_t await_suspend(coro::coroutine_handle<> continuation) noexcept;
47 void await_resume();
49 private:
50 handle_t coro_;
53 Task(handle_t coro) noexcept : coro_(coro) {}
55 handle_t coro_;
57 Task(const Task &t) = delete;
58 Task(Task &&t) noexcept;
59 ~Task();
60 Task &operator=(Task t) noexcept;
62 Awaiter co_viaIfAsync();
65 static Task foo() {
66 co_return;
69 Task bar() {
70 auto mode = 2;
71 switch (mode) {
72 case 1:
73 co_await foo();
74 break;
75 case 2:
76 co_await foo();
77 break;
78 default:
79 break;
83 // CHECK-LABEL: define{{.*}} void @_Z3barv
84 // CHECK: %[[MODE:.+]] = load i32, i32* %mode
85 // CHECK-NEXT: switch i32 %[[MODE]], label %{{.+}} [
86 // CHECK-NEXT: i32 1, label %[[CASE1:.+]]
87 // CHECK-NEXT: i32 2, label %[[CASE2:.+]]
88 // CHECK-NEXT: ]
90 // CHECK: [[CASE1]]:
91 // CHECK: br i1 %{{.+}}, label %[[CASE1_AWAIT_READY:.+]], label %[[CASE1_AWAIT_SUSPEND:.+]]
92 // CHECK: [[CASE1_AWAIT_SUSPEND]]:
93 // CHECK-NEXT: %{{.+}} = call token @llvm.coro.save(i8* null)
94 // CHECK-NEXT: %[[HANDLE11:.+]] = bitcast %"struct.std::experimental::coroutines_v1::coroutine_handle"* %[[TMP1:.+]] to i8*
95 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* %[[HANDLE11]])
97 // CHECK: %[[HANDLE12:.+]] = bitcast %"struct.std::experimental::coroutines_v1::coroutine_handle"* %[[TMP1]] to i8*
98 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* %[[HANDLE12]])
99 // CHECK-NEXT: call void @llvm.coro.resume
100 // CHECK-NEXT: %{{.+}} = call i8 @llvm.coro.suspend
101 // CHECK-NEXT: switch i8 %{{.+}}, label %coro.ret [
102 // CHECK-NEXT: i8 0, label %[[CASE1_AWAIT_READY]]
103 // CHECK-NEXT: i8 1, label %[[CASE1_AWAIT_CLEANUP:.+]]
104 // CHECK-NEXT: ]
105 // CHECK: [[CASE1_AWAIT_CLEANUP]]:
106 // make sure that the awaiter eventually gets cleaned up.
107 // CHECK: call void @{{.+Awaiter.+}}
109 // CHECK: [[CASE2]]:
110 // CHECK: br i1 %{{.+}}, label %[[CASE2_AWAIT_READY:.+]], label %[[CASE2_AWAIT_SUSPEND:.+]]
111 // CHECK: [[CASE2_AWAIT_SUSPEND]]:
112 // CHECK-NEXT: %{{.+}} = call token @llvm.coro.save(i8* null)
113 // CHECK-NEXT: %[[HANDLE21:.+]] = bitcast %"struct.std::experimental::coroutines_v1::coroutine_handle"* %[[TMP2:.+]] to i8*
114 // CHECK-NEXT: call void @llvm.lifetime.start.p0i8(i64 8, i8* %[[HANDLE21]])
116 // CHECK: %[[HANDLE22:.+]] = bitcast %"struct.std::experimental::coroutines_v1::coroutine_handle"* %[[TMP2]] to i8*
117 // CHECK-NEXT: call void @llvm.lifetime.end.p0i8(i64 8, i8* %[[HANDLE22]])
118 // CHECK-NEXT: call void @llvm.coro.resume
119 // CHECK-NEXT: %{{.+}} = call i8 @llvm.coro.suspend
120 // CHECK-NEXT: switch i8 %{{.+}}, label %coro.ret [
121 // CHECK-NEXT: i8 0, label %[[CASE2_AWAIT_READY]]
122 // CHECK-NEXT: i8 1, label %[[CASE2_AWAIT_CLEANUP:.+]]
123 // CHECK-NEXT: ]
124 // CHECK: [[CASE2_AWAIT_CLEANUP]]:
125 // make sure that the awaiter eventually gets cleaned up.
126 // CHECK: call void @{{.+Awaiter.+}}