[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / CodeGenCoroutines / coro-halo.cpp
blob6244f130b7be23878e6ec64b7b7b53c2288c4bb2
1 // This tests that the coroutine heap allocation elision optimization could happen succesfully.
2 // RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -std=c++20 -O2 -emit-llvm %s -o - | FileCheck %s
4 #include "Inputs/coroutine.h"
5 #include "Inputs/numeric.h"
7 template <typename T> struct generator {
8 struct promise_type {
9 T current_value;
10 std::suspend_always yield_value(T value) {
11 this->current_value = value;
12 return {};
14 std::suspend_always initial_suspend() { return {}; }
15 std::suspend_always final_suspend() noexcept { return {}; }
16 generator get_return_object() { return generator{this}; };
17 void unhandled_exception() {}
18 void return_void() {}
21 struct iterator {
22 std::coroutine_handle<promise_type> _Coro;
23 bool _Done;
25 iterator(std::coroutine_handle<promise_type> Coro, bool Done)
26 : _Coro(Coro), _Done(Done) {}
28 iterator &operator++() {
29 _Coro.resume();
30 _Done = _Coro.done();
31 return *this;
34 bool operator==(iterator const &_Right) const {
35 return _Done == _Right._Done;
38 bool operator!=(iterator const &_Right) const { return !(*this == _Right); }
39 T const &operator*() const { return _Coro.promise().current_value; }
40 T const *operator->() const { return &(operator*()); }
43 iterator begin() {
44 p.resume();
45 return {p, p.done()};
48 iterator end() { return {p, true}; }
50 generator(generator const &) = delete;
51 generator(generator &&rhs) : p(rhs.p) { rhs.p = nullptr; }
53 ~generator() {
54 if (p)
55 p.destroy();
58 private:
59 explicit generator(promise_type *p)
60 : p(std::coroutine_handle<promise_type>::from_promise(*p)) {}
62 std::coroutine_handle<promise_type> p;
65 template <typename T>
66 generator<T> seq() {
67 for (T i = {};; ++i)
68 co_yield i;
71 template <typename T>
72 generator<T> take_until(generator<T> &g, T limit) {
73 for (auto &&v : g)
74 if (v < limit)
75 co_yield v;
76 else
77 break;
80 template <typename T>
81 generator<T> multiply(generator<T> &g, T factor) {
82 for (auto &&v : g)
83 co_yield v *factor;
86 template <typename T>
87 generator<T> add(generator<T> &g, T adder) {
88 for (auto &&v : g)
89 co_yield v + adder;
92 int main() {
93 auto s = seq<int>();
94 auto t = take_until(s, 10);
95 auto m = multiply(t, 2);
96 auto a = add(m, 110);
97 return std::accumulate(a.begin(), a.end(), 0);
100 // CHECK-LABEL: define{{.*}} i32 @main(
101 // CHECK: ret i32 1190
102 // CHECK-NOT: call{{.*}}_Znwm