blob: ab9523126c3df7ab324a0933501086135b5585d8 [file] [log] [blame]
Fariborz Jahanian90a2d392013-01-17 00:25:06 +00001// RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -fobjc-runtime=macosx-fragile-10.5 -O0 -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
2// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.layout %s
3// rdar://12752901
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +00004
Fariborz Jahaniane1a48982010-08-05 21:00:25 +00005struct S {
6 int i1;
7 id o1;
8 struct V {
9 int i2;
10 id o2;
11 } v1;
12 int i3;
13 id o3;
14};
15
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +000016__weak id wid;
17void x(id y) {}
18void y(int a) {}
19
John McCall6b5a61b2011-02-07 10:33:21 +000020extern id opaque_id();
21
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +000022void f() {
23 __block int byref_int = 0;
24 char ch = 'a';
25 char ch1 = 'b';
26 char ch2 = 'c';
27 short sh = 2;
John McCall6b5a61b2011-02-07 10:33:21 +000028 const id bar = (id) opaque_id();
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +000029 id baz = 0;
30 __strong void *strong_void_sta;
31 __block id byref_bab = (id)0;
32 __block void *bl_var1;
33 int i; double dob;
34
John McCall6b5a61b2011-02-07 10:33:21 +000035// The patterns here are a sequence of bytes, each saying first how
36// many sizeof(void*) chunks to skip (high nibble) and then how many
37// to scan (low nibble). A zero byte says that we've reached the end
38// of the pattern.
39//
40// All of these patterns start with 01 3x because the block header on
41// LP64 consists of an isa pointer (which we're supposed to scan for
42// some reason) followed by three words (2 ints, a function pointer,
43// and a descriptor pointer).
44
45// FIXME: do these really have to be named L_OBJC_CLASS_NAME_xxx?
46// FIXME: sequences should never end in x0 00 instead of just 00
47
48// Test 1
49// byref int, short, char, char, char, id, id, strong void*, byref id
Fariborz Jahanian90a2d392013-01-17 00:25:06 +000050// CHECK-LP64: block variable layout for block: 0x01, 0x35, 0x10, 0x00
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +000051 void (^b)() = ^{
52 byref_int = sh + ch+ch1+ch2 ;
53 x(bar);
54 x(baz);
55 x((id)strong_void_sta);
56 x(byref_bab);
57 };
58 b();
59
60// Test 2
John McCall6b5a61b2011-02-07 10:33:21 +000061// byref int, short, char, char, char, id, id, strong void*, byref void*, byref id
62// 01 36 10 00
Fariborz Jahanian90a2d392013-01-17 00:25:06 +000063// CHECK-LP64: block variable layout for block: 0x01, 0x36, 0x10, 0x00
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +000064 void (^c)() = ^{
65 byref_int = sh + ch+ch1+ch2 ;
66 x(bar);
67 x(baz);
68 x((id)strong_void_sta);
69 x(wid);
70 bl_var1 = 0;
71 x(byref_bab);
72 };
73 c();
74
75// Test 3
John McCall6b5a61b2011-02-07 10:33:21 +000076// byref int, short, char, char, char, id, id, byref void*, int, double, byref id
77// 01 34 11 30 00
78// FIXME: we'd get a better format here if we sorted by scannability, not just alignment
Fariborz Jahanian90a2d392013-01-17 00:25:06 +000079// CHECK-LP64: block variable layout for block: 0x01, 0x35, 0x30, 0x00
John McCall6b5a61b2011-02-07 10:33:21 +000080 void (^d)() = ^{
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +000081 byref_int = sh + ch+ch1+ch2 ;
82 x(bar);
83 x(baz);
84 x(wid);
85 bl_var1 = 0;
86 y(i + dob);
87 x(byref_bab);
88 };
89 d();
Fariborz Jahaniane1a48982010-08-05 21:00:25 +000090
John McCall6b5a61b2011-02-07 10:33:21 +000091// Test 4
92// struct S (int, id, int, id, int, id)
Eli Friedmana2f9d212012-11-06 03:38:02 +000093// 01 41 11 11 00
Fariborz Jahanian90a2d392013-01-17 00:25:06 +000094// CHECK-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x11, 0x00
Fariborz Jahaniane1a48982010-08-05 21:00:25 +000095 struct S s2;
96 void (^e)() = ^{
97 x(s2.o1);
98 };
99 e();
Fariborz Jahanian93ce50d2010-08-04 23:55:24 +0000100}
101
Fariborz Jahaniana1f024c2010-08-06 16:28:55 +0000102// Test 5 (unions/structs and their nesting):
103void Test5() {
John McCall6b5a61b2011-02-07 10:33:21 +0000104 struct S5 {
Fariborz Jahaniana1f024c2010-08-06 16:28:55 +0000105 int i1;
106 id o1;
107 struct V {
108 int i2;
109 id o2;
110 } v1;
111 int i3;
112 union UI {
113 void * i1;
114 id o1;
115 int i3;
116 id o3;
117 }ui;
John McCall6b5a61b2011-02-07 10:33:21 +0000118 };
Fariborz Jahaniana1f024c2010-08-06 16:28:55 +0000119
John McCall6b5a61b2011-02-07 10:33:21 +0000120 union U {
Fariborz Jahaniana1f024c2010-08-06 16:28:55 +0000121 void * i1;
122 id o1;
123 int i3;
124 id o3;
John McCall6b5a61b2011-02-07 10:33:21 +0000125 }ui;
Fariborz Jahaniana1f024c2010-08-06 16:28:55 +0000126
John McCall6b5a61b2011-02-07 10:33:21 +0000127 struct S5 s2;
128 union U u2;
129
130// struct s2 (int, id, int, id, int, id?), union u2 (id?)
Eli Friedmana2f9d212012-11-06 03:38:02 +0000131// 01 41 11 12 00
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000132// CHECK-LP64: block variable layout for block: 0x01, 0x41, 0x11, 0x12, 0x00
John McCall6b5a61b2011-02-07 10:33:21 +0000133 void (^c)() = ^{
Fariborz Jahaniana1f024c2010-08-06 16:28:55 +0000134 x(s2.ui.o1);
135 x(u2.o1);
John McCall6b5a61b2011-02-07 10:33:21 +0000136 };
137 c();
Fariborz Jahaniana1f024c2010-08-06 16:28:55 +0000138}
139
Fariborz Jahanianc5904b42010-09-11 01:27:29 +0000140// rdar: //8417746
141void CFRelease(id);
142void notifyBlock(id dependentBlock) {
143 id singleObservationToken;
144 id token;
145 void (^b)();
John McCall6b5a61b2011-02-07 10:33:21 +0000146
147// id, id, void(^)()
148// 01 33 00
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000149// CHECK-LP64: block variable layout for block: 0x01, 0x33, 0x00
Fariborz Jahanianc5904b42010-09-11 01:27:29 +0000150 void (^wrapperBlock)() = ^() {
151 CFRelease(singleObservationToken);
152 CFRelease(singleObservationToken);
153 CFRelease(token);
154 CFRelease(singleObservationToken);
155 b();
156 };
157 wrapperBlock();
158}
159
Fariborz Jahanianfb550312010-09-13 16:09:44 +0000160void test_empty_block() {
John McCall6b5a61b2011-02-07 10:33:21 +0000161// 01 00
Fariborz Jahanian90a2d392013-01-17 00:25:06 +0000162// CHECK-LP64: block variable layout for block: 0x01, 0x00
John McCall6b5a61b2011-02-07 10:33:21 +0000163 void (^wrapperBlock)() = ^() {
164 };
Fariborz Jahanianfb550312010-09-13 16:09:44 +0000165 wrapperBlock();
166}