1; RUN: llc -mtriple x86_64-apple-darwin -filetype=obj -o %t.o < %s 2; RUN: llvm-dwarfdump %t.o | FileCheck %s 3; 4; RUN: llc --try-experimental-debuginfo-iterators -mtriple x86_64-apple-darwin -filetype=obj -o %t.o < %s 5; RUN: llvm-dwarfdump %t.o | FileCheck %s 6; 7; Test that DW_AT_location is generated for a captured "self" inside a 8; block. 9; 10; This test is split into two parts, the frontend part can be found at 11; llvm/tools/clang/test/CodeGenObjC/debug-info-block-captured-self.m 12; 13; CHECK: {{.*}}DW_AT_name{{.*}}_block_invoke{{.*}} 14; CHECK: DW_TAG_variable 15; CHECK-NOT: DW_TAG 16; CHECK: DW_AT_location 17; CHECK-NOT: DW_TAG 18; CHECK: DW_AT_name{{.*}}"self"{{.*}} 19; 20; CHECK: {{.*}}DW_AT_name{{.*}}_block_invoke{{.*}} 21; CHECK: DW_TAG_variable 22; CHECK-NOT: DW_TAG 23; CHECK: DW_AT_location 24; CHECK-NOT: DW_TAG 25; CHECK: DW_AT_name{{.*}}"self"{{.*}} 26; 27; Generated (and then reduced) from 28; ---------------------------------------------------------------------- 29; 30; @class T; 31; @interface S 32; @end 33; @interface Mode 34; -(int) count; 35; @end 36; @interface Context 37; @end 38; @interface ViewController 39; @property (nonatomic, readwrite, strong) Context *context; 40; @end 41; typedef enum { 42; Unknown = 0, 43; } State; 44; @interface Main : ViewController 45; { 46; T * t1; 47; T * t2; 48; } 49; @property(readwrite, nonatomic) State state; 50; @end 51; @implementation Main 52; - (id) initWithContext:(Context *) context 53; { 54; t1 = [self.context withBlock:^(id obj){ 55; id *mode1; 56; t2 = [mode1 withBlock:^(id object){ 57; Mode *mode2 = object; 58; if ([mode2 count] != 0) { 59; self.state = 0; 60; } 61; }]; 62; }]; 63; } 64; @end 65; ---------------------------------------------------------------------- 66; ModuleID = 'llvm/tools/clang/test/CodeGenObjC/debug-info-block-captured-self.m' 67%0 = type opaque 68%struct.__block_descriptor = type { i64, i64 } 69declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 70define internal void @"__24-[Main initWithContext:]_block_invoke"(ptr %.block_descriptor, ptr %obj) #0 !dbg !38 { 71 %block.captured-self = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %.block_descriptor, i32 0, i32 5, !dbg !84 72 call void @llvm.dbg.declare(metadata ptr %.block_descriptor, metadata !86, metadata !110), !dbg !87 73 ret void, !dbg !87 74} 75 76define internal void @"__24-[Main initWithContext:]_block_invoke_2"(ptr %.block_descriptor, ptr %object) #0 !dbg !42 { 77 %block.captured-self = getelementptr inbounds <{ ptr, i32, i32, ptr, ptr, ptr }>, ptr %.block_descriptor, i32 0, i32 5, !dbg !103 78 call void @llvm.dbg.declare(metadata ptr %.block_descriptor, metadata !105, metadata !109), !dbg !106 79 ret void, !dbg !106 80} 81 82!llvm.dbg.cu = !{!0} 83!llvm.module.flags = !{!108} 84!0 = distinct !DICompileUnit(language: DW_LANG_ObjC, producer: "clang version 3.3 ", isOptimized: false, runtimeVersion: 2, emissionKind: FullDebug, file: !107, enums: !2, retainedTypes: !4, globals: !15, imports: !15) 85!1 = !DIFile(filename: "llvm/tools/clang/test/CodeGenObjC/debug-info-block-captured-self.m", directory: "") 86!2 = !{!3} 87!3 = !DICompositeType(tag: DW_TAG_enumeration_type, line: 20, size: 32, align: 32, file: !107, elements: !4) 88!4 = !{} 89!15 = !{} 90!27 = !DIDerivedType(tag: DW_TAG_typedef, name: "id", line: 31, file: !107, baseType: !28) 91!28 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !29) 92!29 = !DICompositeType(tag: DW_TAG_structure_type, name: "objc_object", file: !107, elements: !30) 93!30 = !{!31} 94!31 = !DIDerivedType(tag: DW_TAG_member, name: "isa", size: 64, file: !107, scope: !29, baseType: !32) 95!32 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, baseType: !33) 96!33 = !DICompositeType(tag: DW_TAG_structure_type, name: "objc_class", flags: DIFlagFwdDecl, file: !107) 97!34 = !DICompositeType(tag: DW_TAG_structure_type, name: "Main", line: 23, flags: DIFlagArtificial | DIFlagObjectPointer, runtimeLang: DW_LANG_ObjC, file: !107) 98!38 = distinct !DISubprogram(name: "__24-[Main initWithContext:]_block_invoke", line: 33, isLocal: true, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 33, file: !1, scope: !1, type: !39, retainedNodes: !15) 99!39 = !DISubroutineType(types: !40) 100!40 = !{null, !41, !27} 101!41 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: null) 102!42 = distinct !DISubprogram(name: "__24-[Main initWithContext:]_block_invoke_2", line: 35, isLocal: true, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0, scopeLine: 35, file: !1, scope: !1, type: !39, retainedNodes: !15) 103!84 = !DILocation(line: 33, scope: !38) 104!86 = !DILocalVariable(name: "self", line: 41, scope: !38, file: !1, type: !34) 105!87 = !DILocation(line: 41, scope: !38) 106!103 = !DILocation(line: 35, scope: !42) 107!105 = !DILocalVariable(name: "self", line: 40, scope: !42, file: !1, type: !34) 108!106 = !DILocation(line: 40, scope: !42) 109!107 = !DIFile(filename: "llvm/tools/clang/test/CodeGenObjC/debug-info-block-captured-self.m", directory: "") 110!108 = !{i32 1, !"Debug Info Version", i32 3} 111!109 = !DIExpression(DW_OP_plus_uconst, 32, DW_OP_deref) 112!110 = !DIExpression(DW_OP_plus_uconst, 32, DW_OP_deref) 113