1*ec117158SChuanqi Xu // Verify that we synthesized the coroutine for a lambda inside of a function template. 2*ec117158SChuanqi Xu // 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*ec117158SChuanqi Xu 4*ec117158SChuanqi Xu namespace std::experimental { 5*ec117158SChuanqi Xu template <typename R, typename... T> struct coroutine_traits { 6*ec117158SChuanqi Xu using promise_type = typename R::promise_type; 7*ec117158SChuanqi Xu }; 8*ec117158SChuanqi Xu 9*ec117158SChuanqi Xu template <class Promise = void> struct coroutine_handle; 10*ec117158SChuanqi Xu template <> struct coroutine_handle<void> { 11*ec117158SChuanqi Xu static coroutine_handle from_address(void *) noexcept; 12*ec117158SChuanqi Xu coroutine_handle() = default; 13*ec117158SChuanqi Xu template <class PromiseType> 14*ec117158SChuanqi Xu coroutine_handle(coroutine_handle<PromiseType>) noexcept; 15*ec117158SChuanqi Xu }; 16*ec117158SChuanqi Xu template <class Promise> struct coroutine_handle : coroutine_handle<void> { 17*ec117158SChuanqi Xu coroutine_handle() = default; 18*ec117158SChuanqi Xu static coroutine_handle from_address(void *) noexcept; 19*ec117158SChuanqi Xu }; 20*ec117158SChuanqi Xu } // namespace std::experimental 21*ec117158SChuanqi Xu 22*ec117158SChuanqi Xu struct suspend_always { 23*ec117158SChuanqi Xu bool await_ready() noexcept; 24*ec117158SChuanqi Xu void await_suspend(std::experimental::coroutine_handle<>) noexcept; 25*ec117158SChuanqi Xu void await_resume() noexcept; 26*ec117158SChuanqi Xu }; 27*ec117158SChuanqi Xu 28*ec117158SChuanqi Xu struct Task { 29*ec117158SChuanqi Xu struct promise_type { 30*ec117158SChuanqi Xu Task get_return_object(); return_voidTask::promise_type31*ec117158SChuanqi Xu void return_void() {} 32*ec117158SChuanqi Xu suspend_always initial_suspend() noexcept; 33*ec117158SChuanqi Xu suspend_always final_suspend() noexcept; 34*ec117158SChuanqi Xu void unhandled_exception() noexcept; 35*ec117158SChuanqi Xu }; 36*ec117158SChuanqi Xu }; 37*ec117158SChuanqi Xu SyncAwait(_AwrT && A)38*ec117158SChuanqi Xutemplate <typename _AwrT> auto SyncAwait(_AwrT &&A) { 39*ec117158SChuanqi Xu if (!A.await_ready()) { 40*ec117158SChuanqi Xu auto AwaitAsync = [&]() -> Task { 41*ec117158SChuanqi Xu try { 42*ec117158SChuanqi Xu (void)(co_await A); 43*ec117158SChuanqi Xu } catch (...) { 44*ec117158SChuanqi Xu } 45*ec117158SChuanqi Xu }; 46*ec117158SChuanqi Xu Task t = AwaitAsync(); 47*ec117158SChuanqi Xu } 48*ec117158SChuanqi Xu return A.await_resume(); 49*ec117158SChuanqi Xu } 50*ec117158SChuanqi Xu f()51*ec117158SChuanqi Xuvoid f() { 52*ec117158SChuanqi Xu suspend_always test; 53*ec117158SChuanqi Xu SyncAwait(test); 54*ec117158SChuanqi Xu } 55*ec117158SChuanqi Xu 56*ec117158SChuanqi Xu // Verify that we synthesized the coroutine for a lambda inside SyncAwait 57*ec117158SChuanqi Xu // CHECK-LABEL: define linkonce_odr void @_ZZ9SyncAwaitIR14suspend_alwaysEDaOT_ENKUlvE_clEv( 58*ec117158SChuanqi Xu // CHECK: alloca %"struct.Task::promise_type" 59*ec117158SChuanqi Xu // CHECK: call token @llvm.coro.id( 60*ec117158SChuanqi Xu // CHECK: call i8 @llvm.coro.suspend( 61*ec117158SChuanqi Xu // CHECK: call i1 @llvm.coro.end( 62