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