Files
clang-p2996/clang/test/AST/Inputs/std-coroutine.h
dingfei 8d60e10ce4 [AST][Coroutine] Fix CoyieldExpr missing end loc
Coroutine co_yield/co_await/co_return are implemented by a serious of
synthesized CXXMemberExpr which have no lexical right-side parenthesis.

This fix uses the end loc of inner expr as the hypothetical RParenLoc of
CXXMemberExpr. For tools this might be an issue since the RParen token doesn't
exist (but has a valid location).

For future improvement, we might:
1. mark those inner (generated) exprs as implict (tools have chances to skip
   these nodes) (by @aaron.ballman)
2. borrow the idea from InitListExpr, there are two forms, one is for semantic,
   the other one is for syntactic, having these two split can make everything
   easier (by @hokein)

Fixes https://github.com/llvm/llvm-project/issues/64483

Reviewed By: aaron.ballman, hokein

Differential Revision: https://reviews.llvm.org/D157296
2023-08-10 08:02:32 +08:00

72 lines
2.0 KiB
C++

// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -Wignored-qualifiers -Wno-error=return-type -verify -fblocks -Wno-unreachable-code -Wno-unused-value
#ifndef STD_COROUTINE_H
#define STD_COROUTINE_H
namespace std {
template <typename R, typename...> struct coroutine_traits {
using promise_type = typename R::promise_type;
};
template <typename Promise = void> struct coroutine_handle;
template <> struct coroutine_handle<void> {
static coroutine_handle from_address(void *addr) noexcept {
coroutine_handle me;
me.ptr = addr;
return me;
}
void operator()() { resume(); }
void *address() const noexcept { return ptr; }
void resume() const { __builtin_coro_resume(ptr); }
void destroy() const { __builtin_coro_destroy(ptr); }
bool done() const { return __builtin_coro_done(ptr); }
coroutine_handle &operator=(decltype(nullptr)) {
ptr = nullptr;
return *this;
}
coroutine_handle(decltype(nullptr)) : ptr(nullptr) {}
coroutine_handle() : ptr(nullptr) {}
// void reset() { ptr = nullptr; } // add to P0057?
explicit operator bool() const { return ptr; }
protected:
void *ptr;
};
template <typename Promise> struct coroutine_handle : coroutine_handle<> {
using coroutine_handle<>::operator=;
static coroutine_handle from_address(void *addr) noexcept {
coroutine_handle me;
me.ptr = addr;
return me;
}
Promise &promise() const {
return *reinterpret_cast<Promise *>(
__builtin_coro_promise(ptr, alignof(Promise), false));
}
static coroutine_handle from_promise(Promise &promise) {
coroutine_handle p;
p.ptr = __builtin_coro_promise(&promise, alignof(Promise), true);
return p;
}
};
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
#endif // STD_COROUTINE_H