Author: Andres-Salamanca Date: 2026-07-26T14:21:13-05:00 New Revision: 39eb2a11a21927832091b54f25dc4a8bd1c61604
URL: https://github.com/llvm/llvm-project/commit/39eb2a11a21927832091b54f25dc4a8bd1c61604 DIFF: https://github.com/llvm/llvm-project/commit/39eb2a11a21927832091b54f25dc4a8bd1c61604.diff LOG: [CIR][NFC] Reorganize coroutine tests (#211152) Move the coroutine tests into a dedicated CodeGenCoroutines directory. This is a test only reorganization in preparation for upcoming coroutine-related changes. Added: clang/test/CIR/CodeGenCoroutines/Inputs/coroutine.h clang/test/CIR/CodeGenCoroutines/coro-exceptions.cpp clang/test/CIR/CodeGenCoroutines/coro-task.cpp Modified: Removed: clang/test/CIR/CodeGen/coro-exceptions.cpp clang/test/CIR/CodeGen/coro-task.cpp ################################################################################ diff --git a/clang/test/CIR/CodeGenCoroutines/Inputs/coroutine.h b/clang/test/CIR/CodeGenCoroutines/Inputs/coroutine.h new file mode 100644 index 0000000000000..15a0a549d6226 --- /dev/null +++ b/clang/test/CIR/CodeGenCoroutines/Inputs/coroutine.h @@ -0,0 +1,152 @@ + +namespace std { + +template<typename T> struct remove_reference { typedef T type; }; +template<typename T> struct remove_reference<T &> { typedef T type; }; +template<typename T> struct remove_reference<T &&> { typedef T type; }; + +template<typename T> +typename remove_reference<T>::type &&move(T &&t) noexcept; + +template <class Ret, typename... T> +struct coroutine_traits { using promise_type = typename Ret::promise_type; }; + +template <class Promise = void> +struct coroutine_handle { + static coroutine_handle from_address(void *) noexcept; +}; +template <> +struct coroutine_handle<void> { + template <class PromiseType> + coroutine_handle(coroutine_handle<PromiseType>) noexcept; + static coroutine_handle from_address(void *); +}; + +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 {} +}; + +// Awaitable whose await_resume CAN throw. +struct suspend_maybe_throw { + bool await_ready() noexcept; + void await_suspend(coroutine_handle<>) noexcept; + void await_resume(); // not noexcept +}; + +// Awaitable whose await_resume is noexcept. +struct suspend_nothrow { + bool await_ready() noexcept; + void await_suspend(coroutine_handle<>) noexcept; + void await_resume() noexcept; +}; + +struct string { + int size() const; + string(); + string(char const *s); +}; + +template<typename T> +struct optional { + optional(); + optional(const T&); + T &operator*() &; + T &&operator*() &&; + T &value() &; + T &&value() &&; +}; +} // namespace std + +namespace folly { +namespace coro { + +using std::suspend_always; +using std::suspend_never; +using std::coroutine_handle; + +using SemiFuture = int; + +template<class T> +struct Task { + struct promise_type { + Task<T> get_return_object() noexcept; + suspend_always initial_suspend() noexcept; + suspend_always final_suspend() noexcept; + void return_value(T); + void unhandled_exception(); + auto yield_value(Task<T>) noexcept { return final_suspend(); } + }; + bool await_ready() noexcept { return false; } + void await_suspend(coroutine_handle<>) noexcept {} + T await_resume(); +}; + +template<> +struct Task<void> { + struct promise_type { + Task<void> get_return_object() noexcept; + suspend_always initial_suspend() noexcept; + suspend_always final_suspend() noexcept; + void return_void() noexcept; + void unhandled_exception() noexcept; + auto yield_value(Task<void>) noexcept { return final_suspend(); } + }; + bool await_ready() noexcept { return false; } + void await_suspend(coroutine_handle<>) noexcept {} + void await_resume() noexcept {} + SemiFuture semi(); +}; + +// FIXME: add CIRGen support here. +// struct blocking_wait_fn { +// template <typename T> +// T operator()(Task<T>&& awaitable) const { +// return T(); +// } +// }; + +// inline constexpr blocking_wait_fn blocking_wait{}; +// static constexpr blocking_wait_fn const& blockingWait = blocking_wait; +template <typename T> +T blockingWait(Task<T>&& awaitable) { + return T(); +} + +struct co_invoke_fn { + template <typename F, typename... A> + Task<void> operator()(F&& f, A&&... a) const { + return Task<void>(); + } +}; + +co_invoke_fn co_invoke; + +}} // namespace folly::coro + +struct TaskWithEH { + struct promise_type { + TaskWithEH get_return_object(); + std::suspend_nothrow initial_suspend() noexcept; + std::suspend_nothrow final_suspend() noexcept; + void return_void(); + void unhandled_exception(); + }; +}; + +struct TaskThrowingInit { + struct promise_type { + TaskThrowingInit get_return_object(); + std::suspend_maybe_throw initial_suspend() noexcept; // resume CAN throw + std::suspend_nothrow final_suspend() noexcept; + void return_void(); + void unhandled_exception(); + }; +}; diff --git a/clang/test/CIR/CodeGen/coro-exceptions.cpp b/clang/test/CIR/CodeGenCoroutines/coro-exceptions.cpp similarity index 69% rename from clang/test/CIR/CodeGen/coro-exceptions.cpp rename to clang/test/CIR/CodeGenCoroutines/coro-exceptions.cpp index 7ccca4d2b7006..5edae916f8f9f 100644 --- a/clang/test/CIR/CodeGen/coro-exceptions.cpp +++ b/clang/test/CIR/CodeGenCoroutines/coro-exceptions.cpp @@ -4,42 +4,7 @@ // FIXME: we currently don't have flatten-cfg for coroutines or lower to LLVM-IR // implemented correctly, so this tests only the CIR output. -namespace std { -template <class Ret, typename... T> -struct coroutine_traits { using promise_type = typename Ret::promise_type; }; - -template <class Promise = void> struct coroutine_handle { - static coroutine_handle from_address(void *) noexcept; -}; -template <> struct coroutine_handle<void> { - template <class P> coroutine_handle(coroutine_handle<P>) noexcept; - static coroutine_handle from_address(void *); -}; - -// Awaitable whose await_resume CAN throw. -struct suspend_maybe_throw { - bool await_ready() noexcept; - void await_suspend(coroutine_handle<>) noexcept; - void await_resume(); // not noexcept -}; - -// Awaitable whose await_resume is noexcept. -struct suspend_nothrow { - bool await_ready() noexcept; - void await_suspend(coroutine_handle<>) noexcept; - void await_resume() noexcept; -}; -} // namespace std - -struct TaskWithEH { - struct promise_type { - TaskWithEH get_return_object(); - std::suspend_nothrow initial_suspend() noexcept; - std::suspend_nothrow final_suspend() noexcept; - void return_void(); - void unhandled_exception(); - }; -}; +#include "Inputs/coroutine.h" TaskWithEH simple_eh_body() { co_return; @@ -74,16 +39,6 @@ TaskWithEH simple_eh_body() { // Make sure that 'final' is outside of the above try/catch/etc. // CIR: cir.call @_ZN10TaskWithEH12promise_type13final_suspendEv -struct TaskThrowingInit { - struct promise_type { - TaskThrowingInit get_return_object(); - std::suspend_maybe_throw initial_suspend() noexcept; // resume CAN throw - std::suspend_nothrow final_suspend() noexcept; - void return_void(); - void unhandled_exception(); - }; -}; - TaskThrowingInit throwing_init_suspend() { co_return; } diff --git a/clang/test/CIR/CodeGen/coro-task.cpp b/clang/test/CIR/CodeGenCoroutines/coro-task.cpp similarity index 91% rename from clang/test/CIR/CodeGen/coro-task.cpp rename to clang/test/CIR/CodeGenCoroutines/coro-task.cpp index 8d093180ae307..afaf66b8a8d06 100644 --- a/clang/test/CIR/CodeGen/coro-task.cpp +++ b/clang/test/CIR/CodeGenCoroutines/coro-task.cpp @@ -3,123 +3,7 @@ // RUN: %clang_cc1 -std=c++20 -triple x86_64-unknown-linux-gnu -emit-llvm -disable-llvm-passes %s -o %t-cir.ll // RUN: FileCheck --input-file=%t-cir.ll %s --check-prefix=OGCG -namespace std { - -template<typename T> struct remove_reference { typedef T type; }; -template<typename T> struct remove_reference<T &> { typedef T type; }; -template<typename T> struct remove_reference<T &&> { typedef T type; }; - -template<typename T> -typename remove_reference<T>::type &&move(T &&t) noexcept; - -template <class Ret, typename... T> -struct coroutine_traits { using promise_type = typename Ret::promise_type; }; - -template <class Promise = void> -struct coroutine_handle { - static coroutine_handle from_address(void *) noexcept; -}; -template <> -struct coroutine_handle<void> { - template <class PromiseType> - coroutine_handle(coroutine_handle<PromiseType>) noexcept; - static coroutine_handle from_address(void *); -}; - -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 {} -}; - -struct string { - int size() const; - string(); - string(char const *s); -}; - -template<typename T> -struct optional { - optional(); - optional(const T&); - T &operator*() &; - T &&operator*() &&; - T &value() &; - T &&value() &&; -}; -} // namespace std - -namespace folly { -namespace coro { - -using std::suspend_always; -using std::suspend_never; -using std::coroutine_handle; - -using SemiFuture = int; - -template<class T> -struct Task { - struct promise_type { - Task<T> get_return_object() noexcept; - suspend_always initial_suspend() noexcept; - suspend_always final_suspend() noexcept; - void return_value(T); - void unhandled_exception(); - auto yield_value(Task<T>) noexcept { return final_suspend(); } - }; - bool await_ready() noexcept { return false; } - void await_suspend(coroutine_handle<>) noexcept {} - T await_resume(); -}; - -template<> -struct Task<void> { - struct promise_type { - Task<void> get_return_object() noexcept; - suspend_always initial_suspend() noexcept; - suspend_always final_suspend() noexcept; - void return_void() noexcept; - void unhandled_exception() noexcept; - auto yield_value(Task<void>) noexcept { return final_suspend(); } - }; - bool await_ready() noexcept { return false; } - void await_suspend(coroutine_handle<>) noexcept {} - void await_resume() noexcept {} - SemiFuture semi(); -}; - -// FIXME: add CIRGen support here. -// struct blocking_wait_fn { -// template <typename T> -// T operator()(Task<T>&& awaitable) const { -// return T(); -// } -// }; - -// inline constexpr blocking_wait_fn blocking_wait{}; -// static constexpr blocking_wait_fn const& blockingWait = blocking_wait; -template <typename T> -T blockingWait(Task<T>&& awaitable) { - return T(); -} - -struct co_invoke_fn { - template <typename F, typename... A> - Task<void> operator()(F&& f, A&&... a) const { - return Task<void>(); - } -}; - -co_invoke_fn co_invoke; - -}} // namespace folly::coro +#include "Inputs/coroutine.h" // CIR-DAG: ![[VoidTask:.*]] = !cir.struct<"folly::coro::Task<void>" padded {!u8i}> // CIR-DAG: ![[IntTask:.*]] = !cir.struct<"folly::coro::Task<int>" padded {!u8i}> _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
