1 // RUN: %clang_cc1 -std=c++2a -fcoroutines-ts -triple=x86_64 -dwarf-version=4 -debug-info-kind=limited -emit-llvm -o - %s | FileCheck %s 2 3 namespace std::experimental { 4 template <typename... T> struct coroutine_traits; 5 6 template <class Promise = void> struct coroutine_handle { 7 coroutine_handle() = default; 8 static coroutine_handle from_address(void *) noexcept; 9 }; 10 template <> struct coroutine_handle<void> { 11 static coroutine_handle from_address(void *) noexcept; 12 coroutine_handle() = default; 13 template <class PromiseType> 14 coroutine_handle(coroutine_handle<PromiseType>) noexcept; 15 }; 16 } // namespace std::experimental 17 18 struct suspend_always { 19 bool await_ready() noexcept; 20 void await_suspend(std::experimental::coroutine_handle<>) noexcept; 21 void await_resume() noexcept; 22 }; 23 24 template <typename... Args> struct std::experimental::coroutine_traits<void, Args...> { 25 struct promise_type { 26 void get_return_object() noexcept; 27 suspend_always initial_suspend() noexcept; 28 suspend_always final_suspend() noexcept; 29 void return_void() noexcept; 30 promise_type(); 31 ~promise_type() noexcept; 32 void unhandled_exception() noexcept; 33 }; 34 }; 35 36 // TODO: Not supported yet 37 struct CopyOnly { 38 int val; 39 CopyOnly(const CopyOnly &) noexcept; 40 CopyOnly(CopyOnly &&) = delete; 41 ~CopyOnly(); 42 }; 43 44 struct MoveOnly { 45 int val; 46 MoveOnly(const MoveOnly &) = delete; 47 MoveOnly(MoveOnly &&) noexcept; 48 ~MoveOnly(); 49 }; 50 51 struct MoveAndCopy { 52 int val; 53 MoveAndCopy(const MoveAndCopy &) noexcept; 54 MoveAndCopy(MoveAndCopy &&) noexcept; 55 ~MoveAndCopy(); 56 }; 57 58 void consume(int, int, int) noexcept; 59 60 void f_coro(int val, MoveOnly moParam, MoveAndCopy mcParam) { 61 consume(val, moParam.val, mcParam.val); 62 co_return; 63 } 64 65 // CHECK: ![[SP:[0-9]+]] = distinct !DISubprogram(name: "f_coro", linkageName: "_Z6f_coroi8MoveOnly11MoveAndCopy" 66 // CHECK: !{{[0-9]+}} = !DILocalVariable(name: "val", arg: 1, scope: ![[SP]], file: !8, line: 60, type: !{{[0-9]+}}) 67 // CHECK: !{{[0-9]+}} = !DILocation(line: 60, column: 17, scope: ![[SP]]) 68 // CHECK: !{{[0-9]+}} = !DILocalVariable(name: "moParam", arg: 2, scope: ![[SP]], file: !8, line: 60, type: !{{[0-9]+}}) 69 // CHECK: !{{[0-9]+}} = !DILocation(line: 60, column: 31, scope: ![[SP]]) 70 // CHECK: !{{[0-9]+}} = !DILocalVariable(name: "mcParam", arg: 3, scope: ![[SP]], file: !8, line: 60, type: !{{[0-9]+}}) 71 // CHECK: !{{[0-9]+}} = !DILocation(line: 60, column: 52, scope: ![[SP]]) 72 // CHECK: !{{[0-9]+}} = !DILocation(line: 60, column: 61, scope: ![[SP]]) 73 // CHECK: !{{[0-9]+}} = !DILocation(line: 60, column: 6, scope: ![[SP]]) 74 // CHECK: !{{[0-9]+}} = !DILocation(line: 0, scope: ![[SP]]) 75 // CHECK-NOT: !{{[0-9]+}} = !DILocalVariable(name: "val", scope: ![[SP]], type: !{{[0-9]+}}, flags: DIFlagArtificial) 76 // CHECK-NOT: !{{[0-9]+}} = !DILocalVariable(name: "moParam", scope: ![[SP]], type: !{{[0-9]+}}, flags: DIFlagArtificial) 77 // CHECK-NOT:: !{{[0-9]+}} = !DILocalVariable(name: "mcParam", scope: ![[SP]], type: !{{[0-9]+}}, flags: DIFlagArtificial) 78