104 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -ast-dump %s | FileCheck %s2 3#include "Inputs/std-coroutine.h"4 5using namespace std;6 7struct Task {8 struct promise_type {9 Task get_return_object() noexcept {10 return Task{coroutine_handle<promise_type>::from_promise(*this)};11 }12 13 void return_void() noexcept {}14 15 struct final_awaiter {16 bool await_ready() noexcept { return false; }17 coroutine_handle<> await_suspend(coroutine_handle<promise_type> h) noexcept {18 h.destroy();19 return {};20 }21 void await_resume() noexcept {}22 };23 24 void unhandled_exception() noexcept {}25 26 final_awaiter final_suspend() noexcept { return {}; }27 28 suspend_always initial_suspend() noexcept { return {}; }29 30 template <typename Awaitable>31 auto await_transform(Awaitable &&awaitable) {32 return awaitable.co_viaIfAsync();33 }34 };35 36 using handle_t = coroutine_handle<promise_type>;37 38 class Awaiter {39 public:40 explicit Awaiter(handle_t coro) noexcept;41 Awaiter(Awaiter &&other) noexcept;42 Awaiter(const Awaiter &) = delete;43 ~Awaiter();44 45 bool await_ready() noexcept { return false; }46 handle_t await_suspend(coroutine_handle<> continuation) noexcept;47 void await_resume();48 49 private:50 handle_t coro_;51 };52 53 Task(handle_t coro) noexcept : coro_(coro) {}54 55 handle_t coro_;56 57 Task(const Task &t) = delete;58 Task(Task &&t) noexcept;59 ~Task();60 Task &operator=(Task t) noexcept;61 62 Awaiter co_viaIfAsync();63};64 65static Task foo() {66 co_return;67}68 69Task 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;80 }81}82 83// CHECK-LABEL: FunctionDecl {{.*}} bar 'Task ()'84// CHECK: SwitchStmt85// CHECK: CaseStmt86// CHECK: ExprWithCleanups {{.*}} 'void'87// CHECK-NEXT: CoawaitExpr88// CHECK-NEXT: CXXBindTemporaryExpr {{.*}} 'Task' (CXXTemporary {{.*}})89// CHECK: MaterializeTemporaryExpr {{.*}} 'Awaiter'90// CHECK: ExprWithCleanups {{.*}} 'bool'91// CHECK-NEXT: CXXMemberCallExpr {{.*}} 'bool'92// CHECK-NEXT: MemberExpr {{.*}} .await_ready93// CHECK: ExprWithCleanups {{.*}} 'void *'94 95// CHECK: CaseStmt96// CHECK: ExprWithCleanups {{.*}} 'void'97// CHECK-NEXT: CoawaitExpr98// CHECK-NEXT: CXXBindTemporaryExpr {{.*}} 'Task' (CXXTemporary {{.*}})99// CHECK: MaterializeTemporaryExpr {{.*}} 'Awaiter'100// CHECK: ExprWithCleanups {{.*}} 'bool'101// CHECK-NEXT: CXXMemberCallExpr {{.*}} 'bool'102// CHECK-NEXT: MemberExpr {{.*}} .await_ready103// CHECK: ExprWithCleanups {{.*}} 'void *'104