1*67e74705SXin Li// RUN: %clang_cc1 -fblocks -debug-info-kind=limited -emit-llvm -triple x86_64-apple-darwin -o - %s | FileCheck %s 2*67e74705SXin Li// 3*67e74705SXin Li// Test that debug location is generated for a captured "self" inside 4*67e74705SXin Li// a block. 5*67e74705SXin Li// 6*67e74705SXin Li// This test is split into two parts, this one for the frontend, and 7*67e74705SXin Li// then llvm/test/DebugInfo/debug-info-block-captured-self.ll to 8*67e74705SXin Li// ensure that DW_AT_location is generated for the captured self. 9*67e74705SXin Li@class T; 10*67e74705SXin Li@interface S 11*67e74705SXin Li@end 12*67e74705SXin Li@interface Mode 13*67e74705SXin Li-(int) count; 14*67e74705SXin Li@end 15*67e74705SXin Li@interface Context 16*67e74705SXin Li@end 17*67e74705SXin Li@interface ViewController 18*67e74705SXin Li@property (nonatomic, readwrite, strong) Context *context; 19*67e74705SXin Li@end 20*67e74705SXin Litypedef enum { 21*67e74705SXin Li Unknown = 0, 22*67e74705SXin Li} State; 23*67e74705SXin Li@interface Main : ViewController 24*67e74705SXin Li{ 25*67e74705SXin Li T * t1; 26*67e74705SXin Li T * t2; 27*67e74705SXin Li} 28*67e74705SXin Li@property(readwrite, nonatomic) State state; 29*67e74705SXin Li@end 30*67e74705SXin Li@implementation Main 31*67e74705SXin Li- (id) initWithContext:(Context *) context 32*67e74705SXin Li{ 33*67e74705SXin Li t1 = [self.context withBlock:^(id obj){ 34*67e74705SXin Li id *mode1; 35*67e74705SXin Li t2 = [mode1 withBlock:^(id object){ 36*67e74705SXin Li Mode *mode2 = object; 37*67e74705SXin Li if ([mode2 count] != 0) { 38*67e74705SXin Li self.state = 0; 39*67e74705SXin Li } 40*67e74705SXin Li }]; 41*67e74705SXin Li }]; 42*67e74705SXin Li} 43*67e74705SXin Li@end 44*67e74705SXin Li// The important part of this test is that there is a dbg.value 45*67e74705SXin Li// intrinsic associated with the implicit .block_descriptor argument 46*67e74705SXin Li// of the block. We also test that this value gets alloca'd, so the 47*67e74705SXin Li// register llocator won't accidentally kill it. 48*67e74705SXin Li 49*67e74705SXin Li// outer block: 50*67e74705SXin Li// CHECK: define internal void {{.*}}_block_invoke{{.*}} 51*67e74705SXin Li 52*67e74705SXin Li// inner block: 53*67e74705SXin Li// CHECK: define internal void {{.*}}_block_invoke{{.*}} 54*67e74705SXin Li// CHECK: %[[MEM1:.*]] = alloca i8*, align 8 55*67e74705SXin Li// CHECK-NEXT: %[[MEM2:.*]] = alloca i8*, align 8 56*67e74705SXin Li// CHECK-NEXT: [[DBGADDR:%.*]] = alloca [[BLOCK_T:<{.*}>]]*, align 8 57*67e74705SXin Li// CHECK: store i8* [[BLOCK_DESC:%.*]], i8** %[[MEM1]], align 8 58*67e74705SXin Li// CHECK: %[[TMP0:.*]] = load i8*, i8** %[[MEM1]] 59*67e74705SXin Li// CHECK: call void @llvm.dbg.value(metadata i8* %[[TMP0]], i64 0, metadata ![[BDMD:[0-9]+]], metadata !{{.*}}) 60*67e74705SXin Li// CHECK: call void @llvm.dbg.declare(metadata i8* [[BLOCK_DESC]], metadata ![[BDMD:[0-9]+]], metadata !{{.*}}) 61*67e74705SXin Li// CHECK: store [[BLOCK_T]]* {{%.*}}, [[BLOCK_T]]** [[DBGADDR]], align 8 62*67e74705SXin Li// CHECK: call void @llvm.dbg.declare(metadata [[BLOCK_T]]** [[DBGADDR]], metadata ![[SELF:.*]], metadata !{{.*}}) 63*67e74705SXin Li// make sure we are still in the same function 64*67e74705SXin Li// CHECK: define {{.*}}__copy_helper_block_ 65*67e74705SXin Li// Metadata 66*67e74705SXin Li// CHECK: ![[MAIN:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "Main" 67*67e74705SXin Li// CHECK-SAME: line: 23, 68*67e74705SXin Li// CHECK: ![[PMAIN:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[MAIN]], 69*67e74705SXin Li// CHECK: ![[BDMD]] = !DILocalVariable(name: ".block_descriptor", arg: 70*67e74705SXin Li// CHECK: ![[SELF]] = !DILocalVariable(name: "self" 71*67e74705SXin Li// CHECK-NOT: arg: 72*67e74705SXin Li// CHECK-SAME: line: 40, 73