xref: /aosp_15_r20/external/clang/test/CodeGenObjCXX/property-reference.mm (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -fobjc-runtime=macosx-fragile-10.5 -emit-llvm -o - | FileCheck %s
2*67e74705SXin Li// rdar://9208606
3*67e74705SXin Li
4*67e74705SXin Listruct MyStruct {
5*67e74705SXin Li  int x;
6*67e74705SXin Li  int y;
7*67e74705SXin Li  int z;
8*67e74705SXin Li};
9*67e74705SXin Li
10*67e74705SXin Li@interface MyClass {
11*67e74705SXin Li  MyStruct _foo;
12*67e74705SXin Li}
13*67e74705SXin Li
14*67e74705SXin Li@property (assign, readwrite) const MyStruct& foo;
15*67e74705SXin Li
16*67e74705SXin Li- (const MyStruct&) foo;
17*67e74705SXin Li- (void) setFoo:(const MyStruct&)inFoo;
18*67e74705SXin Li@end
19*67e74705SXin Li
20*67e74705SXin Livoid test0() {
21*67e74705SXin Li  MyClass* myClass;
22*67e74705SXin Li  MyStruct myStruct;
23*67e74705SXin Li
24*67e74705SXin Li  myClass.foo = myStruct;
25*67e74705SXin Li
26*67e74705SXin Li  const MyStruct& currentMyStruct = myClass.foo;
27*67e74705SXin Li}
28*67e74705SXin Li
29*67e74705SXin Li// CHECK: [[C:%.*]] = call dereferenceable({{[0-9]+}}) %struct.MyStruct* bitcast (i8* (i8*, i8*, ...)* @objc_msgSend
30*67e74705SXin Li// CHECK:   store %struct.MyStruct* [[C]], %struct.MyStruct** [[D:%.*]]
31*67e74705SXin Li
32*67e74705SXin Linamespace test1 {
33*67e74705SXin Li  struct A { A(); A(const A&); A&operator=(const A&); ~A(); };
34*67e74705SXin Li}
35*67e74705SXin Li@interface Test1 {
36*67e74705SXin Li  test1::A ivar;
37*67e74705SXin Li}
38*67e74705SXin Li@property (nonatomic) const test1::A &prop1;
39*67e74705SXin Li@end
40*67e74705SXin Li@implementation Test1
41*67e74705SXin Li@synthesize prop1 = ivar;
42*67e74705SXin Li@end
43*67e74705SXin Li// CHECK:    define internal dereferenceable({{[0-9]+}}) [[A:%.*]]* @"\01-[Test1 prop1]"(
44*67e74705SXin Li// CHECK:      [[SELF:%.*]] = alloca [[TEST1:%.*]]*, align 8
45*67e74705SXin Li// CHECK:      [[T0:%.*]] = load [[TEST1]]*, [[TEST1]]** [[SELF]]
46*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = bitcast [[TEST1]]* [[T0]] to i8*
47*67e74705SXin Li// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i8, i8* [[T1]], i64 0
48*67e74705SXin Li// CHECK-NEXT: [[T3:%.*]] = bitcast i8* [[T2]] to [[A]]*
49*67e74705SXin Li// CHECK-NEXT: ret [[A]]* [[T3]]
50*67e74705SXin Li
51*67e74705SXin Li// CHECK:    define internal void @"\01-[Test1 setProp1:]"(
52*67e74705SXin Li// CHECK:      call dereferenceable({{[0-9]+}}) [[A]]* @_ZN5test11AaSERKS0_(
53*67e74705SXin Li// CHECK-NEXT: ret void
54*67e74705SXin Li
55*67e74705SXin Li// rdar://problem/10497174
56*67e74705SXin Li@interface Test2
57*67e74705SXin Li@property int prop;
58*67e74705SXin Li@end
59*67e74705SXin Li
60*67e74705SXin Li// The fact that these are all non-dependent is critical.
61*67e74705SXin Litemplate <class T> void test2(Test2 *a) {
62*67e74705SXin Li  int x = a.prop;
63*67e74705SXin Li  a.prop = x;
64*67e74705SXin Li  a.prop += x;
65*67e74705SXin Li}
66*67e74705SXin Litemplate void test2<int>(Test2*);
67*67e74705SXin Li// CHECK-LABEL: define weak_odr void @_Z5test2IiEvP5Test2(
68*67e74705SXin Li// CHECK: [[X:%.*]] = alloca i32,
69*67e74705SXin Li// CHECK:      @objc_msgSend
70*67e74705SXin Li// CHECK:      store i32 {{%.*}}, i32* [[X]],
71*67e74705SXin Li// CHECK:      load i32, i32* [[X]],
72*67e74705SXin Li// CHECK:      @objc_msgSend
73*67e74705SXin Li// CHECK:      @objc_msgSend
74*67e74705SXin Li// CHECK:      load i32, i32* [[X]],
75*67e74705SXin Li// CHECK-NEXT: add nsw
76*67e74705SXin Li// CHECK:      @objc_msgSend
77*67e74705SXin Li// CHECK-NEXT: ret void
78*67e74705SXin Li
79*67e74705SXin Li// Same as the previous test, but instantiation-dependent.
80*67e74705SXin Litemplate <class T> void test3(Test2 *a) {
81*67e74705SXin Li  int x = (sizeof(T), a).prop;
82*67e74705SXin Li  a.prop = (sizeof(T), x);
83*67e74705SXin Li  a.prop += (sizeof(T), x);
84*67e74705SXin Li}
85*67e74705SXin Litemplate void test3<int>(Test2*);
86*67e74705SXin Li// CHECK-LABEL: define weak_odr void @_Z5test3IiEvP5Test2(
87*67e74705SXin Li// CHECK: [[X:%.*]] = alloca i32,
88*67e74705SXin Li// CHECK:      @objc_msgSend
89*67e74705SXin Li// CHECK:      store i32 {{%.*}}, i32* [[X]],
90*67e74705SXin Li// CHECK:      load i32, i32* [[X]],
91*67e74705SXin Li// CHECK:      @objc_msgSend
92*67e74705SXin Li// CHECK:      @objc_msgSend
93*67e74705SXin Li// CHECK:      load i32, i32* [[X]],
94*67e74705SXin Li// CHECK-NEXT: add nsw
95*67e74705SXin Li// CHECK:      @objc_msgSend
96*67e74705SXin Li// CHECK-NEXT: ret void
97