1 // RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s
4 void explicit_object_function(this TrivialStruct
) {}
8 s
.explicit_object_function();
10 // CHECK: define {{.*}}test{{.*}}
12 // CHECK: {{.*}} = alloca %struct.TrivialStruct, align 1
13 // CHECK: {{.*}} = alloca %struct.TrivialStruct, align 1
14 // CHECK: call void {{.*}}explicit_object_function{{.*}}
15 // CHECK-NEXT: ret void
18 // CHECK: define {{.*}}explicit_object_function{{.*}}
20 // CHECK: {{.*}} = alloca %struct.TrivialStruct, align 1
26 [](this auto This
) -> int {
31 //CHECK: define dso_local void @{{.*}}test_lambda{{.*}}() #0 {
33 //CHECK: %agg.tmp = alloca %class.anon, align 1
34 //CHECK: %call = call noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"()
38 //CHECK: define internal noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"() #0 align 2 {
40 //CHECK: %This = alloca %class.anon, align 1
41 //CHECK: %agg.tmp = alloca %class.anon, align 1
42 //CHECK: %call = call noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"()
43 //CHECK: ret i32 %call
46 void test_lambda_ref() {
47 auto l
= [i
= 42](this auto & This
, int j
) -> int {
53 // CHECK: define dso_local void @_Z15test_lambda_refv() #0 {
55 // CHECK: %[[This_address:.]] = alloca %class.anon{{.*}}, align 4
56 // CHECK: %[[i_addr:.*]] = getelementptr inbounds nuw %class.anon{{.*}}, ptr %[[This_address]], i32 0, i32 0
57 // CHECK: store i32 42, ptr %[[i_addr]], align 4
58 // CHECK: %call = call noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"{{.*}}
62 // CHECK: define internal noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"{{.*}}
64 // CHECK: %This.addr = alloca ptr, align 8
65 // CHECK: %j.addr = alloca i32, align 4
66 // CHECK: store ptr %This, ptr %This.addr, align 8
67 // CHECK: store i32 %j, ptr %j.addr, align 4
68 // CHECK: %[[this_addr:.*]] = load ptr, ptr %This.addr, align 8
69 // CHECK: %[[j_addr:.*]] = load i32, ptr %j.addr, align 4
70 // CHECK: %call = call noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"(ptr noundef nonnull align 4 dereferenceable(4) %[[this_addr]], i32 noundef %[[j_addr]])
71 // CHECK: ret i32 %call
76 void f(this TestPointer
&);
81 using Fn
= void(TestPointer
&);
82 Fn
* fn
= &TestPointer::f
;
85 //CHECK: define dso_local void @_Z12test_pointerv() #0 {
87 //CHECK-NEXT: %t = alloca %struct.TestPointer, align 1
88 //CHECK-NEXT: %fn = alloca ptr, align 8
89 //CHECK-NEXT: store ptr @_ZNH11TestPointer1fERS_, ptr %fn, align 8
90 //CHECK: %[[fn_ptr:.*]] = load ptr, ptr %fn, align 8
91 //CHECK-NEXT: call void %[[fn_ptr]](ptr noundef nonnull align 1 dereferenceable(1) %t)
92 //CHECK-NEXT: ret void
96 struct MaterializedTemporary
{
97 void foo(this MaterializedTemporary
&&);
98 MaterializedTemporary();
99 ~MaterializedTemporary();
102 void test_temporary() {
103 MaterializedTemporary
{}.foo();
106 //CHECK: define dso_local void @_Z14test_temporaryv(){{.*}}
108 //CHECK: %ref.tmp = alloca %struct.MaterializedTemporary, align 1
109 //CHECK: call void @_ZN21MaterializedTemporaryC1Ev(ptr noundef nonnull align 1 dereferenceable(1) %ref.tmp){{.*}}
110 //CHECK invoke void @_ZNH21MaterializedTemporary3fooEOS_(ptr noundef nonnull align 1 dereferenceable(1) %ref.tmp){{.*}}
115 function
& operator=(function
const&) {
124 //CHECK-LABEL: define internal void @"_ZZN7GH863991f{{.*}}"(ptr %{{.*}})
125 //CHECK: call {{.*}} @_ZN7GH863998functionaSERKS0_
126 //CHECK-NEXT: ret void
127 [&list
](this auto self
) {
134 // Just check that this doesn't crash (we were previously not instantiating
135 // everything that needs instantiating in here).
136 template <typename
> struct S
{};
140 const auto l
= [&x
](this auto&) { S
<decltype(x
)> q
; };
147 void do_thing(int x
) {
148 auto second
= [&](this auto const& self
, int b
) -> int {
156 void do_thing2(int x
) {
157 auto second
= [&](this auto const& self
) {
170 [&x
](this auto&&) {return x
;}();
175 auto dothing(int num
)
177 auto fun
= [&num
](this auto&& self
) -> void {
186 template <typename
... Ts
>
187 struct Overloaded
: Ts
... {
188 using Ts::operator()...;
191 template <typename
... Ts
>
192 Overloaded(Ts
...) -> Overloaded
<Ts
...>;
194 // CHECK-LABEL: define dso_local void @_ZN7GH872101fEv()
195 // CHECK-NEXT: entry:
196 // CHECK-NEXT: [[X:%.*]] = alloca i32
197 // CHECK-NEXT: [[Over:%.*]] = alloca %"{{.*}}Overloaded"
198 // CHECK: call noundef ptr @"_ZZN7GH872101fEvENH3$_0clINS_10OverloadedIJS0_EEEEEDaRT_"(ptr {{.*}} [[Over]])
202 // CHECK: define internal noundef ptr @"_ZZN7GH872101fEvENH3$_0clINS_10OverloadedIJS0_EEEEEDaRT_"(ptr {{.*}} [[Self:%.*]])
203 // CHECK-NEXT: entry:
204 // CHECK-NEXT: [[SelfAddr:%.*]] = alloca ptr
205 // CHECK-NEXT: store ptr [[Self]], ptr [[SelfAddr]]
206 // CHECK-NEXT: [[SelfPtr:%.*]] = load ptr, ptr [[SelfAddr]]
207 // CHECK-NEXT: [[XRef:%.*]] = getelementptr inbounds nuw %{{.*}}, ptr [[SelfPtr]], i32 0, i32 0
208 // CHECK-NEXT: [[X:%.*]] = load ptr, ptr [[XRef]]
209 // CHECK-NEXT: ret ptr [[X]]
210 [&](this auto& self
) {
220 [=](this auto& self
) {
229 // Same as above; just check that this doesn't crash.
231 auto factory(int& x
= one
) {
232 return [&](this auto self
) {
237 using Base
= decltype(factory());
238 struct Derived
: Base
{
239 Derived() : Base(factory()) {}
251 void c(this const C
&); // #first
252 void c() &; // #second
253 static void c(int = 0); // #third
263 // CHECK-LABEL: {{.*}} @_ZN5P27971C1dEv
264 // CHECK: call void @_ZNH5P27971C1cERKS0_
265 // CHECK: call void @_ZN5P27971C1cEi