Skip to content

Commit 7f78d47

Browse files
committed
[DebugInfo] Apply subprogram attributes on behalf of owner CU
When using full LTO it is possible that template function definition DIE is bound to one compilation unit and it's declaration to another. We should add function declaration attributes on behalf of its owner CU otherwise we may end up with malformed file identifier in function declaration DW_AT_decl_file attribute. Differential revision: https://reviews.llvm.org/D58538 llvm-svn: 354978
1 parent d73a67a commit 7f78d47

File tree

4 files changed

+96
-3
lines changed

4 files changed

+96
-3
lines changed

llvm/include/llvm/CodeGen/DIE.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ class DIE : IntrusiveBackListNode, public DIEValueList {
759759
///
760760
/// \returns the DIEUnit that represents the compile or type unit that owns
761761
/// this DIE, or NULL if this DIE hasn't been added to a unit DIE.
762-
const DIEUnit *getUnit() const;
762+
DIEUnit *getUnit() const;
763763

764764
void setOffset(unsigned O) { Offset = O; }
765765
void setSize(unsigned S) { Size = S; }

llvm/lib/CodeGen/AsmPrinter/DIE.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ const DIE *DIE::getUnitDie() const {
211211
return nullptr;
212212
}
213213

214-
const DIEUnit *DIE::getUnit() const {
214+
DIEUnit *DIE::getUnit() const {
215215
const DIE *UnitDie = getUnitDie();
216216
if (UnitDie)
217217
return UnitDie->Owner.dyn_cast<DIEUnit*>();

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -1106,7 +1106,8 @@ DIE *DwarfUnit::getOrCreateSubprogramDIE(const DISubprogram *SP, bool Minimal) {
11061106
if (SP->isDefinition())
11071107
return &SPDie;
11081108

1109-
applySubprogramAttributes(SP, SPDie);
1109+
static_cast<DwarfUnit *>(SPDie.getUnit())
1110+
->applySubprogramAttributes(SP, SPDie);
11101111
return &SPDie;
11111112
}
11121113

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
; Checks that DW_AT_decl_file attribute is correctly set for
2+
; template function declaration. When using full LTO we likely
3+
; end up having multiple CUs in a single DWARF file, and it is
4+
; possible that we add template function declaration DIE from
5+
; CU#1 to structure type DIE from CU#2. In such case we should
6+
; add source line attributes on behalf of CU#2, not CU#1
7+
8+
; Example source code used to generate this sample (C++)
9+
; // File inc1.h
10+
; struct S {
11+
; template <typename T> static void tmpfn() {}
12+
; };
13+
;
14+
; // File: inc2.h
15+
; extern int x;
16+
; int x;
17+
;
18+
; // File: foo.cpp
19+
; #include "inc1.h"
20+
; S s;
21+
;
22+
; // File: bar.cpp
23+
; #include "inc1.h"
24+
; #include "inc2.h"
25+
; void f3() { S::tmpfn<int>(); }
26+
27+
; RUN: llc -filetype=obj %s -o %t
28+
; RUN: llvm-dwarfdump %t -o - | FileCheck %s
29+
30+
; CHECK: DW_AT_linkage_name ("_ZN1S5tmpfnIiEEvv")
31+
; CHECK-NEXT: DW_AT_name ("tmpfn<int>")
32+
; CHECK-NEXT: DW_AT_decl_file ("{{.*}}inc1.h")
33+
; CHECK-NEXT: DW_AT_decl_line (2)
34+
35+
source_filename = "ld-temp.o"
36+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
37+
target triple = "x86_64-unknown-linux-gnu"
38+
39+
%struct.S = type { i8 }
40+
41+
$_ZN1S5tmpfnIiEEvv = comdat any
42+
43+
@s = dso_local global %struct.S zeroinitializer, align 1, !dbg !0
44+
@x = dso_local global i32 0, align 4, !dbg !8
45+
46+
; Function Attrs: noinline optnone uwtable
47+
define dso_local void @_Z2f3v() !dbg !21 {
48+
call void @_ZN1S5tmpfnIiEEvv(), !dbg !24
49+
ret void, !dbg !25
50+
}
51+
52+
; Function Attrs: noinline nounwind optnone uwtable
53+
define weak_odr dso_local void @_ZN1S5tmpfnIiEEvv() comdat align 2 !dbg !26 {
54+
ret void, !dbg !30
55+
}
56+
57+
!llvm.dbg.cu = !{!2, !10}
58+
!llvm.ident = !{!15, !15}
59+
!llvm.module.flags = !{!16, !17, !18, !19, !20}
60+
61+
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
62+
!1 = distinct !DIGlobalVariable(name: "s", scope: !2, file: !3, line: 2, type: !6, isLocal: false, isDefinition: true)
63+
!2 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !3, producer: "clang version 9.0.0 (trunk 354767)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, nameTableKind: None)
64+
!3 = !DIFile(filename: "foo.cpp", directory: "/home/evgeny/work/cpp_lexer/sample2")
65+
!4 = !{}
66+
!5 = !{!0}
67+
!6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "S", file: !7, line: 1, size: 8, flags: DIFlagTypePassByValue | DIFlagTrivial, elements: !4, identifier: "_ZTS1S")
68+
!7 = !DIFile(filename: "./inc1.h", directory: "/home/evgeny/work/cpp_lexer/sample2")
69+
!8 = !DIGlobalVariableExpression(var: !9, expr: !DIExpression())
70+
!9 = distinct !DIGlobalVariable(name: "x", scope: !10, file: !13, line: 2, type: !14, isLocal: false, isDefinition: true)
71+
!10 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !11, producer: "clang version 9.0.0 (trunk 354767)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !12, nameTableKind: None)
72+
!11 = !DIFile(filename: "bar.cpp", directory: "/home/evgeny/work/cpp_lexer/sample2")
73+
!12 = !{!8}
74+
!13 = !DIFile(filename: "./inc2.h", directory: "/home/evgeny/work/cpp_lexer/sample2")
75+
!14 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
76+
!15 = !{!"clang version 9.0.0 (trunk 354767)"}
77+
!16 = !{i32 2, !"Dwarf Version", i32 4}
78+
!17 = !{i32 2, !"Debug Info Version", i32 3}
79+
!18 = !{i32 1, !"wchar_size", i32 4}
80+
!19 = !{i32 1, !"ThinLTO", i32 0}
81+
!20 = !{i32 1, !"EnableSplitLTOUnit", i32 0}
82+
!21 = distinct !DISubprogram(name: "f3", linkageName: "_Z2f3v", scope: !11, file: !11, line: 3, type: !22, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !10, retainedNodes: !4)
83+
!22 = !DISubroutineType(types: !23)
84+
!23 = !{null}
85+
!24 = !DILocation(line: 3, column: 13, scope: !21)
86+
!25 = !DILocation(line: 3, column: 30, scope: !21)
87+
!26 = distinct !DISubprogram(name: "tmpfn<int>", linkageName: "_ZN1S5tmpfnIiEEvv", scope: !6, file: !7, line: 2, type: !22, scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !10, templateParams: !28, declaration: !27, retainedNodes: !4)
88+
!27 = !DISubprogram(name: "tmpfn<int>", linkageName: "_ZN1S5tmpfnIiEEvv", scope: !6, file: !7, line: 2, type: !22, scopeLine: 2, flags: DIFlagPrototyped | DIFlagStaticMember, spFlags: 0, templateParams: !28)
89+
!28 = !{!29}
90+
!29 = !DITemplateTypeParameter(name: "T", type: !14)
91+
!30 = !DILocation(line: 2, column: 46, scope: !26)
92+

0 commit comments

Comments
 (0)