blob: 6c72138f93e1883bc868850ebba7c1c1b5d53c5a [file] [log] [blame]
Fariborz Jahanianbd8fa302012-11-05 18:14:34 +00001// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -O0 -emit-llvm %s -o %t-64.s
2// RUN: FileCheck --input-file=%t-64.s %s
3// rdar://12184410
4
5void x(id y) {}
6void y(int a) {}
7
8extern id opaque_id();
9
10void f() {
11 __weak id wid;
12 __block int byref_int = 0;
13 char ch = 'a';
14 char ch1 = 'b';
15 char ch2 = 'c';
16 short sh = 2;
17 const id bar = (id) opaque_id();
18 id baz = 0;
19 __strong id strong_void_sta;
20 __block id byref_bab = (id)0;
21 __block id bl_var1;
22 int i; double dob;
23
24// The patterns here are a sequence of bytes, each saying first how
25// many sizeof(void*) chunks to skip (high nibble) and then how many
26// to scan (low nibble). A zero byte says that we've reached the end
27// of the pattern.
28//
29// All of these patterns start with 01 3x because the block header on
30// LP64 consists of an isa pointer (which we're supposed to scan for
31// some reason) followed by three words (2 ints, a function pointer,
32// and a descriptor pointer).
33
34// Test 1
35// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_BYREF:1, BL_OPERATOR:0
36// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"@2@\00"
37 void (^b)() = ^{
38 byref_int = sh + ch+ch1+ch2 ;
39 x(bar);
40 x(baz);
41 x((id)strong_void_sta);
42 x(byref_bab);
43 };
44 b();
45
46// Test 2
47// block variable layout: BL_BYREF:1, BL_STRONG:3, BL_WEAK:1, BL_BYREF:2, BL_OPERATOR:0
48// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"@2PA\00"
49 void (^c)() = ^{
50 byref_int = sh + ch+ch1+ch2 ;
51 x(bar);
52 x(baz);
53 x((id)strong_void_sta);
54 x(wid);
55 bl_var1 = 0;
56 x(byref_bab);
57 };
58}
59
60@class NSString, NSNumber;
61void g() {
62 NSString *foo;
63 NSNumber *bar;
64 unsigned int bletch;
65 __weak id weak_delegate;
66 unsigned int i;
67 NSString *y;
68 NSString *z;
69// block variable layout: BL_STRONG:2, BL_WEAK:1, BL_STRONG:2, BL_OPERATOR:0
70// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"!1P1\00"
71 void (^c)() = ^{
72 int j = i + bletch;
73 x(foo);
74 x(bar);
75 x(weak_delegate);
76 x(y);
77 x(z);
78 };
79 c();
80}
81
82// Test 5 (unions/structs and their nesting):
83void h() {
84 struct S5 {
85 int i1;
86 __unsafe_unretained id o1;
87 struct V {
88 int i2;
89 __unsafe_unretained id o2;
90 } v1;
91 int i3;
92 union UI {
93 void * i1;
94 __unsafe_unretained id o1;
95 int i3;
96 __unsafe_unretained id o3;
97 }ui;
98 };
99
100 union U {
101 void * i1;
102 __unsafe_unretained id o1;
103 int i3;
104 __unsafe_unretained id o3;
105 }ui;
106
107 struct S5 s2;
108 union U u2;
109 __block id block_id;
110
111/**
112block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1, BL_NON_OBJECT_WORD:1,
113 BL_UNRETAINE:1, BL_NON_OBJECT_WORD:3, BL_BYREF:1, BL_OPERATOR:0
114*/
115// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [7 x i8] c" ` `\22@\00"
116 void (^c)() = ^{
117 x(s2.ui.o1);
118 x(u2.o1);
119 block_id = 0;
120 };
121 c();
122}
123
124// Test for array of stuff.
125void arr1() {
126 struct S {
127 __unsafe_unretained id unsafe_unretained_var[4];
128 } imported_s;
129
130// block variable layout: BL_UNRETAINE:4, BL_OPERATOR:0
131// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"c\00"
132 void (^c)() = ^{
133 x(imported_s.unsafe_unretained_var[2]);
134 };
135
136 c();
137}
138
139// Test2 for array of stuff.
140void arr2() {
141 struct S {
142 int a;
143 __unsafe_unretained id unsafe_unretained_var[4];
144 } imported_s;
145
146// block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:4, BL_OPERATOR:0
147// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c" c\00"
148 void (^c)() = ^{
149 x(imported_s.unsafe_unretained_var[2]);
150 };
151
152 c();
153}
154
155// Test3 for array of stuff.
156void arr3() {
157 struct S {
158 int a;
159 __unsafe_unretained id unsafe_unretained_var[0];
160 } imported_s;
161
162// block variable layout: BL_OPERATOR:0
163// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
164 void (^c)() = ^{
165 int i = imported_s.a;
166 };
167
168 c();
169}
170
171
172// Test4 for array of stuff.
173@class B;
174void arr4() {
175 struct S {
176 struct s0 {
177 __unsafe_unretained id s_f0;
178 __unsafe_unretained id s_f1;
179 } f0;
180
181 __unsafe_unretained id f1;
182
183 struct s1 {
184 int *f0;
185 __unsafe_unretained B *f1;
186 } f4[2][2];
187 } captured_s;
188
189/**
190block variable layout: BL_UNRETAINE:3,
191 BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
192 BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
193 BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
194 BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1,
195 BL_OPERATOR:0
196*/
197// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [10 x i8]
198 void (^c)() = ^{
199 id i = captured_s.f0.s_f1;
200 };
201
202 c();
203}
204
205// Test1 bitfield in cpatured aggregate.
206void bf1() {
207 struct S {
208 int flag : 25;
209 int flag1: 7;
210 int flag2 :1;
211 int flag3: 7;
212 int flag4: 24;
213 } s;
214
215// block variable layout: BL_OPERATOR:0
216// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
217 int (^c)() = ^{
218 return s.flag;
219 };
220 c();
221}
222
223// Test2 bitfield in cpatured aggregate.
224void bf2() {
225 struct S {
226 int flag : 1;
227 } s;
228
229// block variable layout: BL_OPERATOR:0
230// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
231 int (^c)() = ^{
232 return s.flag;
233 };
234 c();
235}
236
237// Test3 bitfield in cpatured aggregate.
238void bf3() {
239
240 struct {
241 unsigned short _reserved : 16;
242
243 unsigned char _draggedNodesAreDeletable: 1;
244 unsigned char _draggedOutsideOutlineView : 1;
245 unsigned char _adapterRespondsTo_addRootPaths : 1;
246 unsigned char _adapterRespondsTo_moveDataNodes : 1;
247 unsigned char _adapterRespondsTo_removeRootDataNode : 1;
248 unsigned char _adapterRespondsTo_doubleClickDataNode : 1;
249 unsigned char _adapterRespondsTo_selectDataNode : 1;
250 unsigned char _adapterRespondsTo_textDidEndEditing : 1;
251 unsigned char _adapterRespondsTo_updateAndSaveRoots : 1;
252 unsigned char _adapterRespondsTo_askToDeleteRootNodes : 1;
253 unsigned char _adapterRespondsTo_contextMenuForSelectedNodes : 1;
254 unsigned char _adapterRespondsTo_pasteboardFilenamesForNodes : 1;
255 unsigned char _adapterRespondsTo_writeItemsToPasteboard : 1;
256 unsigned char _adapterRespondsTo_writeItemsToPasteboardXXXX : 1;
257
258 unsigned int _filler : 32;
259 } _flags;
260
261// block variable layout: BL_OPERATOR:0
262// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
263 unsigned char (^c)() = ^{
264 return _flags._draggedNodesAreDeletable;
265 };
266
267 c();
268}
269
270// Test4 unnamed bitfield
271void bf4() {
272
273 struct {
274 unsigned short _reserved : 16;
275
276 unsigned char _draggedNodesAreDeletable: 1;
277 unsigned char _draggedOutsideOutlineView : 1;
278 unsigned char _adapterRespondsTo_addRootPaths : 1;
279 unsigned char _adapterRespondsTo_moveDataNodes : 1;
280 unsigned char _adapterRespondsTo_removeRootDataNode : 1;
281 unsigned char _adapterRespondsTo_doubleClickDataNode : 1;
282 unsigned char _adapterRespondsTo_selectDataNode : 1;
283 unsigned char _adapterRespondsTo_textDidEndEditing : 1;
284
285 unsigned long long : 64;
286
287 unsigned char _adapterRespondsTo_updateAndSaveRoots : 1;
288 unsigned char _adapterRespondsTo_askToDeleteRootNodes : 1;
289 unsigned char _adapterRespondsTo_contextMenuForSelectedNodes : 1;
290 unsigned char _adapterRespondsTo_pasteboardFilenamesForNodes : 1;
291 unsigned char _adapterRespondsTo_writeItemsToPasteboard : 1;
292 unsigned char _adapterRespondsTo_writeItemsToPasteboardXXXX : 1;
293
294 unsigned int _filler : 32;
295 } _flags;
296
297// block variable layout: BL_OPERATOR:0
298// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
299 unsigned char (^c)() = ^{
300 return _flags._draggedNodesAreDeletable;
301 };
302
303 c();
304}
305
306
307
308// Test5 unnamed bitfield.
309void bf5() {
310 struct {
311 unsigned char flag : 1;
312 unsigned int : 32;
313 unsigned char flag1 : 1;
314 } _flags;
315
316// block variable layout: BL_OPERATOR:0
317// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
318 unsigned char (^c)() = ^{
319 return _flags.flag;
320 };
321
322 c();
323}
324
325
326// Test6 0 length bitfield.
327void bf6() {
328 struct {
329 unsigned char flag : 1;
330 unsigned int : 0;
331 unsigned char flag1 : 1;
332 } _flags;
333
334// block variable layout: BL_OPERATOR:0
335// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [1 x i8] zeroinitializer
336 unsigned char (^c)() = ^{
337 return _flags.flag;
338 };
339
340 c();
341}
342
343// Test7 large number of captured variables.
344void Test7() {
345 __weak id wid;
346 __weak id wid1, wid2, wid3, wid4;
347 __weak id wid5, wid6, wid7, wid8;
348 __weak id wid9, wid10, wid11, wid12;
349 __weak id wid13, wid14, wid15, wid16;
350 const id bar = (id) opaque_id();
351//block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
352// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"0_\00"
353 void (^b)() = ^{
354 x(bar);
355 x(wid1);
356 x(wid2);
357 x(wid3);
358 x(wid4);
359 x(wid5);
360 x(wid6);
361 x(wid7);
362 x(wid8);
363 x(wid9);
364 x(wid10);
365 x(wid11);
366 x(wid12);
367 x(wid13);
368 x(wid14);
369 x(wid15);
370 x(wid16);
371 };
372}
373
374
375// Test 8 very large number of captured variables.
376void Test8() {
377__weak id wid;
378 __weak id wid1, wid2, wid3, wid4;
379 __weak id wid5, wid6, wid7, wid8;
380 __weak id wid9, wid10, wid11, wid12;
381 __weak id wid13, wid14, wid15, wid16;
382 __weak id w1, w2, w3, w4;
383 __weak id w5, w6, w7, w8;
384 __weak id w9, w10, w11, w12;
385 __weak id w13, w14, w15, w16;
386 const id bar = (id) opaque_id();
387// block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
388// CHECK: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8]
389 void (^b)() = ^{
390 x(bar);
391 x(wid1);
392 x(wid2);
393 x(wid3);
394 x(wid4);
395 x(wid5);
396 x(wid6);
397 x(wid7);
398 x(wid8);
399 x(wid9);
400 x(wid10);
401 x(wid11);
402 x(wid12);
403 x(wid13);
404 x(wid14);
405 x(wid15);
406 x(wid16);
407 x(w1);
408 x(w2);
409 x(w3);
410 x(w4);
411 x(w5);
412 x(w6);
413 x(w7);
414 x(w8);
415 x(w9);
416 x(w10);
417 x(w11);
418 x(w12);
419 x(w13);
420 x(w14);
421 x(w15);
422 x(w16);
423 x(wid);
424 };
425}