]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGenObjC/arc-captured-32bit-block-var-layout.m
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
[FreeBSD/FreeBSD.git] / test / CodeGenObjC / arc-captured-32bit-block-var-layout.m
1 // 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
2 // RUN: FileCheck --input-file=%t-32.layout %s
3 // rdar://12184410
4 // rdar://12752901
5
6 void x(id y) {}
7 void y(int a) {}
8
9 extern id opaque_id();
10
11 void 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
36 // CHECK: Inline instruction for block variable layout: 0x0320
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 // CHECK: Inline instruction for block variable layout: 0x0331
48     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;
60 void 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;
68 // CHECK: Inline instruction for block variable layout: 0x0401
69   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):
81 void 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 /**
110 block 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 */
113 // 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
114   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.
123 void arr1() {
124   struct S {
125     __unsafe_unretained id unsafe_unretained_var[4];
126  } imported_s;
127
128 // CHECK: block variable layout: BL_UNRETAINED:4, BL_OPERATOR:0
129     void (^c)() = ^{
130         x(imported_s.unsafe_unretained_var[2]);
131     };    
132
133    c();
134 }
135
136 // Test2 for array of stuff.
137 void arr2() {
138   struct S {
139    int a;
140     __unsafe_unretained id unsafe_unretained_var[4];
141  } imported_s;
142
143 // CHECK: block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINED:4, BL_OPERATOR:0
144     void (^c)() = ^{
145         x(imported_s.unsafe_unretained_var[2]);
146     };    
147
148    c();
149 }
150
151 // Test3 for array of stuff.
152 void arr3() {
153   struct S {
154    int a;
155     __unsafe_unretained id unsafe_unretained_var[0];
156  } imported_s;
157
158 // CHECK: block variable layout: BL_OPERATOR:0
159     void (^c)() = ^{
160       int i = imported_s.a;
161     };    
162
163    c();
164 }
165
166
167 // Test4 for array of stuff.
168 @class B;
169 void 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
184 // 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
185   void (^c)() = ^{
186       id i = captured_s.f0.s_f1;
187   };
188
189    c();
190 }
191
192 // Test1 bitfield in cpatured aggregate.
193 void 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
202 // CHECK:  block variable layout: BL_OPERATOR:0
203   int (^c)() = ^{
204       return s.flag;
205   };
206   c();
207 }
208
209 // Test2 bitfield in cpatured aggregate.
210 void bf2() {
211   struct S {
212     int flag : 1;
213   } s;
214
215 // CHECK: block variable layout: BL_OPERATOR:0
216   int (^c)() = ^{
217       return s.flag;
218   };
219   c();
220 }
221
222 // Test3 bitfield in cpatured aggregate.
223 void 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
246 // CHECK: block variable layout: BL_OPERATOR:0
247   unsigned char (^c)() = ^{
248       return _flags._draggedNodesAreDeletable;
249   };
250
251    c();
252 }
253
254 // Test4 unnamed bitfield
255 void 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
281 // CHECK:  block variable layout: BL_OPERATOR:0
282   unsigned char (^c)() = ^{
283       return _flags._draggedNodesAreDeletable;
284   };
285
286    c();
287 }
288
289
290
291 // Test5 unnamed bitfield.
292 void bf5() {
293      struct {
294         unsigned char flag : 1;
295         unsigned int  : 32;
296         unsigned char flag1 : 1;
297     } _flags;
298
299 // CHECK:  block variable layout: BL_OPERATOR:0
300   unsigned char (^c)() = ^{
301       return _flags.flag;
302   };
303
304    c();
305 }
306
307
308 // Test6 0 length bitfield.
309 void bf6() {
310      struct {
311         unsigned char flag : 1;
312         unsigned int  : 0;
313         unsigned char flag1 : 1;
314     } _flags;
315
316 // CHECK: block variable layout: BL_OPERATOR:0
317   unsigned char (^c)() = ^{
318       return _flags.flag;
319   };
320
321    c();
322 }
323
324 // Test7 large number of captured variables.
325 void 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();
332 // CHECK: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
333     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.
356 void 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();
367 // CHECK: block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
368     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 }