[clang] [coroutines] Introduce [[clang::coro_return_type]] and [[clang::coro_wrapper]] (PR #71945)

Utkarsh Saxena via cfe-commits cfe-commits at lists.llvm.org
Fri Nov 17 06:11:59 PST 2023


================
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 %s -std=c++20 -fsyntax-only -verify -Wall -Wextra
+#include "Inputs/std-coroutine.h"
+
+using std::suspend_always;
+using std::suspend_never;
+
+
+template <typename T> struct [[clang::coro_return_type]] Gen {
+  struct promise_type {
+    Gen<T> get_return_object() {
+      return {};
+    }
+    suspend_always initial_suspend();
+    suspend_always final_suspend() noexcept;
+    void unhandled_exception();
+    void return_value(const T &t);
+
+    template <typename U>
+    auto await_transform(const Gen<U> &) {
+      struct awaitable {
+        bool await_ready() noexcept { return false; }
+        void await_suspend(std::coroutine_handle<>) noexcept {}
+        U await_resume() noexcept { return {}; }
+      };
+      return awaitable{};
+    }
+  };
+};
+
+Gen<int> foo_coro(int b);
+Gen<int> foo_coro(int b) { co_return b; }
+
+[[clang::coro_wrapper]] Gen<int> marked_wrapper1(int b) { return foo_coro(b); }
+
+// expected-error at +1 {{neither a coroutine nor a coroutine wrapper}}
+Gen<int> non_marked_wrapper(int b) { return foo_coro(b); }
+
+namespace using_decl {
+template <typename T> using Co = Gen<T>;
+
+[[clang::coro_wrapper]] Co<int> marked_wrapper1(int b) { return foo_coro(b); }
+
+// expected-error at +1 {{neither a coroutine nor a coroutine wrapper}}
+Co<int> non_marked_wrapper(int b) { return foo_coro(b); }
+} // namespace using_decl
+
+namespace lambdas {
+void foo() {
+  auto coro_lambda = []() -> Gen<int> {
+    co_return 1;
+  };
+  // expected-error at +1 {{neither a coroutine nor a coroutine wrapper}}
+  auto wrapper_lambda = []() -> Gen<int> {
----------------
usx95 wrote:

Missed to add this test.  This would be ugly, although possible, if we silenced the C++23 extension warning 🥲
```cpp
#define CORO_WRAPPER \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Wc++23-extensions\"") \
  [[clang::coro_wrapper]] \
  _Pragma("clang diagnostic pop")

void foo() {
  auto allowed_wrapper = [] CORO_WRAPPER() -> Gen<int> {
    return some_coroutine(1);
  };
}
```

Added the test.

https://github.com/llvm/llvm-project/pull/71945


More information about the cfe-commits mailing list