1 // Test this without pch.
2 // RUN: %clang_cc1 -include %s -verify -std=c++1z -fcoroutines-ts %s
3 
4 // Test with pch.
5 // RUN: %clang_cc1 -std=c++1z -fcoroutines-ts  -emit-pch -o %t %s
6 // RUN: %clang_cc1 -include-pch %t -verify -std=c++1z -fcoroutines-ts %s
7 
8 #ifndef HEADER
9 #define HEADER
10 
11 namespace std::experimental {
12 template <typename... T> struct coroutine_traits;
13 
14 template <class Promise = void> struct coroutine_handle {
15   coroutine_handle() = default;
16   static coroutine_handle from_address(void *) noexcept;
17 };
18 template <> struct coroutine_handle<void> {
19   static coroutine_handle from_address(void *) noexcept;
20   coroutine_handle() = default;
21   template <class PromiseType>
22   coroutine_handle(coroutine_handle<PromiseType>) noexcept;
23 };
24 }
25 
26 struct suspend_always {
27   bool await_ready() noexcept;
28   void await_suspend(std::experimental::coroutine_handle<>) noexcept;
29   void await_resume() noexcept;
30 };
31 
32 template <typename... Args> struct std::experimental::coroutine_traits<void, Args...> {
33   struct promise_type {
34     void get_return_object() noexcept;
35     suspend_always initial_suspend() noexcept;
36     suspend_always final_suspend() noexcept;
37     void return_void() noexcept;
38     suspend_always yield_value(int) noexcept;
39     promise_type();
40     ~promise_type() noexcept;
41     void unhandled_exception() noexcept;
42   };
43 };
44 
45 template <typename... Args> struct std::experimental::coroutine_traits<int, Args...> {
46   struct promise_type {
47     int get_return_object() noexcept;
48     suspend_always initial_suspend() noexcept;
49     suspend_always final_suspend() noexcept;
50     void return_value(int) noexcept;
51     promise_type();
52     ~promise_type() noexcept;
53     void unhandled_exception() noexcept;
54   };
55 };
56 
57 template <typename T>
f(T x)58 void f(T x) {  // checks coawait_expr and coroutine_body_stmt
59   co_yield 42; // checks coyield_expr
60   co_await x;  // checks dependent_coawait
61   co_return;   // checks coreturn_stmt
62 }
63 
64 template <typename T>
f2(T x)65 int f2(T x) {  // checks coawait_expr and coroutine_body_stmt
66   co_return x;   // checks coreturn_stmt with expr
67 }
68 
69 struct S {};
operator co_await(S)70 S operator co_await(S) { return S(); }
71 
72 template <typename T>
f3(T x)73 int f3(T x) {
74   co_await x; // checks dependent_coawait with overloaded co_await operator
75 }
76 
77 #else
78 
79 // expected-no-diagnostics
g()80 void g() {
81   f(suspend_always{});
82   f2(42);
83 }
84 
85 #endif
86