[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / CodeGenObjC / arc-captured-32bit-block-var-layout.m
blob9531ab894a5ebdda1853bf510ee2b2e4f33abf24
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
4 void x(id y) {}
5 void y(int a) {}
7 extern id opaque_id(void);
9 void f(void) {
10     __weak id wid;
11     __block int byref_int = 0;
12     char ch = 'a';
13     char ch1 = 'b';
14     char ch2 = 'c';
15     short sh = 2;
16     const id bar = (id) opaque_id();
17     id baz = 0;
18     __strong id strong_void_sta;
19     __block id byref_bab = (id)0;
20     __block id bl_var1;
21     int i; double dob;
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.
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).
33 // Test 1
34 // CHECK: Inline block variable layout: 0x0320, BL_STRONG:3, BL_BYREF:2, BL_OPERATOR:0
35     void (^b)(void) = ^{
36         byref_int = sh + ch+ch1+ch2 ;
37         x(bar);
38         x(baz);
39         x((id)strong_void_sta);
40         x(byref_bab);
41     };    
42     b();
44 // Test 2
45 // CHECK: Inline block variable layout: 0x0331, BL_STRONG:3, BL_BYREF:3, BL_WEAK:1, BL_OPERATOR:0
46     void (^c)(void) = ^{
47         byref_int = sh + ch+ch1+ch2 ;
48         x(bar);
49         x(baz);
50         x((id)strong_void_sta);
51         x(wid);
52         bl_var1 = 0;
53         x(byref_bab);
54     };    
57 @class NSString, NSNumber;
58 void g(void) {
59   NSString *foo;
60    NSNumber *bar;
61    unsigned int bletch;
62    __weak id weak_delegate;
63   unsigned int i;
64   NSString *y;
65   NSString *z;
66 // CHECK: Inline block variable layout: 0x0401, BL_STRONG:4, BL_WEAK:1, BL_OPERATOR:0
67   void (^c)(void) = ^{
68    int j = i + bletch;
69    x(foo);
70    x(bar);
71    x(weak_delegate);
72    x(y);
73    x(z); 
74   };
75   c();
78 // Test 5 (unions/structs and their nesting):
79 void h(void) {
80   struct S5 {
81     int i1;
82     __unsafe_unretained id o1;
83     struct V {
84      int i2;
85      __unsafe_unretained id o2;
86     } v1;
87     int i3;
88     union UI {
89         void * i1;
90         __unsafe_unretained id o1;
91         int i3;
92         __unsafe_unretained id o3;
93     }ui;
94   };
96   union U {
97         void * i1;
98         __unsafe_unretained id o1;
99         int i3;
100         __unsafe_unretained id o3;
101   }ui;
103   struct S5 s2;
104   union U u2;
105   __block id block_id;
108 block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINE:1, BL_NON_OBJECT_WORD:1, 
109                        BL_UNRETAINE:1, BL_NON_OBJECT_WORD:3, BL_BYREF:1, BL_OPERATOR:0
111 // 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
112   void (^c)(void) = ^{
113     x(s2.ui.o1);
114     x(u2.o1);
115     block_id = 0;
116   };
117   c();
120 // Test for array of stuff.
121 void arr1(void) {
122   struct S {
123     __unsafe_unretained id unsafe_unretained_var[4];
124  } imported_s;
126 // CHECK: Block variable layout: BL_UNRETAINED:4, BL_OPERATOR:0
127     void (^c)(void) = ^{
128         x(imported_s.unsafe_unretained_var[2]);
129     };    
131    c();
134 // Test2 for array of stuff.
135 void arr2(void) {
136   struct S {
137    int a;
138     __unsafe_unretained id unsafe_unretained_var[4];
139  } imported_s;
141 // CHECK: Block variable layout: BL_NON_OBJECT_WORD:1, BL_UNRETAINED:4, BL_OPERATOR:0
142     void (^c)(void) = ^{
143         x(imported_s.unsafe_unretained_var[2]);
144     };    
146    c();
149 // Test3 for array of stuff.
150 void arr3(void) {
151   struct S {
152    int a;
153     __unsafe_unretained id unsafe_unretained_var[0];
154  } imported_s;
156 // CHECK: Block variable layout: BL_OPERATOR:0
157     void (^c)(void) = ^{
158       int i = imported_s.a;
159     };    
161    c();
165 // Test4 for array of stuff.
166 @class B;
167 void arr4(void) {
168   struct S {
169     struct s0 {
170       __unsafe_unretained id s_f0;
171       __unsafe_unretained id s_f1;
172     } f0;
174     __unsafe_unretained id f1;
176     struct s1 {
177       int *f0;
178       __unsafe_unretained B *f1;
179     } f4[2][2];
180   } captured_s;
182 // 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
183   void (^c)(void) = ^{
184       id i = captured_s.f0.s_f1;
185   };
187    c();
190 // Test1 bitfield in cpatured aggregate.
191 void bf1(void) {
192   struct S {
193     int flag : 25;
194     int flag1: 7;
195     int flag2 :1;
196     int flag3: 7;
197     int flag4: 24;
198   } s;
200 // CHECK:  Block variable layout: BL_OPERATOR:0
201   int (^c)(void) = ^{
202       return s.flag;
203   };
204   c();
207 // Test2 bitfield in cpatured aggregate.
208 void bf2(void) {
209   struct S {
210     int flag : 1;
211   } s;
213 // CHECK: Block variable layout: BL_OPERATOR:0
214   int (^c)(void) = ^{
215       return s.flag;
216   };
217   c();
220 // Test3 bitfield in cpatured aggregate.
221 void bf3(void) {
223      struct {
224         unsigned short _reserved : 16;
226         unsigned char _draggedNodesAreDeletable: 1;
227         unsigned char _draggedOutsideOutlineView : 1;
228         unsigned char _adapterRespondsTo_addRootPaths : 1;
229         unsigned char _adapterRespondsTo_moveDataNodes : 1;
230         unsigned char _adapterRespondsTo_removeRootDataNode : 1;
231         unsigned char _adapterRespondsTo_doubleClickDataNode : 1;
232         unsigned char _adapterRespondsTo_selectDataNode : 1;
233         unsigned char _adapterRespondsTo_textDidEndEditing : 1;
234         unsigned char _adapterRespondsTo_updateAndSaveRoots : 1;
235         unsigned char _adapterRespondsTo_askToDeleteRootNodes : 1;
236         unsigned char _adapterRespondsTo_contextMenuForSelectedNodes : 1;
237         unsigned char _adapterRespondsTo_pasteboardFilenamesForNodes : 1;
238         unsigned char _adapterRespondsTo_writeItemsToPasteboard : 1;
239         unsigned char _adapterRespondsTo_writeItemsToPasteboardXXXX : 1;
241         unsigned int _filler : 32;
242     } _flags;
244 // CHECK: Block variable layout: BL_OPERATOR:0
245   unsigned char (^c)(void) = ^{
246       return _flags._draggedNodesAreDeletable;
247   };
249    c();
252 // Test4 unnamed bitfield
253 void bf4(void) {
255      struct {
256         unsigned short _reserved : 16;
258         unsigned char _draggedNodesAreDeletable: 1;
259         unsigned char _draggedOutsideOutlineView : 1;
260         unsigned char _adapterRespondsTo_addRootPaths : 1;
261         unsigned char _adapterRespondsTo_moveDataNodes : 1;
262         unsigned char _adapterRespondsTo_removeRootDataNode : 1;
263         unsigned char _adapterRespondsTo_doubleClickDataNode : 1;
264         unsigned char _adapterRespondsTo_selectDataNode : 1;
265         unsigned char _adapterRespondsTo_textDidEndEditing : 1;
267         unsigned long long : 64;
269         unsigned char _adapterRespondsTo_updateAndSaveRoots : 1;
270         unsigned char _adapterRespondsTo_askToDeleteRootNodes : 1;
271         unsigned char _adapterRespondsTo_contextMenuForSelectedNodes : 1;
272         unsigned char _adapterRespondsTo_pasteboardFilenamesForNodes : 1;
273         unsigned char _adapterRespondsTo_writeItemsToPasteboard : 1;
274         unsigned char _adapterRespondsTo_writeItemsToPasteboardXXXX : 1;
276         unsigned int _filler : 32;
277     } _flags;
279 // CHECK:  Block variable layout: BL_OPERATOR:0
280   unsigned char (^c)(void) = ^{
281       return _flags._draggedNodesAreDeletable;
282   };
284    c();
289 // Test5 unnamed bitfield.
290 void bf5(void) {
291      struct {
292         unsigned char flag : 1;
293         unsigned int  : 32;
294         unsigned char flag1 : 1;
295     } _flags;
297 // CHECK:  Block variable layout: BL_OPERATOR:0
298   unsigned char (^c)(void) = ^{
299       return _flags.flag;
300   };
302    c();
306 // Test6 0 length bitfield.
307 void bf6(void) {
308      struct {
309         unsigned char flag : 1;
310         unsigned int  : 0;
311         unsigned char flag1 : 1;
312     } _flags;
314 // CHECK: Block variable layout: BL_OPERATOR:0
315   unsigned char (^c)(void) = ^{
316       return _flags.flag;
317   };
319    c();
322 // Test7 large number of captured variables.
323 void Test7(void) {
324     __weak id wid;
325     __weak id wid1, wid2, wid3, wid4;
326     __weak id wid5, wid6, wid7, wid8;
327     __weak id wid9, wid10, wid11, wid12;
328     __weak id wid13, wid14, wid15, wid16;
329     const id bar = (id) opaque_id();
330 // CHECK: Block variable layout: BL_STRONG:1, BL_WEAK:16, BL_OPERATOR:0
331     void (^b)(void) = ^{
332       x(bar);
333       x(wid1);
334       x(wid2);
335       x(wid3);
336       x(wid4);
337       x(wid5);
338       x(wid6);
339       x(wid7);
340       x(wid8);
341       x(wid9);
342       x(wid10);
343       x(wid11);
344       x(wid12);
345       x(wid13);
346       x(wid14);
347       x(wid15);
348       x(wid16);
349     };    
353 // Test 8 very large number of captured variables.
354 void Test8(void) {
355 __weak id wid;
356     __weak id wid1, wid2, wid3, wid4;
357     __weak id wid5, wid6, wid7, wid8;
358     __weak id wid9, wid10, wid11, wid12;
359     __weak id wid13, wid14, wid15, wid16;
360     __weak id w1, w2, w3, w4;
361     __weak id w5, w6, w7, w8;
362     __weak id w9, w10, w11, w12;
363     __weak id w13, w14, w15, w16;
364     const id bar = (id) opaque_id();
365 // CHECK: Block variable layout: BL_STRONG:1, BL_WEAK:16, BL_WEAK:16, BL_WEAK:1, BL_OPERATOR:0
366     void (^b)(void) = ^{
367       x(bar);
368       x(wid1);
369       x(wid2);
370       x(wid3);
371       x(wid4);
372       x(wid5);
373       x(wid6);
374       x(wid7);
375       x(wid8);
376       x(wid9);
377       x(wid10);
378       x(wid11);
379       x(wid12);
380       x(wid13);
381       x(wid14);
382       x(wid15);
383       x(wid16);
384       x(w1);
385       x(w2);
386       x(w3);
387       x(w4);
388       x(w5);
389       x(w6);
390       x(w7);
391       x(w8);
392       x(w9);
393       x(w10);
394       x(w11);
395       x(w12);
396       x(w13);
397       x(w14);
398       x(w15);
399       x(w16);
400       x(wid);
401     };