aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/blocks.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-01-19 10:04:05 +0000
commit676fbe8105eeb6ff4bb2ed261cb212fcfdbe7b63 (patch)
tree02a1ac369cb734d0abfa5000dd86e5b7797e6a74 /test/CodeGenCXX/blocks.cpp
parentc7e70c433efc6953dc3888b9fbf9f3512d7da2b0 (diff)
Notes
Diffstat (limited to 'test/CodeGenCXX/blocks.cpp')
-rw-r--r--test/CodeGenCXX/blocks.cpp57
1 files changed, 56 insertions, 1 deletions
diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp
index 37219d3f7abd..3b3363dc4175 100644
--- a/test/CodeGenCXX/blocks.cpp
+++ b/test/CodeGenCXX/blocks.cpp
@@ -1,5 +1,8 @@
// RUN: %clang_cc1 %s -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+// CHECK: %[[STRUCT_BLOCK_DESCRIPTOR:.*]] = type { i64, i64 }
+// CHECK: @[[BLOCK_DESCRIPTOR22:.*]] = internal constant { i64, i64, i8*, i8*, i8*, i8* } { i64 0, i64 36, i8* bitcast (void (i8*, i8*)* @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE to i8*), i8* bitcast (void (i8*)* @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE to i8*), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0), i8* null }, align 8
+
namespace test0 {
// CHECK-LABEL: define void @_ZN5test04testEi(
// CHECK: define internal void @___ZN5test04testEi_block_invoke{{.*}}(
@@ -73,6 +76,7 @@ namespace test2 {
void test() {
__block A a;
__block B b;
+ ^{ (void)a; (void)b; };
}
// CHECK-LABEL: define internal void @__Block_byref_object_copy
@@ -122,7 +126,7 @@ namespace test4 {
// CHECK-LABEL: define internal void @___ZN5test44testEv_block_invoke
// CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1
// CHECK-NEXT: store i8* [[BLOCKDESC:%.*]], i8** {{.*}}, align 8
- // CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>*
+ // CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %[[STRUCT_BLOCK_DESCRIPTOR]]* }>*
// CHECK: call void @_ZN5test41AC1Ev([[A]]* [[TMP]])
// CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]])
// CHECK-NEXT: call void @_ZN5test41AD1Ev([[A]]* [[TMP]])
@@ -252,3 +256,54 @@ namespace test9 {
});
}
}
+
+namespace test10 {
+ // Check that 'v' is included in the copy helper function name to indicate
+ // the constructor taking a volatile parameter is called to copy the captured
+ // object.
+
+ // CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_8_32c16_ZTSVN6test101BE(
+ // CHECK: call void @_ZN6test101BC1ERVKS0_(
+ // CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_8_32c16_ZTSVN6test101BE(
+ // CHECK: call void @_ZN6test101BD1Ev(
+
+ struct B {
+ int a;
+ B();
+ B(const B &);
+ B(const volatile B &);
+ ~B();
+ };
+
+ void test() {
+ volatile B x;
+ ^{ (void)x; };
+ }
+}
+
+// Copy/dispose helper functions and block descriptors of blocks that capture
+// objects that are non-external and non-trivial have internal linkage.
+
+// CHECK-LABEL: define internal void @_ZN12_GLOBAL__N_14testEv(
+// CHECK: store %[[STRUCT_BLOCK_DESCRIPTOR]]* bitcast ({ i64, i64, i8*, i8*, i8*, i8* }* @[[BLOCK_DESCRIPTOR22]] to %[[STRUCT_BLOCK_DESCRIPTOR]]*), %[[STRUCT_BLOCK_DESCRIPTOR]]** %{{.*}}, align 8
+
+// CHECK-LABEL: define internal void @__copy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(
+// CHECK-LABEL: define internal void @__destroy_helper_block_8_32c22_ZTSN12_GLOBAL__N_11BE(
+
+namespace {
+ struct B {
+ int a;
+ B();
+ B(const B &);
+ ~B();
+ };
+
+ void test() {
+ B x;
+ ^{ (void)x; };
+ }
+}
+
+void callTest() {
+ test();
+}