]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/CodeGenObjC/block-var-layout.m
Vendor import of clang trunk r126079:
[FreeBSD/FreeBSD.git] / test / CodeGenObjC / block-var-layout.m
1 // RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -O0 -emit-llvm %s -o %t-64.s
2 // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s
3
4 struct S {
5     int i1;
6     id o1;
7     struct V {
8      int i2;
9      id o2;
10     } v1;
11     int i3;
12     id o3;
13 };
14
15 __weak id wid;
16 void x(id y) {}
17 void y(int a) {}
18
19 extern id opaque_id();
20
21 void f() {
22     __block int byref_int = 0;
23     char ch = 'a';
24     char ch1 = 'b';
25     char ch2 = 'c';
26     short sh = 2;
27     const id bar = (id) opaque_id();
28     id baz = 0;
29     __strong void *strong_void_sta;
30     __block id byref_bab = (id)0;
31     __block void *bl_var1;
32     int i; double dob;
33
34 // The patterns here are a sequence of bytes, each saying first how
35 // many sizeof(void*) chunks to skip (high nibble) and then how many
36 // to scan (low nibble).  A zero byte says that we've reached the end
37 // of the pattern.
38 //
39 // All of these patterns start with 01 3x because the block header on
40 // LP64 consists of an isa pointer (which we're supposed to scan for
41 // some reason) followed by three words (2 ints, a function pointer,
42 // and a descriptor pointer).
43
44 // FIXME: do these really have to be named L_OBJC_CLASS_NAME_xxx?
45 // FIXME: sequences should never end in x0 00 instead of just 00
46
47 // Test 1
48 // byref int, short, char, char, char, id, id, strong void*, byref id
49 // 01 35 10 00
50 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\015\10\00"
51     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
61 // byref int, short, char, char, char, id, id, strong void*, byref void*, byref id
62 // 01 36 10 00
63 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [4 x i8] c"\016\10\00"
64     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
76 // 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
79 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\014\11 \00"
80     void (^d)() = ^{
81         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();
90
91 // Test 4
92 // struct S (int, id, int, id, int, id)
93 // 01 41 11 11
94 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [5 x i8] c"\01A\11\11\00"
95     struct S s2;
96     void (^e)() = ^{
97         x(s2.o1);
98     };    
99     e();
100 }
101
102 // Test 5 (unions/structs and their nesting):
103 void Test5() {
104   struct S5 {
105     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;
118   };
119
120   union U {
121         void * i1;
122         id o1;
123         int i3;
124         id o3;
125   }ui;
126
127   struct S5 s2;
128   union U u2;
129
130 // struct s2 (int, id, int, id, int, id?), union u2 (id?)
131 // 01 41 11 12 70 00
132 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [6 x i8] c"\01A\11\12p\00"
133   void (^c)() = ^{
134     x(s2.ui.o1);
135     x(u2.o1);
136   };
137   c();
138 }
139
140 // rdar: //8417746
141 void CFRelease(id);
142 void notifyBlock(id dependentBlock) {
143  id singleObservationToken;
144  id token;
145  void (^b)();
146
147 // id, id, void(^)()
148 // 01 33 00
149 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\013\00"
150  void (^wrapperBlock)() = ^() {
151      CFRelease(singleObservationToken);
152      CFRelease(singleObservationToken);
153      CFRelease(token);
154      CFRelease(singleObservationToken);
155      b();
156     };
157  wrapperBlock();
158 }
159
160 void test_empty_block() {
161 // 01 00
162 // CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"\01\00"
163   void (^wrapperBlock)() = ^() {
164   };
165  wrapperBlock();
166 }