blob: de8c124c050eb06a15c0e2348c87599f56b6555a [file] [log] [blame]
// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s
struct TrivialStruct {
void explicit_object_function(this TrivialStruct) {}
};
void test() {
TrivialStruct s;
s.explicit_object_function();
}
// CHECK: define {{.*}}test{{.*}}
// CHECK-NEXT: entry:
// CHECK: {{.*}} = alloca %struct.TrivialStruct, align 1
// CHECK: {{.*}} = alloca %struct.TrivialStruct, align 1
// CHECK: call void {{.*}}explicit_object_function{{.*}}
// CHECK-NEXT: ret void
// CHECK-NEXT: }
// CHECK: define {{.*}}explicit_object_function{{.*}}
// CHECK-NEXT: entry:
// CHECK: {{.*}} = alloca %struct.TrivialStruct, align 1
// CHECK: ret void
// CHECK-NEXT: }
void test_lambda() {
[](this auto This) -> int {
return This();
}();
}
//CHECK: define dso_local void @{{.*}}test_lambda{{.*}}() #0 {
//CHECK: entry:
//CHECK: %agg.tmp = alloca %class.anon, align 1
//CHECK: %ref.tmp = alloca %class.anon, align 1
//CHECK: %call = call noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"()
//CHECK: ret void
//CHECK: }
//CHECK: define internal noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"() #0 align 2 {
//CHECK: entry:
//CHECK: %This = alloca %class.anon, align 1
//CHECK: %agg.tmp = alloca %class.anon, align 1
//CHECK: %call = call noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"()
//CHECK: ret i32 %call
//CHECK: }
void test_lambda_ref() {
auto l = [i = 42](this auto & This, int j) -> int {
return This(j);
};
l(0);
}
// CHECK: define dso_local void @_Z15test_lambda_refv() #0 {
// CHECK: entry:
// CHECK: %[[This_address:.]] = alloca %class.anon{{.*}}, align 4
// CHECK: %[[i_addr:.*]] = getelementptr inbounds %class.anon{{.*}}, ptr %[[This_address]], i32 0, i32 0
// CHECK: store i32 42, ptr %[[i_addr]], align 4
// CHECK: %call = call noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"{{.*}}
// CHECK: ret void
// CHECK: }
// CHECK: define internal noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"{{.*}}
// CHECK: entry:
// CHECK: %This.addr = alloca ptr, align 8
// CHECK: %j.addr = alloca i32, align 4
// CHECK: store ptr %This, ptr %This.addr, align 8
// CHECK: store i32 %j, ptr %j.addr, align 4
// CHECK: %[[this_addr:.*]] = load ptr, ptr %This.addr, align 8
// CHECK: %[[j_addr:.*]] = load i32, ptr %j.addr, align 4
// CHECK: %call = call noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"(ptr noundef nonnull align 4 dereferenceable(4) %[[this_addr]], i32 noundef %[[j_addr]])
// CHECK: ret i32 %call
// CHECK: }
struct TestPointer {
void f(this TestPointer &);
};
void test_pointer() {
TestPointer t;
using Fn = void(TestPointer&);
Fn* fn = &TestPointer::f;
fn(t);
}
//CHECK: define dso_local void @_Z12test_pointerv() #0 {
//CHECK-NEXT: entry:
//CHECK-NEXT: %t = alloca %struct.TestPointer, align 1
//CHECK-NEXT: %fn = alloca ptr, align 8
//CHECK-NEXT: store ptr @_ZNH11TestPointer1fERS_, ptr %fn, align 8
//CHECK: %[[fn_ptr:.*]] = load ptr, ptr %fn, align 8
//CHECK-NEXT: call void %[[fn_ptr]](ptr noundef nonnull align 1 dereferenceable(1) %t)
//CHECK-NEXT: ret void
//CHECK-NEXT: }
struct MaterializedTemporary {
void foo(this MaterializedTemporary&&);
MaterializedTemporary();
~MaterializedTemporary();
};
void test_temporary() {
MaterializedTemporary{}.foo();
}
//CHECK: define dso_local void @_Z14test_temporaryv(){{.*}}
//CHECK-NEXT: entry:
//CHECK: %ref.tmp = alloca %struct.MaterializedTemporary, align 1
//CHECK: call void @_ZN21MaterializedTemporaryC1Ev(ptr noundef nonnull align 1 dereferenceable(1) %ref.tmp){{.*}}
//CHECK invoke void @_ZNH21MaterializedTemporary3fooEOS_(ptr noundef nonnull align 1 dereferenceable(1) %ref.tmp){{.*}}