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