summaryrefslogtreecommitdiffstats
path: root/test/CodeGen/captured-statements-nested.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/CodeGen/captured-statements-nested.c')
-rw-r--r--test/CodeGen/captured-statements-nested.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/test/CodeGen/captured-statements-nested.c b/test/CodeGen/captured-statements-nested.c
new file mode 100644
index 0000000..d8ec746
--- /dev/null
+++ b/test/CodeGen/captured-statements-nested.c
@@ -0,0 +1,126 @@
+// RUN: %clang_cc1 -fblocks -emit-llvm %s -o %t
+// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK1
+// RUN: FileCheck %s -input-file=%t -check-prefix=CHECK2
+
+struct A {
+ int a;
+ float b;
+ char c;
+};
+
+void test_nest_captured_stmt(int param) {
+ int w;
+ // CHECK1: %struct.anon{{.*}} = type { i32*, i32* }
+ // CHECK1: %struct.anon{{.*}} = type { i32*, i32*, i32**, i32* }
+ // CHECK1: [[T:%struct.anon.*]] = type { i32*, i32*, %struct.A*, i32**, i32* }
+ #pragma clang __debug captured
+ {
+ int x;
+ int *y = &w;
+ #pragma clang __debug captured
+ {
+ struct A z;
+ #pragma clang __debug captured
+ {
+ w = x = z.a = 1;
+ *y = param;
+ z.b = 0.1f;
+ z.c = 'c';
+
+ // CHECK1: define internal void @__captured_stmt{{.*}}([[T]]
+ //
+ // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 2
+ // CHECK1-NEXT: load %struct.A**
+ // CHECK1-NEXT: getelementptr inbounds %struct.A*
+ // CHECK1-NEXT: store i32 1
+ //
+ // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 1
+ // CHECK1-NEXT: load i32**
+ // CHECK1-NEXT: store i32 1
+ //
+ // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 0
+ // CHECK1-NEXT: load i32**
+ // CHECK1-NEXT: store i32 1
+ //
+ // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 4
+ // CHECK1-NEXT: load i32**
+ // CHECK1-NEXT: load i32*
+ // CHECK1-NEXT: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 3
+ // CHECK1-NEXT: load i32***
+ // CHECK1-NEXT: load i32**
+ // CHECK1-NEXT: store i32
+ //
+ // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 2
+ // CHECK1-NEXT: load %struct.A**
+ // CHECK1-NEXT: getelementptr inbounds %struct.A*
+ // CHECK1-NEXT: store float
+ //
+ // CHECK1: getelementptr inbounds [[T]]* {{.*}}, i32 0, i32 2
+ // CHECK1-NEXT: load %struct.A**
+ // CHECK1-NEXT: getelementptr inbounds %struct.A*
+ // CHECK1-NEXT: store i8 99
+ }
+ }
+ }
+}
+
+void test_nest_block() {
+ __block int x;
+ int y;
+ ^{
+ int z;
+ x = z;
+ #pragma clang __debug captured
+ {
+ z = y; // OK
+ }
+ }();
+
+ // CHECK2: define internal void @{{.*}}test_nest_block_block_invoke
+ //
+ // CHECK2: [[Z:%[0-9a-z_]*]] = alloca i32
+ // CHECK2: alloca %struct.anon{{.*}}
+ //
+ // CHECK2: store i32
+ // CHECK2: store i32* [[Z]]
+ //
+ // CHECK2: getelementptr inbounds %struct.anon
+ // CHECK2-NEXT: getelementptr inbounds
+ // CHECK2-NEXT: store i32*
+ //
+ // CHECK2: call void @__captured_stmt
+
+ int a;
+ #pragma clang __debug captured
+ {
+ __block int b;
+ int c;
+ __block int d;
+ ^{
+ b = a;
+ b = c;
+ b = d;
+ }();
+ }
+
+ // CHECK2: alloca %struct.__block_byref_b
+ // CHECK2-NEXT: [[C:%[0-9a-z_]*]] = alloca i32
+ // CHECK2-NEXT: alloca %struct.__block_byref_d
+ //
+ // CHECK2: bitcast %struct.__block_byref_b*
+ // CHECK2-NEXT: store i8*
+ //
+ // CHECK2: [[CapA:%[0-9a-z_.]*]] = getelementptr inbounds {{.*}}, i32 0, i32 7
+ //
+ // CHECK2: getelementptr inbounds %struct.anon{{.*}}, i32 0, i32 0
+ // CHECK2: load i32**
+ // CHECK2: load i32*
+ // CHECK2: store i32 {{.*}}, i32* [[CapA]]
+ //
+ // CHECK2: [[CapC:%[0-9a-z_.]*]] = getelementptr inbounds {{.*}}, i32 0, i32 8
+ // CHECK2-NEXT: [[Val:%[0-9a-z_]*]] = load i32* [[C]]
+ // CHECK2-NEXT: store i32 [[Val]], i32* [[CapC]]
+ //
+ // CHECK2: bitcast %struct.__block_byref_d*
+ // CHECK2-NEXT: store i8*
+}
OpenPOWER on IntegriCloud