Index: clang/lib/Sema/SemaCoroutine.cpp =================================================================== --- clang/lib/Sema/SemaCoroutine.cpp +++ clang/lib/Sema/SemaCoroutine.cpp @@ -318,7 +318,8 @@ return ExprError(); } - return S.BuildCallExpr(nullptr, Result.get(), Loc, Args, Loc, nullptr); + auto EndLoc = Args.empty() ? Loc : Args.back()->getBeginLoc(); + return S.BuildCallExpr(nullptr, Result.get(), Loc, Args, EndLoc, nullptr); } // See if return type is coroutine-handle and if so, invoke builtin coro-resume Index: clang/test/AST/coroutine-co_yield-source-range.cpp =================================================================== --- /dev/null +++ clang/test/AST/coroutine-co_yield-source-range.cpp @@ -0,0 +1,77 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 \ +// RUN: -fsyntax-only -ast-dump | FileCheck %s + +namespace std { +template +struct coroutine_traits { using promise_type = typename Ret::promise_type; }; + +template +struct coroutine_handle { + static coroutine_handle from_address(void *) noexcept; + static coroutine_handle from_promise(Promise &promise); + constexpr void* address() const noexcept; +}; +template <> +struct coroutine_handle { + template + coroutine_handle(coroutine_handle) noexcept; + static coroutine_handle from_address(void *); + constexpr void* address() const noexcept; +}; + +struct suspend_always { + bool await_ready() noexcept { return false; } + void await_suspend(coroutine_handle<>) noexcept {} + void await_resume() noexcept {} +}; + +struct suspend_never { + bool await_ready() noexcept { return true; } + void await_suspend(coroutine_handle<>) noexcept {} + void await_resume() noexcept {} +}; +} // namespace std + +struct Chat { + struct promise_type { + std::suspend_always initial_suspend() { return {}; } + Chat get_return_object() { + return std::coroutine_handle::from_promise(*this); + } + std::suspend_always yield_value(int m) { + return {}; + } + std::suspend_always final_suspend() noexcept { return {}; } + std::suspend_always return_value(int) noexcept { return {}; } + void unhandled_exception() noexcept {} + + auto await_transform(int s) noexcept { + struct awaiter { + promise_type *promise; + bool await_ready() const { + return true; + } + int await_resume() const { + return promise->message; + } + void await_suspend(std::coroutine_handle<>) { + } + }; + return awaiter{this}; + } + int message; + }; + + Chat(std::coroutine_handle promise); + + std::coroutine_handle handle; +}; + +Chat f(int s) { + // CHECK: CoyieldExpr {{.*}} + co_yield s; + // CHECK: CoreturnStmt {{.*}} + co_return s; + // CHECK: CoawaitExpr {{.*}} + co_await s; +}