File: co_await-ast.cpp

package info (click to toggle)
llvm-toolchain-19 1%3A19.1.7-3
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 1,998,520 kB
  • sloc: cpp: 6,951,680; ansic: 1,486,157; asm: 913,598; python: 232,024; f90: 80,126; objc: 75,281; lisp: 37,276; pascal: 16,990; sh: 10,009; ml: 5,058; perl: 4,724; awk: 3,523; makefile: 3,167; javascript: 2,504; xml: 892; fortran: 664; cs: 573
file content (98 lines) | stat: -rw-r--r-- 6,831 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
// RUN: %clang_cc1 -std=c++20 -ast-dump -ast-dump-filter=foo %s | FileCheck %s --strict-whitespace
// RUN: %clang_cc1 -std=c++20 -triple i386-windows-pc -ast-dump -ast-dump-filter=foo %s | FileCheck %s --strict-whitespace

namespace std {
template <typename, typename...> struct coroutine_traits;
template <typename> struct coroutine_handle {
  template <typename U>
  coroutine_handle(coroutine_handle<U> &&) noexcept;
  static coroutine_handle from_address(void *__addr) noexcept;
};
} // namespace std

struct executor {};
struct awaitable {};
struct awaitable_frame {
  awaitable get_return_object();
  void return_void();
  void unhandled_exception();
  struct result_t {
    ~result_t();
    bool await_ready() const noexcept;
    void await_suspend(std::coroutine_handle<void>) noexcept;
    void await_resume() const noexcept;
  };
  result_t initial_suspend() noexcept;
  result_t final_suspend() noexcept;
  result_t await_transform(executor) noexcept;
};

namespace std {
template <>
struct coroutine_traits<awaitable> {
  typedef awaitable_frame promise_type;
};
} // namespace std

awaitable foo() {
  co_await executor();
}

// Check that CoawaitExpr contains the correct subexpressions, including
// the operand expression as written in the source.

