Skip to content

Commit

Permalink
[DebugInfo] Emit linkage name into DWARF for types for Swift (#112802)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
augusto2112 authored Oct 22, 2024
1 parent 4c1b1f6 commit 8234f8a
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 9 deletions.
17 changes: 14 additions & 3 deletions llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -645,16 +645,23 @@ 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() &&
CT->getRuntimeLang() == dwarf::DW_LANG_Swift)
DD->addAccelType(*this, CUNode->getNameTableKind(), CT->getIdentifier(),
TyDIE, Flags);

addGlobalType(Ty, TyDIE, Context);
}

Expand Down Expand Up @@ -1042,6 +1049,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 ||
Expand Down
23 changes: 17 additions & 6 deletions llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -1849,8 +1847,21 @@ 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);
}

// For Swift, mangled names are put into DW_AT_linkage_name.
if (Success && AttrInfo.MangledName &&
RuntimeLang == dwarf::DW_LANG_Swift &&
!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.
Expand Down
55 changes: 55 additions & 0 deletions llvm/test/DebugInfo/Generic/debug-names-accel-table-types.ll
Original file line number Diff line number Diff line change
@@ -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())
70 changes: 70 additions & 0 deletions llvm/test/tools/dsymutil/ARM/debug-names-accel-table-types.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
; 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, "int", "SameName", "DifferentName", "UniqueDifferentName").
; SAME-NAME: Name count: 6

; 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.

; 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"

%struct.SameName = type { i32 }
%struct.DifferentName = type { i32 }

@q = global %struct.SameName zeroinitializer, align 4, !dbg !0
@r = global %struct.DifferentName zeroinitializer, align 4, !dbg !5

!llvm.module.flags = !{!14, !15, !16, !17, !18, !19, !20}
!llvm.dbg.cu = !{!2}
!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"}

0 comments on commit 8234f8a

Please sign in to comment.