blob: 363e21497ec727a25ed57d79f776b63e09a505ba [file] [log] [blame]
John McCall6b5a61b2011-02-07 10:33:21 +00001// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -emit-llvm %s -o %t-64.ll
2// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.ll %s
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +00003
John McCall6b5a61b2011-02-07 10:33:21 +00004// See commentary in test/CodeGenObjC/block-var-layout.m, from which
5// this is largely cloned.
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +00006
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
John McCall6b5a61b2011-02-07 10:33:21 +000022extern id opaque_id();
23
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +000024void f() {
25 __block int byref_int = 0;
26 char ch = 'a';
27 char ch1 = 'b';
28 char ch2 = 'c';
29 short sh = 2;
John McCall6b5a61b2011-02-07 10:33:21 +000030 const id bar = (id) opaque_id();
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +000031 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
John McCall6b5a61b2011-02-07 10:33:21 +000037// Test 1
38// byref int, short, char, char, char, id, id, strong void*, byref id
39// 01 35 10 00
40// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\015\10\00"
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +000041 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
John McCall6b5a61b2011-02-07 10:33:21 +000051// byref int, short, char, char, char, id, id, strong void*, byref void*, byref id
52// 01 36 10 00
53// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\016\10\00"
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +000054 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
John McCall6b5a61b2011-02-07 10:33:21 +000066// byref int, short, char, char, char, id, id, byref void*, int, double, byref id
67// 01 34 11 30 00
68// FIXME: we'd get a better format here if we sorted by scannability, not just alignment
69// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\014\11 \00"
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +000070void (^d)() = ^{
71 byref_int = sh + ch+ch1+ch2 ;
72 x(bar);
73 x(baz);
74 x(wid);
75 bl_var1 = 0;
76 y(i + dob);
77 x(byref_bab);
78 };
79 d();
80
81// Test4
John McCall6b5a61b2011-02-07 10:33:21 +000082// struct S (int, id, int, id, int, id)
83// 01 41 11 11
84// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\11\00"
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +000085 struct S s2;
86 void (^e)() = ^{
87 x(s2.o1);
88 };
89 e();
90}
91
92// Test 5 (unions/structs and their nesting):
93void Test5() {
John McCall6b5a61b2011-02-07 10:33:21 +000094 struct S5 {
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +000095 int i1;
96 id o1;
97 struct V {
98 int i2;
99 id o2;
100 } v1;
101 int i3;
102 union UI {
103 void * i1;
104 id o1;
105 int i3;
106 id o3;
107 }ui;
John McCall6b5a61b2011-02-07 10:33:21 +0000108 };
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +0000109
John McCall6b5a61b2011-02-07 10:33:21 +0000110 union U {
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +0000111 void * i1;
112 id o1;
113 int i3;
114 id o3;
John McCall6b5a61b2011-02-07 10:33:21 +0000115 }ui;
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +0000116
John McCall6b5a61b2011-02-07 10:33:21 +0000117 struct S5 s2;
118 union U u2;
119
120// struct s2 (int, id, int, id, int, id?), union u2 (id?)
121// 01 41 11 12 70 00
122// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [6 x i8] c"\01A\11\12p\00"
123 void (^c)() = ^{
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +0000124 x(s2.ui.o1);
125 x(u2.o1);
John McCall6b5a61b2011-02-07 10:33:21 +0000126 };
127 c();
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +0000128
129}
130
131// rdar: //8417746
132void CFRelease(id);
133void notifyBlock(id dependentBlock) {
134 id singleObservationToken;
135 id token;
136 void (^b)();
John McCall6b5a61b2011-02-07 10:33:21 +0000137
138// id, id, void(^)()
139// 01 33 00
140// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\013\00"
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +0000141 void (^wrapperBlock)() = ^() {
142 CFRelease(singleObservationToken);
143 CFRelease(singleObservationToken);
144 CFRelease(token);
145 CFRelease(singleObservationToken);
146 b();
147 };
148 wrapperBlock();
149}
150
151void test_empty_block() {
John McCall6b5a61b2011-02-07 10:33:21 +0000152// 01 00
153// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"\01\00"
Fariborz Jahaniane27e9d62010-11-11 00:11:38 +0000154 void (^wrapperBlock)() = ^() {
155 };
156 wrapperBlock();
157}