1 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 \ 2 // RUN: -O1 -emit-llvm %s -o - | FileCheck %s 3 4 #include "Inputs/coroutine.h" 5 6 // A simple awaiter type with an await_suspend method that can't be 7 // inlined. 8 struct Awaiter { 9 const int& x; 10 await_readyAwaiter11 bool await_ready() { return false; } 12 std::coroutine_handle<> await_suspend(const std::coroutine_handle<> h); await_resumeAwaiter13 void await_resume() {} 14 }; 15 16 struct MyTask { 17 // A lazy promise with an await_transform method that supports awaiting 18 // integer references using the Awaiter struct above. 19 struct promise_type { get_return_objectMyTask::promise_type20 MyTask get_return_object() { 21 return MyTask{ 22 std::coroutine_handle<promise_type>::from_promise(*this), 23 }; 24 } 25 initial_suspendMyTask::promise_type26 std::suspend_always initial_suspend() { return {}; } final_suspendMyTask::promise_type27 std::suspend_always final_suspend() noexcept { return {}; } 28 void unhandled_exception(); 29 await_transformMyTask::promise_type30 auto await_transform(const int& x) { return Awaiter{x}; } 31 }; 32 33 std::coroutine_handle<> h; 34 }; 35 36 // A global array of integers. 37 int g_array[32]; 38 39 // A coroutine that awaits each integer in the global array. FooBar()40MyTask FooBar() { 41 for (const int& x : g_array) { 42 co_await x; 43 } 44 } 45 46 // CHECK: %[[RET:.+]] = {{.*}}call{{.*}}@_ZN7Awaiter13await_suspendESt16coroutine_handleIvE 47 // CHECK: %[[RESUME_ADDR:.+]] = load ptr, ptr %[[RET]], 48 // CHECK: musttail call fastcc void %[[RESUME_ADDR]]({{.*}}%[[RET]] 49 // CHECK: ret 50 51