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