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