[llvm] [DebugInfo] Emit linkage name into DWARF for types for Swift (PR #112802)
Augusto Noronha via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 22 13:01:35 PDT 2024
https://github.com/augusto2112 updated https://github.com/llvm/llvm-project/pull/112802
>From fff31eb8f70338939ceab90504b8bbac78c477e1 Mon Sep 17 00:00:00 2001
From: Augusto Noronha <anoronha at apple.com>
Date: Thu, 17 Oct 2024 16:51:02 -0700
Subject: [PATCH 1/3] [DebugInfo] Emit linkage name into DWARF for types for
Swift
Store Swift mangled names in DW_AT_linkage_name. The Swift compiler
emits only the type mangled name in debug information, and LLDB uses
those mangled names as keys to look up size, alignment, fields, etc
from either reflection metadata or Swift modules.
Additionally, emit types linkage names for types into the accelerator
table if they exist and they're different from the display name.
---
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 16 +++++-
llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 21 +++++--
.../Generic/debug-names-accel-table-types.ll | 55 ++++++++++++++++++
.../debug-names-accel-table-types.test | 56 +++++++++++++++++++
4 files changed, 139 insertions(+), 9 deletions(-)
create mode 100644 llvm/test/DebugInfo/Generic/debug-names-accel-table-types.ll
create mode 100644 llvm/test/tools/dsymutil/debug-names-accel-table-types.test
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index e76b0fe2081c07..08154de9418b77 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -645,16 +645,22 @@ void DwarfUnit::updateAcceleratorTables(const DIScope *Context,
// add temporary record for this type to be added later
- bool IsImplementation = false;
+ unsigned Flags = 0;
if (auto *CT = dyn_cast<DICompositeType>(Ty)) {
// A runtime language of 0 actually means C/C++ and that any
// non-negative value is some version of Objective-C/C++.
- IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete();
+ if (CT->getRuntimeLang() == 0 || CT->isObjcClassComplete())
+ Flags = dwarf::DW_FLAG_type_implementation;
}
- unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0;
+
DD->addAccelType(*this, CUNode->getNameTableKind(), Ty->getName(), TyDIE,
Flags);
+ if (auto *CT = dyn_cast<DICompositeType>(Ty))
+ if (Ty->getName() != CT->getIdentifier())
+ DD->addAccelType(*this, CUNode->getNameTableKind(), CT->getIdentifier(),
+ TyDIE, Flags);
+
addGlobalType(Ty, TyDIE, Context);
}
@@ -1042,6 +1048,10 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
if (!Name.empty())
addString(Buffer, dwarf::DW_AT_name, Name);
+ // For Swift, mangled names are put into DW_AT_linkage_name.
+ if (CTy->getRuntimeLang() == dwarf::DW_LANG_Swift && CTy->getRawIdentifier())
+ addString(Buffer, dwarf::DW_AT_linkage_name, CTy->getIdentifier());
+
addAnnotation(Buffer, CTy->getAnnotations());
if (Tag == dwarf::DW_TAG_enumeration_type ||
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 280d3f1861ff00..adfb920abb9387 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -1837,10 +1837,8 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
} else if (Tag == dwarf::DW_TAG_imported_declaration && AttrInfo.Name) {
Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
- } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration &&
- getDIENames(InputDIE, AttrInfo, DebugStrPool) && AttrInfo.Name &&
- AttrInfo.Name.getString()[0]) {
- uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit, File);
+ } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration) {
+ bool Success = getDIENames(InputDIE, AttrInfo, DebugStrPool);
uint64_t RuntimeLang =
dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class))
.value_or(0);
@@ -1849,8 +1847,19 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
RuntimeLang == dwarf::DW_LANG_ObjC_plus_plus) &&
dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_objc_complete_type))
.value_or(0);
- Unit.addTypeAccelerator(Die, AttrInfo.Name, ObjCClassIsImplementation,
- Hash);
+ if (Success && AttrInfo.Name && !AttrInfo.Name.getString().empty()) {
+ uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit, File);
+ Unit.addTypeAccelerator(Die, AttrInfo.Name, ObjCClassIsImplementation,
+ Hash);
+ }
+
+ if (Success && AttrInfo.MangledName &&
+ !AttrInfo.MangledName.getString().empty() &&
+ AttrInfo.MangledName != AttrInfo.Name) {
+ auto Hash = djbHash(AttrInfo.MangledName.getString().data());
+ Unit.addTypeAccelerator(Die, AttrInfo.MangledName,
+ ObjCClassIsImplementation, Hash);
+ }
}
// Determine whether there are any children that we want to keep.
diff --git a/llvm/test/DebugInfo/Generic/debug-names-accel-table-types.ll b/llvm/test/DebugInfo/Generic/debug-names-accel-table-types.ll
new file mode 100644
index 00000000000000..e88afe1b4c5118
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/debug-names-accel-table-types.ll
@@ -0,0 +1,55 @@
+; RUN: %llc_dwarf -debugger-tune=lldb -accel-tables=Dwarf -filetype=obj -o %t < %s
+; RUN: llvm-dwarfdump %t | FileCheck %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=SAME-NAME %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=DIFFERENT-NAME %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=UNIQUE-DIFFERENT-NAME %s
+; RUN: llvm-dwarfdump -debug-names -verify %t | FileCheck --check-prefix=VERIFY %s
+
+
+; CHECK: DW_TAG_structure_type
+; CHECK: DW_AT_name ("SameName")
+; CHECK: DW_AT_linkage_name ("SameName")
+
+; CHECK: DW_TAG_structure_type
+; CHECK: DW_AT_name ("DifferentName")
+; CHECK: DW_AT_linkage_name ("UniqueDifferentName")
+
+; The name count should be 5 (the two variables, the two human readable names, one mangled name).
+; SAME-NAME: Name count: 5
+
+; The accelarator should only have one entry for the three following names.
+; SAME-NAME: "SameName"
+; SAME-NAME-NOT: "SameName"
+
+; DIFFERENT-NAME: "DifferentName"
+; DIFFERENT-NAME-NOT: "DifferentName"
+
+; UNIQUE-DIFFERENT-NAME: "UniqueDifferentName"
+; UNIQUE-DIFFERENT-NAME-NOT: "UniqueDifferentName"
+
+; Verification should succeed.
+; VERIFY: No errors.
+
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+ at q = common global i8* null, align 8, !dbg !102
+ at r = common global i8* null, align 8, !dbg !105
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!6, !7}
+
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5)
+!3 = !DIFile(filename: "/tmp/p.c", directory: "/")
+!4 = !{}
+!5 = !{!102, !105}
+!6 = !{i32 2, !"Dwarf Version", i32 4}
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+
+; marking the types as Swift is necessary because we only emit the linkage names for Swift types.
+!11 = !DICompositeType(tag: DW_TAG_structure_type, name: "SameName", file: !3, size: 64, runtimeLang: DW_LANG_Swift, identifier: "SameName")
+!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "DifferentName", file: !3, size: 64, runtimeLang: DW_LANG_Swift, identifier: "UniqueDifferentName")
+
+!102 = !DIGlobalVariableExpression(var: !103, expr: !DIExpression())
+!103 = distinct !DIGlobalVariable(name: "q", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true)
+!104 = distinct !DIGlobalVariable(name: "r", scope: !2, file: !3, line: 1, type: !12, isLocal: false, isDefinition: true)
+!105 = !DIGlobalVariableExpression(var: !104, expr: !DIExpression())
diff --git a/llvm/test/tools/dsymutil/debug-names-accel-table-types.test b/llvm/test/tools/dsymutil/debug-names-accel-table-types.test
new file mode 100644
index 00000000000000..90cdaded8523a9
--- /dev/null
+++ b/llvm/test/tools/dsymutil/debug-names-accel-table-types.test
@@ -0,0 +1,56 @@
+; RUN: %llc_dwarf -debugger-tune=lldb -accel-tables=Dwarf -filetype=obj -o %t < %s
+; RUN: dsymutil %t -o %t.dSYM
+; RUN: llvm-dwarfdump %t | FileCheck %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=SAME-NAME %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=DIFFERENT-NAME %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=UNIQUE-DIFFERENT-NAME %s
+; RUN: llvm-dwarfdump -debug-names -verify %t | FileCheck --check-prefix=VERIFY %s
+
+
+; CHECK: DW_TAG_structure_type
+; CHECK: DW_AT_name ("SameName")
+; CHECK: DW_AT_linkage_name ("SameName")
+
+; CHECK: DW_TAG_structure_type
+; CHECK: DW_AT_name ("DifferentName")
+; CHECK: DW_AT_linkage_name ("UniqueDifferentName")
+
+; The name count should be 5 (the two variables, the two human readable names, one mangled name).
+; SAME-NAME: Name count: 5
+
+; The accelarator should only have one entry for the three following names.
+; SAME-NAME: "SameName"
+; SAME-NAME-NOT: "SameName"
+
+; DIFFERENT-NAME: "DifferentName"
+; DIFFERENT-NAME-NOT: "DifferentName"
+
+; UNIQUE-DIFFERENT-NAME: "UniqueDifferentName"
+; UNIQUE-DIFFERENT-NAME-NOT: "UniqueDifferentName"
+
+; Verification should succeed.
+; VERIFY: No errors.
+
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+ at q = common global i8* null, align 8, !dbg !102
+ at r = common global i8* null, align 8, !dbg !105
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!6, !7}
+
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5)
+!3 = !DIFile(filename: "/tmp/p.c", directory: "/")
+!4 = !{}
+!5 = !{!102, !105}
+!6 = !{i32 2, !"Dwarf Version", i32 4}
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+
+; marking the types as Swift is necessary because we only emit the linkage names for Swift types.
+!11 = !DICompositeType(tag: DW_TAG_structure_type, name: "SameName", file: !3, size: 64, runtimeLang: DW_LANG_Swift, identifier: "SameName")
+!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "DifferentName", file: !3, size: 64, runtimeLang: DW_LANG_Swift, identifier: "UniqueDifferentName")
+
+!102 = !DIGlobalVariableExpression(var: !103, expr: !DIExpression())
+!103 = distinct !DIGlobalVariable(name: "q", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true)
+!104 = distinct !DIGlobalVariable(name: "r", scope: !2, file: !3, line: 1, type: !12, isLocal: false, isDefinition: true)
+!105 = !DIGlobalVariableExpression(var: !104, expr: !DIExpression())
>From 47a8ef3a7bb09e8148fcd99bcd1ce795d59f0ee5 Mon Sep 17 00:00:00 2001
From: Augusto Noronha <anoronha at apple.com>
Date: Fri, 18 Oct 2024 15:19:01 -0700
Subject: [PATCH 2/3] restrict linkage name in accel table to swift
---
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 3 ++-
llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 1 +
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 08154de9418b77..75b80add8e3dba 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -657,7 +657,8 @@ void DwarfUnit::updateAcceleratorTables(const DIScope *Context,
Flags);
if (auto *CT = dyn_cast<DICompositeType>(Ty))
- if (Ty->getName() != CT->getIdentifier())
+ if (Ty->getName() != CT->getIdentifier() &&
+ CT->getRuntimeLang() == dwarf::DW_LANG_Swift)
DD->addAccelType(*this, CUNode->getNameTableKind(), CT->getIdentifier(),
TyDIE, Flags);
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index adfb920abb9387..0b317404c4d685 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -1854,6 +1854,7 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
}
if (Success && AttrInfo.MangledName &&
+ RuntimeLang == dwarf::DW_LANG_Swift &&
!AttrInfo.MangledName.getString().empty() &&
AttrInfo.MangledName != AttrInfo.Name) {
auto Hash = djbHash(AttrInfo.MangledName.getString().data());
>From 6a63b7a2f3d2106eb2f133b76dca0b4638b3fb98 Mon Sep 17 00:00:00 2001
From: Augusto Noronha <anoronha at apple.com>
Date: Mon, 21 Oct 2024 15:17:20 -0700
Subject: [PATCH 3/3] Fix test
---
llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 1 +
.../debug-names-accel-table-types.test | 58 ++++++++++++-------
2 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 0b317404c4d685..d2b3561ee1c802 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -1853,6 +1853,7 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
Hash);
}
+ // For Swift, mangled names are put into DW_AT_linkage_name.
if (Success && AttrInfo.MangledName &&
RuntimeLang == dwarf::DW_LANG_Swift &&
!AttrInfo.MangledName.getString().empty() &&
diff --git a/llvm/test/tools/dsymutil/debug-names-accel-table-types.test b/llvm/test/tools/dsymutil/debug-names-accel-table-types.test
index 90cdaded8523a9..7811942c2deb89 100644
--- a/llvm/test/tools/dsymutil/debug-names-accel-table-types.test
+++ b/llvm/test/tools/dsymutil/debug-names-accel-table-types.test
@@ -15,8 +15,8 @@
; CHECK: DW_AT_name ("DifferentName")
; CHECK: DW_AT_linkage_name ("UniqueDifferentName")
-; The name count should be 5 (the two variables, the two human readable names, one mangled name).
-; SAME-NAME: Name count: 5
+; The name count should be 5 (the two variables, "int", "SameName", "DifferentName", "UniqueDifferentName").
+; SAME-NAME: Name count: 6
; The accelarator should only have one entry for the three following names.
; SAME-NAME: "SameName"
@@ -31,26 +31,40 @@
; Verification should succeed.
; VERIFY: No errors.
-target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+; ModuleID = 't.c'
+source_filename = "t.c"
+target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-n32:64-S128-Fn32"
+target triple = "arm64-apple-macosx14.5.0"
- at q = common global i8* null, align 8, !dbg !102
- at r = common global i8* null, align 8, !dbg !105
+%struct.SameName = type { i32 }
+%struct.DifferentName = type { i32 }
+ at q = global %struct.SameName zeroinitializer, align 4, !dbg !0
+ at r = global %struct.DifferentName zeroinitializer, align 4, !dbg !5
+
+!llvm.module.flags = !{!14, !15, !16, !17, !18, !19, !20}
!llvm.dbg.cu = !{!2}
-!llvm.module.flags = !{!6, !7}
-
-!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5)
-!3 = !DIFile(filename: "/tmp/p.c", directory: "/")
-!4 = !{}
-!5 = !{!102, !105}
-!6 = !{i32 2, !"Dwarf Version", i32 4}
-!7 = !{i32 2, !"Debug Info Version", i32 3}
-
-; marking the types as Swift is necessary because we only emit the linkage names for Swift types.
-!11 = !DICompositeType(tag: DW_TAG_structure_type, name: "SameName", file: !3, size: 64, runtimeLang: DW_LANG_Swift, identifier: "SameName")
-!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "DifferentName", file: !3, size: 64, runtimeLang: DW_LANG_Swift, identifier: "UniqueDifferentName")
-
-!102 = !DIGlobalVariableExpression(var: !103, expr: !DIExpression())
-!103 = distinct !DIGlobalVariable(name: "q", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true)
-!104 = distinct !DIGlobalVariable(name: "r", scope: !2, file: !3, line: 1, type: !12, isLocal: false, isDefinition: true)
-!105 = !DIGlobalVariableExpression(var: !104, expr: !DIExpression())
+!llvm.ident = !{!21}
+
+!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
+!1 = distinct !DIGlobalVariable(name: "q", scope: !2, file: !3, line: 9, type: !11, isLocal: false, isDefinition: true)
+!2 = distinct !DICompileUnit(language: DW_LANG_C11, file: !3, producer: "clang version 1", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, globals: !4, splitDebugInlining: false, nameTableKind: Apple)
+!3 = !DIFile(filename: "t.c", directory: "/")
+!4 = !{!0, !5}
+!5 = !DIGlobalVariableExpression(var: !6, expr: !DIExpression())
+!6 = distinct !DIGlobalVariable(name: "r", scope: !2, file: !3, line: 10, type: !7, isLocal: false, isDefinition: true)
+!7 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "DifferentName", file: !3, line: 5, size: 32, runtimeLang: DW_LANG_Swift, identifier: "UniqueDifferentName", elements: !8)
+!8 = !{!9}
+!9 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !7, file: !3, line: 6, baseType: !10, size: 32)
+!10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+!11 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "SameName", file: !3, line: 1, size: 32, runtimeLang: DW_LANG_Swift, identifier: "SameName", elements: !12)
+!12 = !{!13}
+!13 = !DIDerivedType(tag: DW_TAG_member, name: "i", scope: !11, file: !3, line: 2, baseType: !10, size: 32)
+!14 = !{i32 2, !"SDK Version", [2 x i32] [i32 14, i32 5]}
+!15 = !{i32 7, !"Dwarf Version", i32 4}
+!16 = !{i32 2, !"Debug Info Version", i32 3}
+!17 = !{i32 1, !"wchar_size", i32 4}
+!18 = !{i32 8, !"PIC Level", i32 2}
+!19 = !{i32 7, !"uwtable", i32 1}
+!20 = !{i32 7, !"frame-pointer", i32 1}
+!21 = !{!"clang version 1"}
More information about the llvm-commits
mailing list