blob: d8ec74692adfed4b96a5f0cccab4b56ef8cb8b9d [file] [log] [blame]
Ben Langmuir524387a2013-05-09 19:17:11 +00001// RUN: %clang_cc1 -fblocks -emit-llvm %s -o %t
2// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK1
3// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK2
4
5struct A {
6 int a;
7 float b;
8 char c;
9};
10
11void test_nest_captured_stmt(int param) {
12 int w;
13 // CHECK1: %struct.anon{{.*}} = type { i32*, i32* }
14 // CHECK1: %struct.anon{{.*}} = type { i32*, i32*, i32**, i32* }
15 // CHECK1: [[T:%struct.anon.*]] = type { i32*, i32*, %struct.A*, i32**, i32* }
16 #pragma clang __debug captured
17 {
18 int x;
19 int *y = &w;
20 #pragma clang __debug captured
21 {
22 struct A z;
23 #pragma clang __debug captured
24 {
25 w = x = z.a = 1;
26 *y = param;
27 z.b = 0.1f;
28 z.c = 'c';
29
30 // CHECK1: define internal void @__captured_stmt{{.*}}([[T]]
31 //
32 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 2
33 // CHECK1-NEXT: load %struct.A**
34 // CHECK1-NEXT: getelementptr inbounds %struct.A*
35 // CHECK1-NEXT: store i32 1
36 //
37 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 1
38 // CHECK1-NEXT: load i32**
39 // CHECK1-NEXT: store i32 1
40 //
41 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 0
42 // CHECK1-NEXT: load i32**
43 // CHECK1-NEXT: store i32 1
44 //
45 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 4
46 // CHECK1-NEXT: load i32**
47 // CHECK1-NEXT: load i32*
48 // CHECK1-NEXT: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 3
49 // CHECK1-NEXT: load i32***
50 // CHECK1-NEXT: load i32**
51 // CHECK1-NEXT: store i32
52 //
53 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 2
54 // CHECK1-NEXT: load %struct.A**
55 // CHECK1-NEXT: getelementptr inbounds %struct.A*
56 // CHECK1-NEXT: store float
57 //
58 // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 2
59 // CHECK1-NEXT: load %struct.A**
60 // CHECK1-NEXT: getelementptr inbounds %struct.A*
61 // CHECK1-NEXT: store i8 99
62 }
63 }
64 }
65}
66
67void test_nest_block() {
68 __block int x;
69 int y;
70 ^{
71 int z;
72 x = z;
73 #pragma clang __debug captured
74 {
75 z = y; // OK
76 }
77 }();
78
79 // CHECK2: define internal void @{{.*}}test_nest_block_block_invoke
80 //
81 // CHECK2: [[Z:%[0-9a-z_]*]] = alloca i32
82 // CHECK2: alloca %struct.anon{{.*}}
83 //
84 // CHECK2: store i32
85 // CHECK2: store i32* [[Z]]
86 //
87 // CHECK2: getelementptr inbounds %struct.anon
88 // CHECK2-NEXT: getelementptr inbounds
89 // CHECK2-NEXT: store i32*
90 //
91 // CHECK2: call void @__captured_stmt
92
93 int a;
94 #pragma clang __debug captured
95 {
96 __block int b;
97 int c;
98 __block int d;
99 ^{
100 b = a;
101 b = c;
102 b = d;
103 }();
104 }
105
106 // CHECK2: alloca %struct.__block_byref_b
107 // CHECK2-NEXT: [[C:%[0-9a-z_]*]] = alloca i32
108 // CHECK2-NEXT: alloca %struct.__block_byref_d
109 //
110 // CHECK2: bitcast %struct.__block_byref_b*
111 // CHECK2-NEXT: store i8*
112 //
113 // CHECK2: [[CapA:%[0-9a-z_.]*]] = getelementptr inbounds {{.*}}, i32 0, i32 7
114 //
115 // CHECK2: getelementptr inbounds %struct.anon{{.*}}, i32 0, i32 0
116 // CHECK2: load i32**
117 // CHECK2: load i32*
118 // CHECK2: store i32 {{.*}}, i32* [[CapA]]
119 //
120 // CHECK2: [[CapC:%[0-9a-z_.]*]] = getelementptr inbounds {{.*}}, i32 0, i32 8
121 // CHECK2-NEXT: [[Val:%[0-9a-z_]*]] = load i32* [[C]]
122 // CHECK2-NEXT: store i32 [[Val]], i32* [[CapC]]
123 //
124 // CHECK2: bitcast %struct.__block_byref_d*
125 // CHECK2-NEXT: store i8*
126}