• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// 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
3
4// See commentary in test/CodeGenObjC/block-var-layout.m, from which
5// this is largely cloned.
6
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
22extern id opaque_id();
23
24void f() {
25    __block int byref_int = 0;
26    char ch = 'a';
27    char ch1 = 'b';
28    char ch2 = 'c';
29    short sh = 2;
30    const id bar = (id) opaque_id();
31    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
37// 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"
41    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
51// 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"
54    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
66// 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"
70void (^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
82// 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"
85    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() {
94  struct S5 {
95    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;
108  };
109
110  union U {
111        void * i1;
112        id o1;
113        int i3;
114        id o3;
115  }ui;
116
117  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)() = ^{
124    x(s2.ui.o1);
125    x(u2.o1);
126  };
127  c();
128
129}
130
131// rdar: //8417746
132void CFRelease(id);
133void notifyBlock(id dependentBlock) {
134 id singleObservationToken;
135 id token;
136 void (^b)();
137
138// id, id, void(^)()
139// 01 33 00
140// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [3 x i8] c"\013\00"
141 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() {
152// 01 00
153// CHECK-LP64: @"\01L_OBJC_CLASS_NAME_{{.*}}" = internal global [2 x i8] c"\01\00"
154 void (^wrapperBlock)() = ^() {
155    };
156 wrapperBlock();
157}
158