blob: 42e6060dcc25decf3220f35f52a8515f52be80ec [file] [log] [blame]
Rafael Espindolaa3f55b02013-09-04 04:12:25 +00001// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
Tim Northover931a4fe2013-08-12 12:51:05 +00002// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.layout %s
Fariborz Jahanianf22ae652012-11-01 18:32:55 +00003// rdar://12184410
Fariborz Jahanian90a2d392013-01-17 00:25:06 +00004// rdar://12752901
Fariborz Jahanianf22ae652012-11-01 18:32:55 +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// Inline instruction for block variable layout: 0x0320 (3 strong 2 byref)
37// CHECK-LP64: Inline instruction for block variable layout: 0x0320
Fariborz Jahanianf22ae652012-11-01 18:32:55 +000038 void (^b)() = ^{
39 byref_int = sh + ch+ch1+ch2 ;
40 x(bar);
41 x(baz);
42 x((id)strong_void_sta);
43 x(byref_bab);
44 };
45 b();
46
47// Test 2
Fariborz Jahanian90a2d392013-01-17 00:25:06 +000048// Inline instruction for block variable layout: 0x0331 (3 strong 3 byref 1 weak)
49// CHECK-LP64: Inline instruction for block variable layout: 0x0331
Fariborz Jahanianf22ae652012-11-01 18:32:55 +000050 void (^c)() = ^{
51 byref_int = sh + ch+ch1+ch2 ;
52 x(bar);
53 x(baz);
54 x((id)strong_void_sta);
55 x(wid);
56 bl_var1 = 0;
57 x(byref_bab);
58 };
59}
60
61@class NSString, NSNumber;
62void g() {
63 NSString *foo;
64 NSNumber *bar;
65 unsigned int bletch;
66 __weak id weak_delegate;
67 unsigned int i;
68 NSString *y;
69 NSString *z;
Fariborz Jahanian90a2d392013-01-17 00:25:06 +000070// Inline instruction for block variable layout: 0x0401 (4 strong 0 byref 1 weak)
71// CHECK-LP64: Inline instruction for block variable layout: 0x0401
Fariborz Jahanianf22ae652012-11-01 18:32:55 +000072 void (^c)() = ^{
73 int j = i + bletch;
74 x(foo);
75 x(bar);
76 x(weak_delegate);
77 x(y);
78 x(z);
79 };
80 c();
81}
82
83// Test 5 (unions/structs and their nesting):
84void h() {
85 struct S5 {
86 int i1;
87 __unsafe_unretained id o1;
88 struct V {
89 int i2;
90 __unsafe_unretained id o2;
91 } v1;
92 int i3;
93 union UI {
94 void * i1;
95 __unsafe_unretained id o1;
96 int i3;
97 __unsafe_unretained id o3;
98 }ui;
99 };
100
101 union U {
102 void * i1;
103 __unsafe_unretained id o1;
104 int i3;
105 __unsafe_unretained id o3;
106 }ui;
107
108 struct S5 s2;
109 union U u2;
110 __block id block_id;
111
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000112// CHECK-LP64: 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 Jahanianf22ae652012-11-01 18:32:55 +0000113 void (^c)() = ^{
114 x(s2.ui.o1);
115 x(u2.o1);
116 block_id = 0;
117 };
118 c();
119}
120
121// Test for array of stuff.
122void arr1() {
123 struct S {
124 __unsafe_unretained id unsafe_unretained_var[4];
125 } imported_s;
126
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000127// CHECK-LP64: block variable layout: BL_UNRETAINED:4, BL_OPERATOR:0
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000128 void (^c)() = ^{
129 x(imported_s.unsafe_unretained_var[2]);
130 };
131
132 c();
133}
134
135// Test2 for array of stuff.
136void arr2() {
137 struct S {
138 int a;
139 __unsafe_unretained id unsafe_unretained_var[4];
140 } imported_s;
141
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000142// CHECK-LP64: block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINED:4, BL_OPERATOR:0
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000143 void (^c)() = ^{
144 x(imported_s.unsafe_unretained_var[2]);
145 };
146
147 c();
148}
149
150// Test3 for array of stuff.
151void arr3() {
152 struct S {
153 int a;
154 __unsafe_unretained id unsafe_unretained_var[0];
155 } imported_s;
156
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000157// CHECK-LP64: block variable layout: BL_OPERATOR:0
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000158 void (^c)() = ^{
159 int i = imported_s.a;
160 };
161
162 c();
163}
164
165
166// Test4 for array of stuff.
167@class B;
168void arr4() {
169 struct S {
170 struct s0 {
171 __unsafe_unretained id s_f0;
172 __unsafe_unretained id s_f1;
173 } f0;
174
175 __unsafe_unretained id f1;
176
177 struct s1 {
178 int *f0;
179 __unsafe_unretained B *f1;
180 } f4[2][2];
181 } captured_s;
182
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000183// CHECK-LP64: 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 Jahanianf22ae652012-11-01 18:32:55 +0000184 void (^c)() = ^{
185 id i = captured_s.f0.s_f1;
186 };
187
188 c();
189}
190
191// Test1 bitfield in cpatured aggregate.
192void bf1() {
193 struct S {
194 int flag : 25;
195 int flag1: 7;
196 int flag2 :1;
197 int flag3: 7;
198 int flag4: 24;
199 } s;
200
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000201// CHECK-LP64: block variable layout: BL_OPERATOR:0
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000202 int (^c)() = ^{
203 return s.flag;
204 };
205 c();
206}
207
208// Test2 bitfield in cpatured aggregate.
209void bf2() {
210 struct S {
211 int flag : 1;
212 } s;
213
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000214// CHECK-LP64: block variable layout: BL_OPERATOR:0
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000215 int (^c)() = ^{
216 return s.flag;
217 };
218 c();
219}
220
221// Test3 bitfield in cpatured aggregate.
222void bf3() {
223
224 struct {
225 unsigned short _reserved : 16;
226
227 unsigned char _draggedNodesAreDeletable: 1;
228 unsigned char _draggedOutsideOutlineView : 1;
229 unsigned char _adapterRespondsTo_addRootPaths : 1;
230 unsigned char _adapterRespondsTo_moveDataNodes : 1;
231 unsigned char _adapterRespondsTo_removeRootDataNode : 1;
232 unsigned char _adapterRespondsTo_doubleClickDataNode : 1;
233 unsigned char _adapterRespondsTo_selectDataNode : 1;
234 unsigned char _adapterRespondsTo_textDidEndEditing : 1;
235 unsigned char _adapterRespondsTo_updateAndSaveRoots : 1;
236 unsigned char _adapterRespondsTo_askToDeleteRootNodes : 1;
237 unsigned char _adapterRespondsTo_contextMenuForSelectedNodes : 1;
238 unsigned char _adapterRespondsTo_pasteboardFilenamesForNodes : 1;
239 unsigned char _adapterRespondsTo_writeItemsToPasteboard : 1;
240 unsigned char _adapterRespondsTo_writeItemsToPasteboardXXXX : 1;
241
242 unsigned int _filler : 32;
243 } _flags;
244
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000245// CHECK-LP64: block variable layout: BL_OPERATOR:0
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000246 unsigned char (^c)() = ^{
247 return _flags._draggedNodesAreDeletable;
248 };
249
250 c();
251}
252
253// Test4 unnamed bitfield
254void bf4() {
255
256 struct {
257 unsigned short _reserved : 16;
258
259 unsigned char _draggedNodesAreDeletable: 1;
260 unsigned char _draggedOutsideOutlineView : 1;
261 unsigned char _adapterRespondsTo_addRootPaths : 1;
262 unsigned char _adapterRespondsTo_moveDataNodes : 1;
263 unsigned char _adapterRespondsTo_removeRootDataNode : 1;
264 unsigned char _adapterRespondsTo_doubleClickDataNode : 1;
265 unsigned char _adapterRespondsTo_selectDataNode : 1;
266 unsigned char _adapterRespondsTo_textDidEndEditing : 1;
267
268 unsigned long long : 64;
269
270 unsigned char _adapterRespondsTo_updateAndSaveRoots : 1;
271 unsigned char _adapterRespondsTo_askToDeleteRootNodes : 1;
272 unsigned char _adapterRespondsTo_contextMenuForSelectedNodes : 1;
273 unsigned char _adapterRespondsTo_pasteboardFilenamesForNodes : 1;
274 unsigned char _adapterRespondsTo_writeItemsToPasteboard : 1;
275 unsigned char _adapterRespondsTo_writeItemsToPasteboardXXXX : 1;
276
277 unsigned int _filler : 32;
278 } _flags;
279
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000280// CHECK-LP64: block variable layout: BL_OPERATOR:0
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000281 unsigned char (^c)() = ^{
282 return _flags._draggedNodesAreDeletable;
283 };
284
285 c();
286}
287
288
289
290// Test5 unnamed bitfield.
291void bf5() {
292 struct {
293 unsigned char flag : 1;
294 unsigned int : 32;
295 unsigned char flag1 : 1;
296 } _flags;
297
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000298// CHECK-LP64: block variable layout: BL_OPERATOR:0
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000299 unsigned char (^c)() = ^{
300 return _flags.flag;
301 };
302
303 c();
304}
305
306
307// Test6 0 length bitfield.
308void bf6() {
309 struct {
310 unsigned char flag : 1;
311 unsigned int : 0;
312 unsigned char flag1 : 1;
313 } _flags;
314
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000315// CHECK-LP64: block variable layout: BL_OPERATOR:0
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000316 unsigned char (^c)() = ^{
317 return _flags.flag;
318 };
319
320 c();
321}
322
323// Test7 large number of captured variables.
324void Test7() {
325 __weak id wid;
326 __weak id wid1, wid2, wid3, wid4;
327 __weak id wid5, wid6, wid7, wid8;
328 __weak id wid9, wid10, wid11, wid12;
329 __weak id wid13, wid14, wid15, wid16;
330 const id bar = (id) opaque_id();
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000331// CHECK-LP64: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000332 void (^b)() = ^{
333 x(bar);
334 x(wid1);
335 x(wid2);
336 x(wid3);
337 x(wid4);
338 x(wid5);
339 x(wid6);
340 x(wid7);
341 x(wid8);
342 x(wid9);
343 x(wid10);
344 x(wid11);
345 x(wid12);
346 x(wid13);
347 x(wid14);
348 x(wid15);
349 x(wid16);
350 };
351}
352
353
354// Test 8 very large number of captured variables.
355void Test8() {
356__weak id wid;
357 __weak id wid1, wid2, wid3, wid4;
358 __weak id wid5, wid6, wid7, wid8;
359 __weak id wid9, wid10, wid11, wid12;
360 __weak id wid13, wid14, wid15, wid16;
361 __weak id w1, w2, w3, w4;
362 __weak id w5, w6, w7, w8;
363 __weak id w9, w10, w11, w12;
364 __weak id w13, w14, w15, w16;
365 const id bar = (id) opaque_id();
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000366// CHECK-LP64: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
Fariborz Jahanianf22ae652012-11-01 18:32:55 +0000367 void (^b)() = ^{
368 x(bar);
369 x(wid1);
370 x(wid2);
371 x(wid3);
372 x(wid4);
373 x(wid5);
374 x(wid6);
375 x(wid7);
376 x(wid8);
377 x(wid9);
378 x(wid10);
379 x(wid11);
380 x(wid12);
381 x(wid13);
382 x(wid14);
383 x(wid15);
384 x(wid16);
385 x(w1);
386 x(w2);
387 x(w3);
388 x(w4);
389 x(w5);
390 x(w6);
391 x(w7);
392 x(w8);
393 x(w9);
394 x(w10);
395 x(w11);
396 x(w12);
397 x(w13);
398 x(w14);
399 x(w15);
400 x(w16);
401 x(wid);
402 };
403}