xref: /minix3/external/bsd/llvm/dist/clang/test/CodeGenObjC/block-var-layout.m (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc// RUN: %clang_cc1 -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
2f4a2713aSLionel Sambuc// RUN: FileCheck -check-prefix CHECK-LP64 --input-file=%t-64.layout %s
3f4a2713aSLionel Sambuc// rdar://12752901
4f4a2713aSLionel Sambuc
5f4a2713aSLionel Sambucstruct S {
6f4a2713aSLionel Sambuc    int i1;
7f4a2713aSLionel Sambuc    id o1;
8f4a2713aSLionel Sambuc    struct V {
9f4a2713aSLionel Sambuc     int i2;
10f4a2713aSLionel Sambuc     id o2;
11f4a2713aSLionel Sambuc    } v1;
12f4a2713aSLionel Sambuc    int i3;
13f4a2713aSLionel Sambuc    id o3;
14f4a2713aSLionel Sambuc};
15f4a2713aSLionel Sambuc
16f4a2713aSLionel Sambuc__weak id wid;
17f4a2713aSLionel Sambucvoid x(id y) {}
18f4a2713aSLionel Sambucvoid y(int a) {}
19f4a2713aSLionel Sambuc
20f4a2713aSLionel Sambucextern id opaque_id();
21f4a2713aSLionel Sambuc
22f4a2713aSLionel Sambucvoid f() {
23f4a2713aSLionel Sambuc    __block int byref_int = 0;
24f4a2713aSLionel Sambuc    char ch = 'a';
25f4a2713aSLionel Sambuc    char ch1 = 'b';
26f4a2713aSLionel Sambuc    char ch2 = 'c';
27f4a2713aSLionel Sambuc    short sh = 2;
28f4a2713aSLionel Sambuc    const id bar = (id) opaque_id();
29f4a2713aSLionel Sambuc    id baz = 0;
30f4a2713aSLionel Sambuc    __strong void *strong_void_sta;
31f4a2713aSLionel Sambuc    __block id byref_bab = (id)0;
32f4a2713aSLionel Sambuc    __block void *bl_var1;
33f4a2713aSLionel Sambuc    int i; double dob;
34f4a2713aSLionel Sambuc
35f4a2713aSLionel Sambuc// The patterns here are a sequence of bytes, each saying first how
36f4a2713aSLionel Sambuc// many sizeof(void*) chunks to skip (high nibble) and then how many
37f4a2713aSLionel Sambuc// to scan (low nibble).  A zero byte says that we've reached the end
38f4a2713aSLionel Sambuc// of the pattern.
39f4a2713aSLionel Sambuc//
40f4a2713aSLionel Sambuc// All of these patterns start with 01 3x because the block header on
41f4a2713aSLionel Sambuc// LP64 consists of an isa pointer (which we're supposed to scan for
42f4a2713aSLionel Sambuc// some reason) followed by three words (2 ints, a function pointer,
43f4a2713aSLionel Sambuc// and a descriptor pointer).
44f4a2713aSLionel Sambuc
45f4a2713aSLionel Sambuc// FIXME: do these really have to be named L_OBJC_CLASS_NAME_xxx?
46f4a2713aSLionel Sambuc// FIXME: sequences should never end in x0 00 instead of just 00
47f4a2713aSLionel Sambuc
48f4a2713aSLionel Sambuc// Test 1
49f4a2713aSLionel Sambuc// byref int, short, char, char, char, id, id, strong void*, byref id
50f4a2713aSLionel Sambuc// CHECK-LP64: block variable layout for block: 0x01, 0x35, 0x10, 0x00
51f4a2713aSLionel Sambuc    void (^b)() = ^{
52f4a2713aSLionel Sambuc        byref_int = sh + ch+ch1+ch2 ;
53f4a2713aSLionel Sambuc        x(bar);
54f4a2713aSLionel Sambuc        x(baz);
55f4a2713aSLionel Sambuc        x((id)strong_void_sta);
56f4a2713aSLionel Sambuc        x(byref_bab);
57f4a2713aSLionel Sambuc    };
58f4a2713aSLionel Sambuc    b();
59f4a2713aSLionel Sambuc
60f4a2713aSLionel Sambuc// Test 2
61f4a2713aSLionel Sambuc// byref int, short, char, char, char, id, id, strong void*, byref void*, byref id
62f4a2713aSLionel Sambuc// 01 36 10 00
63f4a2713aSLionel Sambuc// CHECK-LP64: block variable layout for block: 0x01, 0x36, 0x10, 0x00
64f4a2713aSLionel Sambuc    void (^c)() = ^{
65f4a2713aSLionel Sambuc        byref_int = sh + ch+ch1+ch2 ;
66f4a2713aSLionel Sambuc        x(bar);
67f4a2713aSLionel Sambuc        x(baz);
68f4a2713aSLionel Sambuc        x((id)strong_void_sta);
69f4a2713aSLionel Sambuc        x(wid);
70f4a2713aSLionel Sambuc        bl_var1 = 0;
71f4a2713aSLionel Sambuc        x(byref_bab);
72f4a2713aSLionel Sambuc    };
73f4a2713aSLionel Sambuc    c();
74f4a2713aSLionel Sambuc
75f4a2713aSLionel Sambuc// Test 3
76f4a2713aSLionel Sambuc// byref int, short, char, char, char, id, id, byref void*, int, double, byref id
77f4a2713aSLionel Sambuc// 01 34 11 30 00
78f4a2713aSLionel Sambuc// FIXME: we'd get a better format here if we sorted by scannability, not just alignment
79f4a2713aSLionel Sambuc// CHECK-LP64: block variable layout for block: 0x01, 0x35, 0x30, 0x00
80f4a2713aSLionel Sambuc    void (^d)() = ^{
81f4a2713aSLionel Sambuc        byref_int = sh + ch+ch1+ch2 ;
82f4a2713aSLionel Sambuc        x(bar);
83f4a2713aSLionel Sambuc        x(baz);
84f4a2713aSLionel Sambuc        x(wid);
85f4a2713aSLionel Sambuc        bl_var1 = 0;
86f4a2713aSLionel Sambuc        y(i + dob);
87f4a2713aSLionel Sambuc        x(byref_bab);
88f4a2713aSLionel Sambuc    };
89f4a2713aSLionel Sambuc    d();
90f4a2713aSLionel Sambuc
91f4a2713aSLionel Sambuc// Test 4
92f4a2713aSLionel Sambuc// struct S (int, id, int, id, int, id)
93f4a2713aSLionel Sambuc// 01 41 11 11 00
94f4a2713aSLionel Sambuc// CHECK-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x11, 0x00
95f4a2713aSLionel Sambuc    struct S s2;
96f4a2713aSLionel Sambuc    void (^e)() = ^{
97f4a2713aSLionel Sambuc        x(s2.o1);
98f4a2713aSLionel Sambuc    };
99f4a2713aSLionel Sambuc    e();
100f4a2713aSLionel Sambuc}
101f4a2713aSLionel Sambuc
102f4a2713aSLionel Sambuc// Test 5 (unions/structs and their nesting):
103f4a2713aSLionel Sambucvoid Test5() {
104f4a2713aSLionel Sambuc  struct S5 {
105f4a2713aSLionel Sambuc    int i1;
106f4a2713aSLionel Sambuc    id o1;
107f4a2713aSLionel Sambuc    struct V {
108f4a2713aSLionel Sambuc     int i2;
109f4a2713aSLionel Sambuc     id o2;
110f4a2713aSLionel Sambuc    } v1;
111f4a2713aSLionel Sambuc    int i3;
112f4a2713aSLionel Sambuc    union UI {
113f4a2713aSLionel Sambuc        void * i1;
114f4a2713aSLionel Sambuc        id o1;
115f4a2713aSLionel Sambuc        int i3;
116f4a2713aSLionel Sambuc        id o3;
117f4a2713aSLionel Sambuc    }ui;
118f4a2713aSLionel Sambuc  };
119f4a2713aSLionel Sambuc
120f4a2713aSLionel Sambuc  union U {
121f4a2713aSLionel Sambuc        void * i1;
122f4a2713aSLionel Sambuc        id o1;
123f4a2713aSLionel Sambuc        int i3;
124f4a2713aSLionel Sambuc        id o3;
125f4a2713aSLionel Sambuc  }ui;
126f4a2713aSLionel Sambuc
127f4a2713aSLionel Sambuc  struct S5 s2;
128f4a2713aSLionel Sambuc  union U u2;
129f4a2713aSLionel Sambuc
130f4a2713aSLionel Sambuc// struct s2 (int, id, int, id, int, id?), union u2 (id?)
131f4a2713aSLionel Sambuc// 01 41 11 12 00
132f4a2713aSLionel Sambuc// CHECK-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x12, 0x00
133f4a2713aSLionel Sambuc  void (^c)() = ^{
134f4a2713aSLionel Sambuc    x(s2.ui.o1);
135f4a2713aSLionel Sambuc    x(u2.o1);
136f4a2713aSLionel Sambuc  };
137f4a2713aSLionel Sambuc  c();
138f4a2713aSLionel Sambuc}
139f4a2713aSLionel Sambuc
140f4a2713aSLionel Sambuc// rdar: //8417746
141f4a2713aSLionel Sambucvoid CFRelease(id);
142f4a2713aSLionel Sambucvoid notifyBlock(id dependentBlock) {
143f4a2713aSLionel Sambuc id singleObservationToken;
144f4a2713aSLionel Sambuc id token;
145f4a2713aSLionel Sambuc void (^b)();
146f4a2713aSLionel Sambuc
147f4a2713aSLionel Sambuc// id, id, void(^)()
148f4a2713aSLionel Sambuc// 01 33 00
149f4a2713aSLionel Sambuc// CHECK-LP64: block variable layout for block: 0x01, 0x33, 0x00
150f4a2713aSLionel Sambuc void (^wrapperBlock)() = ^() {
151f4a2713aSLionel Sambuc     CFRelease(singleObservationToken);
152f4a2713aSLionel Sambuc     CFRelease(singleObservationToken);
153f4a2713aSLionel Sambuc     CFRelease(token);
154f4a2713aSLionel Sambuc     CFRelease(singleObservationToken);
155f4a2713aSLionel Sambuc     b();
156f4a2713aSLionel Sambuc    };
157f4a2713aSLionel Sambuc wrapperBlock();
158f4a2713aSLionel Sambuc}
159f4a2713aSLionel Sambuc
160f4a2713aSLionel Sambucvoid test_empty_block() {
161f4a2713aSLionel Sambuc// 01 00
162f4a2713aSLionel Sambuc// CHECK-LP64: block variable layout for block: 0x01, 0x00
163f4a2713aSLionel Sambuc  void (^wrapperBlock)() = ^() {
164f4a2713aSLionel Sambuc  };
165f4a2713aSLionel Sambuc wrapperBlock();
166f4a2713aSLionel Sambuc}
167*0a6a1f1dSLionel Sambuc
168*0a6a1f1dSLionel Sambuc// rdar://16111839
169*0a6a1f1dSLionel Sambuctypedef union { char ch[8];  } SS;
170*0a6a1f1dSLionel Sambuctypedef struct { SS s[4]; } CS;
171*0a6a1f1dSLionel Sambucvoid test_union_in_layout() {
172*0a6a1f1dSLionel Sambuc  CS cs;
173*0a6a1f1dSLionel Sambuc  ^{ cs; };
174*0a6a1f1dSLionel Sambuc}
175