coro-lambda.cpp 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. // Verify that we synthesized the coroutine for a lambda inside of a function template.
  2. // RUN: %clang_cc1 -std=c++1z -fcoroutines-ts -triple=x86_64-unknown-linux-gnu -emit-llvm -o - %s -fexceptions -fcxx-exceptions -disable-llvm-passes | FileCheck %s
  3. namespace std::experimental {
  4. template <typename R, typename... T> struct coroutine_traits {
  5. using promise_type = typename R::promise_type;
  6. };
  7. template <class Promise = void> struct coroutine_handle;
  8. template <> struct coroutine_handle<void> {
  9. static coroutine_handle from_address(void *) noexcept;
  10. coroutine_handle() = default;
  11. template <class PromiseType>
  12. coroutine_handle(coroutine_handle<PromiseType>) noexcept;
  13. };
  14. template <class Promise> struct coroutine_handle : coroutine_handle<void> {
  15. coroutine_handle() = default;
  16. static coroutine_handle from_address(void *) noexcept;
  17. };
  18. }
  19. struct suspend_always {
  20. bool await_ready() noexcept;
  21. void await_suspend(std::experimental::coroutine_handle<>) noexcept;
  22. void await_resume() noexcept;
  23. };
  24. struct Task {
  25. struct promise_type {
  26. Task get_return_object();
  27. void return_void() {}
  28. suspend_always initial_suspend() noexcept;
  29. suspend_always final_suspend() noexcept;
  30. void unhandled_exception() noexcept;
  31. };
  32. };
  33. template <typename _AwrT> auto SyncAwait(_AwrT &&A) {
  34. if (!A.await_ready()) {
  35. auto AwaitAsync = [&]() -> Task {
  36. try { (void)(co_await A); } catch (...) {}
  37. };
  38. Task t = AwaitAsync();
  39. }
  40. return A.await_resume();
  41. }
  42. void f() {
  43. suspend_always test;
  44. SyncAwait(test);
  45. }
  46. // Verify that we synthesized the coroutine for a lambda inside SyncAwait
  47. // CHECK-LABEL: define linkonce_odr void @_ZZ9SyncAwaitIR14suspend_alwaysEDaOT_ENKUlvE_clEv(
  48. // CHECK: alloca %"struct.Task::promise_type"
  49. // CHECK: call token @llvm.coro.id(
  50. // CHECK: call i8 @llvm.coro.suspend(
  51. // CHECK: call i1 @llvm.coro.end(