<table border="1" cellspacing="0" cellpadding="8">
    <tr>
        <th>Issue</th>
        <td>
            <a href=https://github.com/llvm/llvm-project/issues/147150>147150</a>
        </td>
    </tr>

    <tr>
        <th>Summary</th>
        <td>
            `CoyieldExpr` doesn't contain the original AST `-ast-print` returns invalid source.
        </td>
    </tr>

    <tr>
      <th>Labels</th>
      <td>
            new issue
      </td>
    </tr>

    <tr>
      <th>Assignees</th>
      <td>
      </td>
    </tr>

    <tr>
      <th>Reporter</th>
      <td>
          hanickadot
      </td>
    </tr>
</table>

<pre>
    Following code when parsed and emitted with `-ast-print` returns wrong result:

```c++
simple_coro<int> coro_test() {
  co_yield 2001;
  co_return 2010;
  co_await my_awaitable{2061};
}
```

Result printed by clang is: (with fixed formatting
```c++
simple_coro<int> coro_test() {
  co_yield __promise.yield_value(2001); // <-- ERROR HERE
  co_return 2010;
  co_await my_awaitable{2061};
}
```

Expected result:
```c++
simple_coro<int> coro_test() {
  co_yield 2001;
  co_return 2010;
  co_await my_awaitable{2061};
}
```

Notice the `co_yield __promise.yield_value(1997);` it contains call to `__promise.yield_value` function, this helper AST is generated in `SemaCoroutine.cpp` in `Sema::ActOnCoyieldExpr`:
```c++
  // Build yield_value call.
  ExprResult Awaitable = buildPromiseCall(
      *this, getCurFunction()->CoroutinePromise, Loc, "yield_value", E);
  if (Awaitable.isInvalid())
    return ExprError();

  // Build 'operator co_await' call.
  Awaitable = buildOperatorCoawaitCall(*this, S, Loc, Awaitable.get());
  if (Awaitable.isInvalid())
    return ExprError();
```

There is Operand slot inside `CoroutineSuspendExpr` which should contain original expression, but the function `BuildCoyieldExpr` is already getting modified AST.

Full source code to repeat the problem:
```c++
#include <coroutine>

struct my_awaitable {
  int value;
  bool await_ready() const {
    return true;
  }
  void await_suspend(std::coroutine_handle<void>) {
    
  }
  int await_resume() const {
    return value;
  }
};

template <typename T> struct simple_coro {
        struct promise_type {
                T value{0};

                constexpr auto initial_suspend() const noexcept {
                        return std::suspend_never{};
                }
                constexpr auto final_suspend() const noexcept {
                        return std::suspend_never{};
                }
                constexpr void return_value(int v) noexcept {
      value = v;
                }
                constexpr auto yield_value(T v) noexcept {
      value = v;
                        return std::suspend_always{};
                }
                std::coroutine_handle<promise_type> get_return_object() {
                        return std::coroutine_handle<promise_type>::from_promise(*this);
                }
                constexpr void unhandled_exception() const noexcept {
                }
        };

private:
        std::coroutine_handle<promise_type> handle;

public:
        constexpr simple_coro(std::coroutine_handle<promise_type> h) noexcept: handle{h} { }
        constexpr ~simple_coro() noexcept {
                handle.destroy();
        }
        constexpr int get() {
                return handle.promise().value;
        }
};

simple_coro<int> coro_test() {
 co_yield 2001;
  co_return 2010;
  co_await my_awaitable{2061};
}
```

Maybe this is fine, but AFAIK clang is trying to represent the AST so the original source code is recoverable and this breaks it.
</pre>
<img width="1" height="1" alt="" src="http://email.email.llvm.org/o/eJzUV99v4joT_WvMy6gocYCUBx4oBX2r78d-avuOHGcgvmvsyHagvNy__WriEMLdtrt7tXelW0UqEPvMnOOTmYnwXu0N4oJNH9j0cSSaUFm3qIRR8osobRgVtjwvNlZre1JmD9KWCKcKDdTCeSxBmBLwoELAEk4qVMBmyZ3w4a52ygQ2S8BhaJzxcHLW7MGhb3Rg2ZIl7TVL4iUZf6ArWXp1qDVupXWWZSsCydZA37YBfWD8nvE5sJyWAki7PSvUJfAkSVnW_xiDAk_SZPCrOAkV4HCOH0ShkeUPPJmlLH-My-jDIKuY5FObM7SMsITiDFILswflWbYExu9b4jv1iiXsrDuIEJTZ_0x2223t7EF5HLfft0ehG2T8vmXN5yx7AMY3jG-AZau7O1g_PX1-gn-tn9Z_iyDr1xolSXFzmv-Eo_yfDUoihArJqN_UN53P86gvOVkFkNYEoYwHKbSGYAnl7c2zBHaNkUFZw_gKQqU8VKhrdLB8fgHlYY8GnSAZlSGcZzyIlXW2CcrgWNZ1G7O_RSpny6UMn83KtpHWr7UjZu_JDxdTPDRKlzDIrk1_3C4hkM7gy4uUwLJHKGjT_yOzldCajos20B_jSyJExPYYVo3b9FTpTO9Ytu6ZdBC09j9W0j_G-Y3MnH5cdzpTCLWjp6pPZ6z8J3MUWpURnq6YSecN4rB2zrrufjz_rwRgPLc1SW5dbyHG84EYbyjwuduxsu36ixJXAZ4HzK4p7zFck_2ptG4N_VKhQ3JTm6cpwWsbQBmvytbi_TE8N75Gc_EMnColK_CVbXR5cTVYp_bKCA34Wjv0vvNu0YT2ibn4mXBbRW99SFkI7VCUZ3IF1UA42FLtFJbk-XHMeNNoDd42TmJsJ8GCwxpFDFI7W2g8vGtqxjNlpG6IXraSF3osW0d4H1wjbytDX2KUCRA9151IYa2Gdt22zbsrSdIaH_pd_XkEd90ZqwvA0aqyQ_BRYcbvfSjj09qnt62EKTWybEUbKNlB5QO4gaQsLzn55oAfJ3XDp6t5fQlMlgEPtRahFSucazTigPBCdbgTalCjO3CWzLt7XV3b0sbrTZbMX7qw-UMyDBZvtomSg0A0wYIyKiihB_Jc2RiLrxLrcAPOknnHrdex27s1eERHa69B2x2R9lvRd-TnXx-7tUVE6ptJ6z6K_6fIsaTGukxl5_id1G5b1ctfwH6frNAncfYfs_3I5UPnkNn2GLpGvrXFbyhvm_-76XwbOa7bOXu4dOFhdZ5_50k1JuKX26he38k-9EqPN3gEaqeOIuBlwP0hkS43LlBNoZXska4pD8eqj4vNVxGGFqHhtVuZP1QsfyR20LO6xvv9NuAbNouCRLBxiT44e77txfM3cOmB6PvkDVLngw5weLDz8aDgXWEHJ_AjQ-cvmTn_K84FxgFQeSpIeGmqy83y07_7lwkI7kw9M_ZDhx5NbIk0L3rbfuw79LCBKg8OpT2ia7sdTQFttMKh-OJBhfGoXGTlPJuLES7SfJrmfDbJ01G1EPeY79KyKMQk46mUOz6bitmsuJ8USZ5NkpFa8IRPkzyZppNJmqbjsriXZTGVUpazSZpxNknwIJQea308jK3bj5T3DS7SSZ5Ok5EWBWrfvl9ybvAE7V2a-aaPI7egTXdFs_dskmjlg7_CBBU0LtoR5mbKKC16w3jeD-O3wpBY776DqjhvdeqNR43TiyqEml7k4qi4V6FqirG0B8Y3lEv37652NtatTcvAM77pKB4X_I8AAAD__1KquMk">