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