|
4 | 4 | // RUN: %clang_cc1 -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s
|
5 | 5 | // RUN: %clang_cc1 -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s
|
6 | 6 |
|
7 |
| -// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s |
8 |
| -// RUN: %clang_cc1 -x c++ -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s |
9 |
| -// RUN: %clang_cc1 -x c++ -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s |
10 |
| -// RUN: %clang_cc1 -x c++ -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s |
11 |
| -// RUN: %clang_cc1 -x c++ -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s |
| 7 | +// RUN: %clang_cc1 -x c++ -triple x86_64-apple-darwin10 -target-cpu core2 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY |
| 8 | +// RUN: %clang_cc1 -x c++ -triple arm64-apple-ios9 -target-cpu cyclone -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY |
| 9 | +// RUN: %clang_cc1 -x c++ -triple armv7-apple-darwin9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY |
| 10 | +// RUN: %clang_cc1 -x c++ -triple armv7s-apple-ios9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY |
| 11 | +// RUN: %clang_cc1 -x c++ -triple armv7k-apple-ios9 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=CPPONLY |
12 | 12 |
|
13 | 13 | // Test tail call behavior when a swiftasynccall function is called
|
14 | 14 | // from another swiftasynccall function.
|
@@ -136,3 +136,49 @@ char c_calling_async(MYBOOL b, unsigned u) {
|
136 | 136 | return x;
|
137 | 137 | }
|
138 | 138 |
|
| 139 | +#if __cplusplus |
| 140 | +struct S { |
| 141 | + SWIFTASYNCCALL void (*fptr)(char * ASYNC_CONTEXT); |
| 142 | + |
| 143 | + SWIFTASYNCCALL void async_leaf_method(char * ASYNC_CONTEXT ctx) { |
| 144 | + *ctx += 1; |
| 145 | + } |
| 146 | + SWIFTASYNCCALL void async_nonleaf_method1(char * ASYNC_CONTEXT ctx) { |
| 147 | + return async_leaf_method(ctx); |
| 148 | + } |
| 149 | + SWIFTASYNCCALL void async_nonleaf_method2(char * ASYNC_CONTEXT ctx) { |
| 150 | + return this->async_leaf_method(ctx); |
| 151 | + } |
| 152 | +}; |
| 153 | + |
| 154 | +SWIFTASYNCCALL void (S::*async_leaf_method_ptr)(char * ASYNC_CONTEXT) = &S::async_leaf_method; |
| 155 | + |
| 156 | +// CPPONLY-LABEL: swifttailcc void {{.*}}async_struct_field_and_methods |
| 157 | +// CPPONLY: musttail call swifttailcc void %{{[0-9]+}} |
| 158 | +// CPPONLY: musttail call swifttailcc void @{{.*}}async_nonleaf_method1 |
| 159 | +// CPPONLY: musttail call swifttailcc void %{{[0-9]+}} |
| 160 | +// CPPONLY: musttail call swifttailcc void @{{.*}}async_nonleaf_method2 |
| 161 | +// CPPONLY-NOT: musttail call swifttailcc void @{{.*}}async_leaf_method |
| 162 | +// ^ TODO: Member pointers should also work. |
| 163 | +SWIFTASYNCCALL void async_struct_field_and_methods(int i, S &sref, S *sptr) { |
| 164 | + char x = 'a'; |
| 165 | + if (i == 0) { |
| 166 | + return (*sref.fptr)(&x); |
| 167 | + } else if (i == 1) { |
| 168 | + return sref.async_nonleaf_method1(&x); |
| 169 | + } else if (i == 2) { |
| 170 | + return (*(sptr->fptr))(&x); |
| 171 | + } else if (i == 3) { |
| 172 | + return sptr->async_nonleaf_method2(&x); |
| 173 | + } else if (i == 4) { |
| 174 | + return (sref.*async_leaf_method_ptr)(&x); |
| 175 | + } |
| 176 | + return (sptr->*async_leaf_method_ptr)(&x); |
| 177 | +} |
| 178 | + |
| 179 | +// CPPONLY-LABEL: define{{.*}} swifttailcc void @{{.*}}async_nonleaf_method1 |
| 180 | +// CPPONLY: musttail call swifttailcc void @{{.*}}async_leaf_method |
| 181 | + |
| 182 | +// CPPONLY-LABEL: define{{.*}} swifttailcc void @{{.*}}async_nonleaf_method2 |
| 183 | +// CPPONLY: musttail call swifttailcc void @{{.*}}async_leaf_method |
| 184 | +#endif |
0 commit comments