xref: /aosp_15_r20/external/clang/test/CodeGenObjCXX/property-objects.mm (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -std=c++11 -emit-llvm -debug-info-kind=limited -o - | FileCheck %s
2*67e74705SXin Li
3*67e74705SXin Liclass S {
4*67e74705SXin Lipublic:
5*67e74705SXin Li	S& operator = (const S&);
6*67e74705SXin Li	S (const S&);
7*67e74705SXin Li	S ();
8*67e74705SXin Li};
9*67e74705SXin Li
10*67e74705SXin Listruct CGRect {
11*67e74705SXin Li	CGRect & operator = (const CGRect &);
12*67e74705SXin Li};
13*67e74705SXin Li
14*67e74705SXin Li@interface I {
15*67e74705SXin Li  S position;
16*67e74705SXin Li  CGRect bounds;
17*67e74705SXin Li}
18*67e74705SXin Li
19*67e74705SXin Li@property(assign, nonatomic) S position;
20*67e74705SXin Li@property CGRect bounds;
21*67e74705SXin Li@property CGRect frame;
22*67e74705SXin Li- (void)setFrame:(CGRect)frameRect;
23*67e74705SXin Li- (CGRect)frame;
24*67e74705SXin Li- (void) initWithOwner;
25*67e74705SXin Li- (CGRect)extent;
26*67e74705SXin Li- (void)dealloc;
27*67e74705SXin Li@end
28*67e74705SXin Li
29*67e74705SXin Li@implementation I
30*67e74705SXin Li@synthesize position;
31*67e74705SXin Li@synthesize bounds;
32*67e74705SXin Li@synthesize frame;
33*67e74705SXin Li
34*67e74705SXin Li// CHECK: define internal void @"\01-[I setPosition:]"
35*67e74705SXin Li// CHECK: call dereferenceable({{[0-9]+}}) %class.S* @_ZN1SaSERKS_
36*67e74705SXin Li// CHECK-NEXT: ret void
37*67e74705SXin Li
38*67e74705SXin Li// Don't attach debug locations to the prologue instructions. These were
39*67e74705SXin Li// leaking over from the previous function emission by accident.
40*67e74705SXin Li// CHECK: define internal void @"\01-[I setBounds:]"({{.*}} {
41*67e74705SXin Li// CHECK-NOT: !dbg
42*67e74705SXin Li// CHECK: call void @llvm.dbg.declare
43*67e74705SXin Li- (void)setFrame:(CGRect)frameRect {}
44*67e74705SXin Li- (CGRect)frame {return bounds;}
45*67e74705SXin Li
46*67e74705SXin Li- (void)initWithOwner {
47*67e74705SXin Li  I* _labelLayer;
48*67e74705SXin Li  CGRect labelLayerFrame = self.bounds;
49*67e74705SXin Li  labelLayerFrame = self.bounds;
50*67e74705SXin Li  _labelLayer.frame = labelLayerFrame;
51*67e74705SXin Li}
52*67e74705SXin Li
53*67e74705SXin Li// rdar://8366604
54*67e74705SXin Li- (void)dealloc
55*67e74705SXin Li  {
56*67e74705SXin Li      CGRect cgrect = self.extent;
57*67e74705SXin Li  }
58*67e74705SXin Li- (struct CGRect)extent {return bounds;}
59*67e74705SXin Li
60*67e74705SXin Li@end
61*67e74705SXin Li
62*67e74705SXin Li// CHECK-LABEL: define i32 @main
63*67e74705SXin Li// CHECK: call void @_ZN1SC1ERKS_(%class.S* [[AGGTMP:%[a-zA-Z0-9\.]+]], %class.S* dereferenceable({{[0-9]+}}) {{%[a-zA-Z0-9\.]+}})
64*67e74705SXin Li// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %class.S*)*)(i8* {{%[a-zA-Z0-9\.]+}}, i8* {{%[a-zA-Z0-9\.]+}}, %class.S* [[AGGTMP]])
65*67e74705SXin Li// CHECK-NEXT: ret i32 0
66*67e74705SXin Liint main() {
67*67e74705SXin Li  I *i;
68*67e74705SXin Li  S s1;
69*67e74705SXin Li  i.position = s1;
70*67e74705SXin Li  return 0;
71*67e74705SXin Li}
72*67e74705SXin Li
73*67e74705SXin Li// rdar://8379892
74*67e74705SXin Li// CHECK-LABEL: define void @_Z1fP1A
75*67e74705SXin Li// CHECK: call void @_ZN1XC1Ev(%struct.X* [[LVTEMP:%[a-zA-Z0-9\.]+]])
76*67e74705SXin Li// CHECK: call void @_ZN1XC1ERKS_(%struct.X* [[AGGTMP:%[a-zA-Z0-9\.]+]], %struct.X* dereferenceable({{[0-9]+}}) [[LVTEMP]])
77*67e74705SXin Li// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, %struct.X*)*)({{.*}} %struct.X* [[AGGTMP]])
78*67e74705SXin Listruct X {
79*67e74705SXin Li  X();
80*67e74705SXin Li  X(const X&);
81*67e74705SXin Li  ~X();
82*67e74705SXin Li};
83*67e74705SXin Li
84*67e74705SXin Li@interface A {
85*67e74705SXin Li  X xval;
86*67e74705SXin Li}
87*67e74705SXin Li- (X)x;
88*67e74705SXin Li- (void)setX:(X)x;
89*67e74705SXin Li@end
90*67e74705SXin Li
91*67e74705SXin Livoid f(A* a) {
92*67e74705SXin Li  a.x = X();
93*67e74705SXin Li}
94*67e74705SXin Li
95*67e74705SXin Li// rdar://21801088
96*67e74705SXin Li//   Ensure that pseudo-objecet expressions that require the RHS to be
97*67e74705SXin Li//   rewritten don't result in crashes or redundant emission of code.
98*67e74705SXin Listruct B0 { long long x; };
99*67e74705SXin Listruct B1 { long long x; }; B1 operator+(B1, B1);
100*67e74705SXin Listruct B2 { B1 x; };
101*67e74705SXin Listruct B3 { B3(); B1 x; operator B1(); };
102*67e74705SXin Li@interface B
103*67e74705SXin Li@property B0 b0;
104*67e74705SXin Li@property B1 b1;
105*67e74705SXin Li@property B2 b2;
106*67e74705SXin Li@property B3 b3;
107*67e74705SXin Li@end
108*67e74705SXin Li
109*67e74705SXin Liint b_makeInt();
110*67e74705SXin Li
111*67e74705SXin Li// Note that there's a promotion from int to long long, so
112*67e74705SXin Li// the syntactic form of the RHS will be bogus.
113*67e74705SXin Livoid testB0(B *b) {
114*67e74705SXin Li  b.b0 = { b_makeInt() };
115*67e74705SXin Li}
116*67e74705SXin Livoid testB1(B *b) {
117*67e74705SXin Li  b.b1 += { b_makeInt() };
118*67e74705SXin Li}
119*67e74705SXin Li// CHECK:    define void @_Z6testB0P1B([[B:%.*]]*
120*67e74705SXin Li// CHECK:      [[BVAR:%.*]] = alloca [[B]]*, align 8
121*67e74705SXin Li// CHECK:      [[TEMP:%.*]] = alloca [[B0:%.*]], align 8
122*67e74705SXin Li// CHECK:      load [[B]]*, [[B]]** [[BVAR]]
123*67e74705SXin Li// CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[B0]], [[B0]]* [[TEMP]], i32 0, i32 0
124*67e74705SXin Li// CHECK-NEXT: [[T0:%.*]] = call i32 @_Z9b_makeIntv()
125*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = sext i32 [[T0]] to i64
126*67e74705SXin Li// CHECK-NEXT: store i64 [[T1]], i64* [[X]], align 8
127*67e74705SXin Li// CHECK-NOT:  call
128*67e74705SXin Li// CHECK:      call void @llvm.memcpy
129*67e74705SXin Li// CHECK-NOT:  call
130*67e74705SXin Li// CHECK:      call void bitcast {{.*}} @objc_msgSend
131*67e74705SXin Li// CHECK-NOT:  call
132*67e74705SXin Li// CHECK:      ret void
133*67e74705SXin Li
134*67e74705SXin Li// CHECK:    define void @_Z6testB1P1B([[B]]*
135*67e74705SXin Li// CHECK:      [[BVAR:%.*]] = alloca [[B]]*, align 8
136*67e74705SXin Li// CHECK:      load [[B]]*, [[B]]** [[BVAR]]
137*67e74705SXin Li// CHECK-NOT:  call
138*67e74705SXin Li// CHECK:      [[T0:%.*]] = call i64 bitcast {{.*}} @objc_msgSend
139*67e74705SXin Li// CHECK-NOT:  call
140*67e74705SXin Li// CHECK:      store i64 [[T0]],
141*67e74705SXin Li// CHECK-NOT:  call
142*67e74705SXin Li// CHECK:      [[T0:%.*]] = call i32 @_Z9b_makeIntv()
143*67e74705SXin Li// CHECK-NEXT: [[T1:%.*]] = sext i32 [[T0]] to i64
144*67e74705SXin Li// CHECK-NEXT: store i64 [[T1]], i64* {{.*}}, align 8
145*67e74705SXin Li// CHECK-NOT:  call
146*67e74705SXin Li// CHECK:      [[T0:%.*]] = call i64 @_Zpl2B1S_
147*67e74705SXin Li// CHECK-NOT:  call
148*67e74705SXin Li// CHECK:      store i64 [[T0]],
149*67e74705SXin Li// CHECK-NOT:  call
150*67e74705SXin Li// CHECK:      call void @llvm.memcpy
151*67e74705SXin Li// CHECK-NOT:  call
152*67e74705SXin Li// CHECK:      call void bitcast {{.*}} @objc_msgSend
153*67e74705SXin Li// CHECK-NOT:  call
154*67e74705SXin Li// CHECK:      ret void
155*67e74705SXin Li
156*67e74705SXin Li// Another example of a conversion that needs to be applied
157*67e74705SXin Li// in the semantic form.
158*67e74705SXin Livoid testB2(B *b) {
159*67e74705SXin Li  b.b2 = { B3() };
160*67e74705SXin Li}
161*67e74705SXin Li
162*67e74705SXin Li// CHECK:    define void @_Z6testB2P1B([[B]]*
163*67e74705SXin Li// CHECK:      [[BVAR:%.*]] = alloca [[B]]*, align 8
164*67e74705SXin Li// CHECK:      load [[B]]*, [[B]]** [[BVAR]]
165*67e74705SXin Li// CHECK-NOT:  call
166*67e74705SXin Li// CHECK:      call void @_ZN2B3C1Ev(
167*67e74705SXin Li// CHECK-NEXT: [[T0:%.*]] = call i64 @_ZN2B3cv2B1Ev(
168*67e74705SXin Li// CHECK-NOT:  call
169*67e74705SXin Li// CHECK:      store i64 [[T0]],
170*67e74705SXin Li// CHECK-NOT:  call
171*67e74705SXin Li// CHECK:      call void @llvm.memcpy
172*67e74705SXin Li// CHECK-NOT:  call
173*67e74705SXin Li// CHECK:      call void bitcast {{.*}} @objc_msgSend
174*67e74705SXin Li// CHECK-NOT:  call
175*67e74705SXin Li// CHECK:      ret void
176*67e74705SXin Li
177*67e74705SXin Li// A similar test to B, but using overloaded function references.
178*67e74705SXin Listruct C1 {
179*67e74705SXin Li  int x;
180*67e74705SXin Li  friend C1 operator+(C1, void(&)());
181*67e74705SXin Li};
182*67e74705SXin Li@interface C
183*67e74705SXin Li@property void (*c0)();
184*67e74705SXin Li@property C1 c1;
185*67e74705SXin Li@end
186*67e74705SXin Li
187*67e74705SXin Livoid c_helper();
188*67e74705SXin Livoid c_helper(int);
189*67e74705SXin Li
190*67e74705SXin Livoid testC0(C *c) {
191*67e74705SXin Li  c.c0 = c_helper;
192*67e74705SXin Li  c.c0 = &c_helper;
193*67e74705SXin Li}
194*67e74705SXin Li// CHECK:    define void @_Z6testC0P1C([[C:%.*]]*
195*67e74705SXin Li// CHECK:      [[CVAR:%.*]] = alloca [[C]]*, align 8
196*67e74705SXin Li// CHECK:      load [[C]]*, [[C]]** [[CVAR]]
197*67e74705SXin Li// CHECK-NOT:  call
198*67e74705SXin Li// CHECK:      call void bitcast {{.*}} @objc_msgSend {{.*}} @_Z8c_helperv
199*67e74705SXin Li// CHECK-NOT:  call
200*67e74705SXin Li// CHECK:      call void bitcast {{.*}} @objc_msgSend {{.*}} @_Z8c_helperv
201*67e74705SXin Li// CHECK-NOT:  call
202*67e74705SXin Li// CHECK:      ret void
203*67e74705SXin Li
204*67e74705SXin Livoid testC1(C *c) {
205*67e74705SXin Li  c.c1 += c_helper;
206*67e74705SXin Li}
207*67e74705SXin Li// CHECK:    define void @_Z6testC1P1C([[C]]*
208*67e74705SXin Li// CHECK:      [[CVAR:%.*]] = alloca [[C]]*, align 8
209*67e74705SXin Li// CHECK:      load [[C]]*, [[C]]** [[CVAR]]
210*67e74705SXin Li// CHECK-NOT:  call
211*67e74705SXin Li// CHECK:      [[T0:%.*]] = call i32 bitcast {{.*}} @objc_msgSend
212*67e74705SXin Li// CHECK-NOT:  call
213*67e74705SXin Li// CHECK:      store i32 [[T0]],
214*67e74705SXin Li// CHECK-NOT:  call
215*67e74705SXin Li// CHECK:      [[T0:%.*]] = call i32 @_Zpl2C1RFvvE({{.*}} @_Z8c_helperv
216*67e74705SXin Li// CHECK-NOT:  call
217*67e74705SXin Li// CHECK:      store i32 [[T0]],
218*67e74705SXin Li// CHECK-NOT:  call
219*67e74705SXin Li// CHECK:      call void @llvm.memcpy
220*67e74705SXin Li// CHECK-NOT:  call
221*67e74705SXin Li// CHECK:      call void bitcast {{.*}} @objc_msgSend
222*67e74705SXin Li// CHECK-NOT:  call
223*67e74705SXin Li// CHECK:      ret void
224