xref: /llvm-project/llvm/test/DebugInfo/X86/debug-info-block-captured-self.ll (revision 5ee088134fb87f7d716c58fa65beb11fb6afcb22)
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