diff options
Diffstat (limited to 'test/CodeGenObjC/debug-info-block-captured-self.m')
-rw-r--r-- | test/CodeGenObjC/debug-info-block-captured-self.m | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/test/CodeGenObjC/debug-info-block-captured-self.m b/test/CodeGenObjC/debug-info-block-captured-self.m new file mode 100644 index 0000000000..6020e84553 --- /dev/null +++ b/test/CodeGenObjC/debug-info-block-captured-self.m @@ -0,0 +1,64 @@ +// RUN: %clang_cc1 -fblocks -g -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s +// +// Test that debug location is generated for a captured "self" inside +// a block. +// +// This test is split into two parts, this one for the frontend, and +// then llvm/test/DebugInfo/debug-info-block-captured-self.ll to +// ensure that DW_AT_location is generated for the captured self. +@class T; +@interface S +@end +@interface Mode +-(int) count; +@end +@interface Context +@end +@interface ViewController +@property (nonatomic, readwrite, strong) Context *context; +@end +typedef enum { + Unknown = 0, +} State; +@interface Main : ViewController +{ + T * t1; + T * t2; +} +@property(readwrite, nonatomic) State state; +@end +@implementation Main +- (id) initWithContext:(Context *) context +{ + t1 = [self.context withBlock:^(id obj){ + id *mode1; + t2 = [mode1 withBlock:^(id object){ + Mode *mode2 = object; + if ([mode2 count] != 0) { + self.state = 0; + } + }]; + }]; +} +@end +// The important part of this test is that there is a dbg.value +// intrinsic associated with the implicit .block_descriptor argument +// of the block. We also test that this value gets alloca'd, so the +// register llocator won't accidentally kill it. + +// outer block: +// CHECK: define internal void {{.*}}_block_invoke{{.*}} + +// inner block: +// CHECK: define internal void {{.*}}_block_invoke{{.*}} +// CHECK: [[MEM1:%.*]] = alloca i8*, align 8 +// CHECK-NEXT: [[MEM2:%.*]] = alloca i8*, align 8 +// CHECK-NEXT: [[MEM3:%.*]] = alloca %{{.*}}*, align 8 +// CHECK: store i8* %[[BLOCK_DESC:.*]], i8** [[MEM1]], align 8 +// CHECK: [[TMP0:%.*]] = load i8** [[MEM1]] +// CHECK: call void @llvm.dbg.value(metadata !{i8* [[TMP0]]}, i64 0, metadata [[BDMD:![0-9]+]]) +// CHECK: [[TMP1:%.*]] = bitcast +// CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, %0* }>* [[TMP1]] +// CHECK-NEXT: [[TMP3:%.*]] = load %0** [[TMP2]] +// CHECK-NEXT: store {{.*}}* [[TMP3]], %{{.*}}** [[MEM3]], align 8 +// CHECK: [[BDMD]] = metadata {{.*}}.block_descriptor |