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