-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[DebugInfo] Emit linkage name into DWARF for types for Swift #112802
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[DebugInfo] Emit linkage name into DWARF for types for Swift #112802
Conversation
@llvm/pr-subscribers-debuginfo Author: Augusto Noronha (augusto2112) ChangesStore Swift mangled names in DW_AT_linkage_name. Additionally, emit types linkage names for types into the accelerator table if they exist and they're different from the display name. Full diff: https://github.com/llvm/llvm-project/pull/112802.diff 4 Files Affected:
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index e76b0fe2081c07..715968c335ca03 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -645,15 +645,21 @@ 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);
+ 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..88bc494439f6cf 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,18 @@ 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()[0]) {
+ uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit, File);
+ Unit.addTypeAccelerator(Die, AttrInfo.Name, ObjCClassIsImplementation,
+ Hash);
+ }
+
+ if (Success && AttrInfo.MangledName &&
+ 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"
+
+@q = common global i8* null, align 8, !dbg !102
+@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"
+
+@q = common global i8* null, align 8, !dbg !102
+@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())
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
Out of curiosity: what's the need/use case? |
We use the mangled names to find type information both in Swift metadata and Swift modules. |
To expand a bit on this: 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. The compiler also have a separate mode where it emits more full debug information so LLDB doesn't need to rely on in reflection metadata/Swift modules existing (that's related to my other "number of extra inhabitants" patch). |
so why is this code change needed? Because up until now the mangled name has been put in DW_AT_name, so didn't need LLVM-side support? Or it's been in downstream patches that are being upstreamed? It'd be good to know about what's new/different/etc to add this change now (even if it's just "we've been doing this downstream for a while, and now have time to upstream it" (in which case a bit of info about the original decision that added the functionality would be handy too - but I think you've mostly covered that in this comment, perhaps)) |
Right, emitting linkage names for types has been downstream for a really long time. Emitting the type linkage names into accelerator tables is new behavior, which is needed to do global searches by linkage names (I'll have another patch soon on the LLDB side to support |
c5ad77c
to
e2a5a66
Compare
I've updated the commit message to explain why we'd want type mangled names in DWARF. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SGTM
I've restricted emitting linkage names into accelerator tables to Swift only since some tests were failing it should be the only language (as far as I'm aware) that uses mangled names for types pervasively anyway. I can also keep it generic and update the tests. |
The |
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.
29e9a7b
to
5141bea
Compare
d09a187
to
6a63b7a
Compare
6a63b7a
to
ac85d19
Compare
…2802) 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. (cherry picked from commit 8234f8a)
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.