1// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple x86_64-apple-darwin -print-ivar-layout -emit-llvm -o /dev/null %s > %t-64.layout
2// RUN: FileCheck -check-prefix=CHECK -check-prefix=CHECK-64 --input-file=%t-64.layout %s
3// RUN: %clang_cc1 -fblocks -fobjc-arc -fobjc-runtime-has-weak -triple i386-apple-darwin -print-ivar-layout -emit-llvm -o /dev/null  %s > %t-32.layout
4// RUN: FileCheck -check-prefix=CHECK -check-prefix=CHECK-32 --input-file=%t-32.layout %s
5// rdar://12184410
6
7void x(id y) {}
8void y(int a) {}
9
10extern id opaque_id();
11
12void f() {
13    __block int byref_int = 0;
14    const id bar = (id) opaque_id();
15    id baz = 0;
16    __strong id strong_void_sta;
17    __block id byref_bab = (id)0;
18    __block id bl_var1;
19
20// CHECK: Inline block variable layout: 0x0100, BL_STRONG:1, BL_OPERATOR:0
21    void (^b)() = ^{
22        x(bar);
23    };
24
25// CHECK: Inline block variable layout: 0x0210, BL_STRONG:2, BL_BYREF:1, BL_OPERATOR:0
26    void (^c)() = ^{
27        x(bar);
28        x(baz);
29        byref_int = 1;
30    };
31
32// CHECK: Inline block variable layout: 0x0230, BL_STRONG:2, BL_BYREF:3, BL_OPERATOR:0
33    void (^d)() = ^{
34        x(bar);
35        x(baz);
36        byref_int = 1;
37        bl_var1 = 0;
38        byref_bab = 0;
39    };
40
41// CHECK: Inline block variable layout: 0x0231, BL_STRONG:2, BL_BYREF:3, BL_WEAK:1, BL_OPERATOR:0
42    __weak id wid;
43    id (^e)() = ^{
44        x(bar);
45        x(baz);
46        byref_int = 1;
47        bl_var1 = 0;
48        byref_bab = 0;
49        return wid;
50    };
51
52// CHECK: Inline block variable layout: 0x0235, BL_STRONG:2, BL_BYREF:3, BL_WEAK:5, BL_OPERATOR:0
53    __weak id wid1, wid2, wid3, wid4;
54    id (^f)() = ^{
55        x(bar);
56        x(baz);
57        byref_int = 1;
58        bl_var1 = 0;
59        byref_bab = 0;
60        x(wid1);
61        x(wid2);
62        x(wid3);
63        x(wid4);
64        return wid;
65    };
66
67// CHECK: Inline block variable layout: 0x035, BL_BYREF:3, BL_WEAK:5, BL_OPERATOR:0
68    id (^g)() = ^{
69        byref_int = 1;
70        bl_var1 = 0;
71        byref_bab = 0;
72        x(wid1);
73        x(wid2);
74        x(wid3);
75        x(wid4);
76        return wid;
77    };
78
79// CHECK: Inline block variable layout: 0x01, BL_WEAK:1, BL_OPERATOR:0
80    id (^h)() = ^{
81        return wid;
82    };
83
84// CHECK: Inline block variable layout: 0x020, BL_BYREF:2, BL_OPERATOR:0
85    void (^ii)() = ^{
86       byref_int = 1;
87       byref_bab = 0;
88    };
89
90// CHECK: Inline block variable layout: 0x0102, BL_STRONG:1, BL_WEAK:2, BL_OPERATOR:0
91    void (^jj)() = ^{
92      x(bar);
93      x(wid1);
94      x(wid2);
95    };
96}
97
98// rdar://12752901
99@class NSString;
100extern void NSLog(NSString *format, ...);
101typedef void (^dispatch_block_t)(void);
102int main() {
103        __strong NSString *s1 = 0;
104        __strong NSString *s2 = 0;
105        __weak NSString *w1 = 0;
106
107
108// CHECK: Inline block variable layout: 0x0201, BL_STRONG:2, BL_WEAK:1, BL_OPERATOR:0
109        dispatch_block_t block2 = ^{
110                NSLog(@"%@, %@, %@", s1, w1, s2);
111        };
112}
113