[clang] 39eb2a1 - [CIR][NFC] Reorganize coroutine tests (#211152)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Jul 26 12:21:18 PDT 2026
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}>
More information about the cfe-commits
mailing list