xref: /aosp_15_r20/external/clang/test/CodeGenObjCXX/block-var-layout.mm (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
2*67e74705SXin Li// RUN: FileCheck --input-file=%t-64.layout %s
3*67e74705SXin Li// rdar://12184410
4*67e74705SXin Li// rdar://12752901
5*67e74705SXin Li
6*67e74705SXin Li// See commentary in test/CodeGenObjC/block-var-layout.m, from which
7*67e74705SXin Li// this is largely cloned.
8*67e74705SXin Li
9*67e74705SXin Listruct S {
10*67e74705SXin Li    int i1;
11*67e74705SXin Li    id o1;
12*67e74705SXin Li    struct V {
13*67e74705SXin Li     int i2;
14*67e74705SXin Li     id o2;
15*67e74705SXin Li    } v1;
16*67e74705SXin Li    int i3;
17*67e74705SXin Li    id o3;
18*67e74705SXin Li};
19*67e74705SXin Li
20*67e74705SXin Li__weak id wid;
21*67e74705SXin Livoid x(id y) {}
22*67e74705SXin Livoid y(int a) {}
23*67e74705SXin Li
24*67e74705SXin Liextern id opaque_id();
25*67e74705SXin Li
26*67e74705SXin Livoid f() {
27*67e74705SXin Li    __block int byref_int = 0;
28*67e74705SXin Li    char ch = 'a';
29*67e74705SXin Li    char ch1 = 'b';
30*67e74705SXin Li    char ch2 = 'c';
31*67e74705SXin Li    short sh = 2;
32*67e74705SXin Li    const id bar = (id) opaque_id();
33*67e74705SXin Li    id baz = 0;
34*67e74705SXin Li    __strong void *strong_void_sta;
35*67e74705SXin Li    __block id byref_bab = (id)0;
36*67e74705SXin Li    __block void *bl_var1;
37*67e74705SXin Li    int i; double dob;
38*67e74705SXin Li
39*67e74705SXin Li// Test 1
40*67e74705SXin Li// byref int, short, char, char, char, id, id, strong void*, byref id
41*67e74705SXin Li// 01 35 10 00
42*67e74705SXin Li// CHECK: block variable layout for block: 0x01, 0x35, 0x10, 0x00
43*67e74705SXin Li    void (^b)() = ^{
44*67e74705SXin Li        byref_int = sh + ch+ch1+ch2 ;
45*67e74705SXin Li        x(bar);
46*67e74705SXin Li        x(baz);
47*67e74705SXin Li        x((id)strong_void_sta);
48*67e74705SXin Li        x(byref_bab);
49*67e74705SXin Li    };
50*67e74705SXin Li    b();
51*67e74705SXin Li
52*67e74705SXin Li// Test 2
53*67e74705SXin Li// byref int, short, char, char, char, id, id, strong void*, byref void*, byref id
54*67e74705SXin Li// 01 36 10 00
55*67e74705SXin Li// CHECK: 0x01, 0x36, 0x10, 0x00
56*67e74705SXin Li    void (^c)() = ^{
57*67e74705SXin Li        byref_int = sh + ch+ch1+ch2 ;
58*67e74705SXin Li        x(bar);
59*67e74705SXin Li        x(baz);
60*67e74705SXin Li        x((id)strong_void_sta);
61*67e74705SXin Li        x(wid);
62*67e74705SXin Li        bl_var1 = 0;
63*67e74705SXin Li        x(byref_bab);
64*67e74705SXin Li    };
65*67e74705SXin Li    c();
66*67e74705SXin Li
67*67e74705SXin Li// Test 3
68*67e74705SXin Li// byref int, short, char, char, char, id, id, byref void*, int, double, byref id
69*67e74705SXin Li// 01 34 11 30 00
70*67e74705SXin Li// CHECK: block variable layout for block: 0x01, 0x35, 0x30, 0x00
71*67e74705SXin Livoid (^d)() = ^{
72*67e74705SXin Li        byref_int = sh + ch+ch1+ch2 ;
73*67e74705SXin Li        x(bar);
74*67e74705SXin Li        x(baz);
75*67e74705SXin Li        x(wid);
76*67e74705SXin Li        bl_var1 = 0;
77*67e74705SXin Li        y(i + dob);
78*67e74705SXin Li        x(byref_bab);
79*67e74705SXin Li    };
80*67e74705SXin Li    d();
81*67e74705SXin Li
82*67e74705SXin Li// Test4
83*67e74705SXin Li// struct S (int, id, int, id, int, id)
84*67e74705SXin Li// 01 41 11 11 00
85*67e74705SXin Li// CHECK: block variable layout for block: 0x01, 0x41, 0x11, 0x11, 0x00
86*67e74705SXin Li    struct S s2;
87*67e74705SXin Li    void (^e)() = ^{
88*67e74705SXin Li        x(s2.o1);
89*67e74705SXin Li    };
90*67e74705SXin Li    e();
91*67e74705SXin Li}
92*67e74705SXin Li
93*67e74705SXin Li// Test 5 (unions/structs and their nesting):
94*67e74705SXin Livoid Test5() {
95*67e74705SXin Li  struct S5 {
96*67e74705SXin Li    int i1;
97*67e74705SXin Li    id o1;
98*67e74705SXin Li    struct V {
99*67e74705SXin Li     int i2;
100*67e74705SXin Li     id o2;
101*67e74705SXin Li    } v1;
102*67e74705SXin Li    int i3;
103*67e74705SXin Li    union UI {
104*67e74705SXin Li        void * i1;
105*67e74705SXin Li        id o1;
106*67e74705SXin Li        int i3;
107*67e74705SXin Li        id o3;
108*67e74705SXin Li    }ui;
109*67e74705SXin Li  };
110*67e74705SXin Li
111*67e74705SXin Li  union U {
112*67e74705SXin Li        void * i1;
113*67e74705SXin Li        id o1;
114*67e74705SXin Li        int i3;
115*67e74705SXin Li        id o3;
116*67e74705SXin Li  }ui;
117*67e74705SXin Li
118*67e74705SXin Li  struct S5 s2;
119*67e74705SXin Li  union U u2;
120*67e74705SXin Li
121*67e74705SXin Li// struct s2 (int, id, int, id, int, id?), union u2 (id?)
122*67e74705SXin Li// 01 41 11 12 00
123*67e74705SXin Li// CHECK: block variable layout for block: 0x01, 0x41, 0x11, 0x12, 0x00
124*67e74705SXin Li  void (^c)() = ^{
125*67e74705SXin Li    x(s2.ui.o1);
126*67e74705SXin Li    x(u2.o1);
127*67e74705SXin Li  };
128*67e74705SXin Li  c();
129*67e74705SXin Li
130*67e74705SXin Li}
131*67e74705SXin Li
132*67e74705SXin Li// rdar: //8417746
133*67e74705SXin Livoid CFRelease(id);
134*67e74705SXin Livoid notifyBlock(id dependentBlock) {
135*67e74705SXin Li id singleObservationToken;
136*67e74705SXin Li id token;
137*67e74705SXin Li void (^b)();
138*67e74705SXin Li
139*67e74705SXin Li// id, id, void(^)()
140*67e74705SXin Li// 01 33 00
141*67e74705SXin Li// CHECK: block variable layout for block: 0x01, 0x33, 0x00
142*67e74705SXin Li void (^wrapperBlock)() = ^() {
143*67e74705SXin Li     CFRelease(singleObservationToken);
144*67e74705SXin Li     CFRelease(singleObservationToken);
145*67e74705SXin Li     CFRelease(token);
146*67e74705SXin Li     CFRelease(singleObservationToken);
147*67e74705SXin Li     b();
148*67e74705SXin Li    };
149*67e74705SXin Li wrapperBlock();
150*67e74705SXin Li}
151*67e74705SXin Li
152*67e74705SXin Livoid test_empty_block() {
153*67e74705SXin Li// 01 00
154*67e74705SXin Li// CHECK: block variable layout for block: 0x01, 0x30, 0x00
155*67e74705SXin Li void (^wrapperBlock)() = ^() {
156*67e74705SXin Li    };
157*67e74705SXin Li wrapperBlock();
158*67e74705SXin Li}
159