// CHECK-LABEL: Dumping foo:
// CHECK: FunctionDecl {{.*}} foo 'awaitable ()'
// CHECK: `-CoroutineBodyStmt {{.*}}
// CHECK:   |-CompoundStmt {{.*}}
// CHECK:   | `-ExprWithCleanups {{.*}} 'void'
// CHECK:   |   `-CoawaitExpr {{.*}} 'void'
// CHECK:   |     |-CXXTemporaryObjectExpr {{.*}} 'executor' 'void (){{.*}} noexcept' zeroing
// CHECK:   |     |-MaterializeTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
// CHECK:   |     | `-CXXBindTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' (CXXTemporary {{.*}})
// CHECK:   |     |   `-CXXMemberCallExpr {{.*}} 'result_t':'awaitable_frame::result_t'
// CHECK:   |     |     |-MemberExpr {{.*}} '<bound member function type>' .await_transform {{.*}}
// CHECK:   |     |     | `-DeclRefExpr {{.*}} 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame' lvalue Var {{.*}} '__promise' 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame'
// CHECK:   |     |     `-CXXTemporaryObjectExpr {{.*}} 'executor' 'void (){{.*}} noexcept' zeroing
// CHECK:   |     |-ExprWithCleanups {{.*}} 'bool'
// CHECK:   |     | `-CXXMemberCallExpr {{.*}} 'bool'
// CHECK:   |     |   `-MemberExpr {{.*}} '<bound member function type>' .await_ready {{.*}}
// CHECK:   |     |     `-ImplicitCastExpr {{.*}} 'const awaitable_frame::result_t' lvalue <NoOp>
// CHECK:   |     |       `-OpaqueValueExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
// CHECK:   |     |         `-MaterializeTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
// CHECK:   |     |           `-CXXBindTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' (CXXTemporary {{.*}})
// CHECK:   |     |             `-CXXMemberCallExpr {{.*}} 'result_t':'awaitable_frame::result_t'
// CHECK:   |     |               |-MemberExpr {{.*}} '<bound member function type>' .await_transform {{.*}}
// CHECK:   |     |               | `-DeclRefExpr {{.*}} 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame' lvalue Var {{.*}} '__promise' 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame'
// CHECK:   |     |               `-CXXTemporaryObjectExpr {{.*}} 'executor' 'void (){{.*}} noexcept' zeroing
// CHECK:   |     |-ExprWithCleanups {{.*}} 'void'
// CHECK:   |     | `-CXXMemberCallExpr {{.*}} 'void'
// CHECK:   |     |   |-MemberExpr {{.*}} '<bound member function type>' .await_suspend {{.*}}
// CHECK:   |     |   | `-OpaqueValueExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
// CHECK:   |     |   |   `-MaterializeTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
// CHECK:   |     |   |     `-CXXBindTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' (CXXTemporary {{.*}})
// CHECK:   |     |   |       `-CXXMemberCallExpr {{.*}} 'result_t':'awaitable_frame::result_t'
// CHECK:   |     |   |         |-MemberExpr {{.*}} '<bound member function type>' .await_transform {{.*}}
// CHECK:   |     |   |         | `-DeclRefExpr {{.*}} 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame' lvalue Var {{.*}} '__promise' 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame'
// CHECK:   |     |   |         `-CXXTemporaryObjectExpr {{.*}} 'executor' 'void (){{.*}} noexcept' zeroing
// CHECK:   |     |   `-ImplicitCastExpr {{.*}} 'std::coroutine_handle<void>' <ConstructorConversion>
// CHECK:   |     |     `-CXXConstructExpr {{.*}} 'std::coroutine_handle<void>' 'void (coroutine_handle<awaitable_frame> &&){{.*}} noexcept'
// CHECK:   |     |       `-MaterializeTemporaryExpr {{.*}} 'coroutine_handle<awaitable_frame>':'std::coroutine_handle<awaitable_frame>' xvalue
// CHECK:   |     |         `-CallExpr {{.*}} 'coroutine_handle<awaitable_frame>':'std::coroutine_handle<awaitable_frame>'
// CHECK:   |     |           |-ImplicitCastExpr {{.*}} 'coroutine_handle<awaitable_frame> (*)(void *) noexcept' <FunctionToPointerDecay>
// CHECK:   |     |           | `-DeclRefExpr {{.*}} 'coroutine_handle<awaitable_frame> (void *) noexcept' lvalue CXXMethod {{.*}} 'from_address' 'coroutine_handle<awaitable_frame> (void *) noexcept'
// CHECK:   |     |           `-CallExpr {{.*}} 'void *'
// CHECK:   |     |             `-ImplicitCastExpr {{.*}} 'void *(*)() noexcept' <FunctionToPointerDecay>
// CHECK:   |     |               `-DeclRefExpr {{.*}} 'void *() noexcept' lvalue Function {{.*}} '__builtin_coro_frame' 'void *() noexcept'
// CHECK:   |     `-CXXMemberCallExpr {{.*}} 'void'
// CHECK:   |       `-MemberExpr {{.*}} '<bound member function type>' .await_resume {{.*}}
// CHECK:   |         `-ImplicitCastExpr {{.*}} 'const awaitable_frame::result_t' lvalue <NoOp>
// CHECK:   |           `-OpaqueValueExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
// CHECK:   |             `-MaterializeTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
// CHECK:   |               `-CXXBindTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' (CXXTemporary {{.*}})
// CHECK:   |                 `-CXXMemberCallExpr {{.*}} 'result_t':'awaitable_frame::result_t'
// CHECK:   |                   |-MemberExpr {{.*}} '<bound member function type>' .await_transform {{.*}}
// CHECK:   |                   | `-DeclRefExpr {{.*}} 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame' lvalue Var {{.*}} '__promise' 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame'
// CHECK:   |                   `-CXXTemporaryObjectExpr {{.*}} <col:12, col:21> 'executor' 'void (){{.*}} noexcept' zeroing

// Rest of the generated coroutine statements omitted.