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