Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / CodeGenCoroutines / Inputs / coroutine.h
blob4473bcc95c096f646f02d2ca19cfbd5a597fb7a4
1 // This is a mock file for <coroutine>.
2 #pragma once
4 namespace std {
6 template <typename R, typename...> struct coroutine_traits {
7 using promise_type = typename R::promise_type;
8 };
10 template <typename Promise = void> struct coroutine_handle;
12 template <> struct coroutine_handle<void> {
13 static coroutine_handle from_address(void *addr) noexcept {
14 coroutine_handle me;
15 me.ptr = addr;
16 return me;
18 void operator()() { resume(); }
19 void *address() const noexcept { return ptr; }
20 void resume() const { __builtin_coro_resume(ptr); }
21 void destroy() const { __builtin_coro_destroy(ptr); }
22 bool done() const { return __builtin_coro_done(ptr); }
23 coroutine_handle &operator=(decltype(nullptr)) {
24 ptr = nullptr;
25 return *this;
27 coroutine_handle(decltype(nullptr)) : ptr(nullptr) {}
28 coroutine_handle() : ptr(nullptr) {}
29 // void reset() { ptr = nullptr; } // add to P0057?
30 explicit operator bool() const { return ptr; }
32 protected:
33 void *ptr;
36 template <typename Promise> struct coroutine_handle : coroutine_handle<> {
37 using coroutine_handle<>::operator=;
39 static coroutine_handle from_address(void *addr) noexcept {
40 coroutine_handle me;
41 me.ptr = addr;
42 return me;
45 Promise &promise() const {
46 return *reinterpret_cast<Promise *>(
47 __builtin_coro_promise(ptr, alignof(Promise), false));
49 static coroutine_handle from_promise(Promise &promise) {
50 coroutine_handle p;
51 p.ptr = __builtin_coro_promise(&promise, alignof(Promise), true);
52 return p;
56 template <typename _PromiseT>
57 bool operator==(coroutine_handle<_PromiseT> const &_Left,
58 coroutine_handle<_PromiseT> const &_Right) noexcept {
59 return _Left.address() == _Right.address();
62 template <typename _PromiseT>
63 bool operator!=(coroutine_handle<_PromiseT> const &_Left,
64 coroutine_handle<_PromiseT> const &_Right) noexcept {
65 return !(_Left == _Right);
68 struct noop_coroutine_promise {};
70 template <>
71 struct coroutine_handle<noop_coroutine_promise> {
72 operator coroutine_handle<>() const noexcept {
73 return coroutine_handle<>::from_address(address());
76 constexpr explicit operator bool() const noexcept { return true; }
77 constexpr bool done() const noexcept { return false; }
79 constexpr void operator()() const noexcept {}
80 constexpr void resume() const noexcept {}
81 constexpr void destroy() const noexcept {}
83 noop_coroutine_promise &promise() const noexcept {
84 return *static_cast<noop_coroutine_promise *>(
85 __builtin_coro_promise(this->__handle_, alignof(noop_coroutine_promise), false));
88 constexpr void *address() const noexcept { return __handle_; }
90 private:
91 friend coroutine_handle<noop_coroutine_promise> noop_coroutine() noexcept;
93 coroutine_handle() noexcept {
94 this->__handle_ = __builtin_coro_noop();
97 void *__handle_ = nullptr;
100 using noop_coroutine_handle = coroutine_handle<noop_coroutine_promise>;
102 inline noop_coroutine_handle noop_coroutine() noexcept { return noop_coroutine_handle(); }
104 struct suspend_always {
105 bool await_ready() noexcept { return false; }
106 void await_suspend(coroutine_handle<>) noexcept {}
107 void await_resume() noexcept {}
109 struct suspend_never {
110 bool await_ready() noexcept { return true; }
111 void await_suspend(coroutine_handle<>) noexcept {}
112 void await_resume() noexcept {}
115 } // namespace std