[llvm] 125c8d3 - [DWARFLinker] Index Swift mangled type names in the parallel linker (#216429)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Aug 14 19:31:48 PDT 2026
Author: Jonas Devlieghere
Date: 2026-08-14T19:31:43-07:00
New Revision: 125c8d39b441dd99f1b1d55b536ad0d821b8fb71
URL: https://github.com/llvm/llvm-project/commit/125c8d39b441dd99f1b1d55b536ad0d821b8fb71
DIFF: https://github.com/llvm/llvm-project/commit/125c8d39b441dd99f1b1d55b536ad0d821b8fb71.diff
LOG: [DWARFLinker] Index Swift mangled type names in the parallel linker (#216429)
Swift records a type's mangled name in DW_AT_linkage_name. The classic
linker indexes it as a type accelerator entry alongside the short
DW_AT_name, but the parallel linker indexed only the short name.
Port the DW_LANG_Swift block added to the classic linker in 8234f8ae2685
to the parallel linker's type case.
Added:
llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/debug-names-swift-mangled-type.s
Modified:
llvm/lib/DWARFLinker/Parallel/AcceleratorRecordsSaver.cpp
llvm/test/tools/dsymutil/AArch64/debug-names-accel-table-types.ll
llvm/test/tools/dsymutil/AArch64/lit.local.cfg
Removed:
################################################################################
diff --git a/llvm/lib/DWARFLinker/Parallel/AcceleratorRecordsSaver.cpp b/llvm/lib/DWARFLinker/Parallel/AcceleratorRecordsSaver.cpp
index 701ff7e0c96b5..ab73a3fce8b4a 100644
--- a/llvm/lib/DWARFLinker/Parallel/AcceleratorRecordsSaver.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/AcceleratorRecordsSaver.cpp
@@ -102,25 +102,46 @@ void AcceleratorRecordsSaver::save(const DWARFDebugInfoEntry *InputDieEntry,
case dwarf::DW_TAG_shared_type:
case dwarf::DW_TAG_immutable_type:
case dwarf::DW_TAG_rvalue_reference_type: {
- if (!AttrInfo.IsDeclaration && AttrInfo.Name != nullptr &&
- !AttrInfo.Name->getKey().empty()) {
+ if (AttrInfo.IsDeclaration)
+ break;
+
+ // hashFullyQualifiedName() advances InputDIE along the specification and
+ // abstract origin chain, so the DIE's own attributes have to be read first.
+
+ // The linkage name may be attached to the declaration rather than to the
+ // definition.
+ if (!AttrInfo.MangledName)
+ if (const char *LinkageName = InputDIE.getLinkageName())
+ AttrInfo.MangledName =
+ GlobalData.getStringPool().insert(LinkageName).first;
+
+ uint64_t RuntimeLang =
+ dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class))
+ .value_or(0);
+
+ bool ObjCClassIsImplementation =
+ (RuntimeLang == dwarf::DW_LANG_ObjC ||
+ RuntimeLang == dwarf::DW_LANG_ObjC_plus_plus) &&
+ dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_objc_complete_type))
+ .value_or(0);
+
+ if (AttrInfo.Name != nullptr && !AttrInfo.Name->getKey().empty()) {
uint32_t Hash = hashFullyQualifiedName(InUnit, InputDIE);
-
- uint64_t RuntimeLang =
- dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class))
- .value_or(0);
-
- bool ObjCClassIsImplementation =
- (RuntimeLang == dwarf::DW_LANG_ObjC ||
- RuntimeLang == dwarf::DW_LANG_ObjC_plus_plus) &&
- dwarf::toUnsigned(
- InputDIE.find(dwarf::DW_AT_APPLE_objc_complete_type))
- .value_or(0);
-
saveTypeRecord(InputDieEntry, AttrInfo.Name, OutDIE,
InputDieEntry->getTag(), Hash, ObjCClassIsImplementation,
TypeEntry);
}
+
+ // Swift carries a type's mangled name in DW_AT_linkage_name, which a
+ // consumer may look up on its own.
+ if (AttrInfo.MangledName != nullptr &&
+ RuntimeLang == dwarf::DW_LANG_Swift &&
+ !AttrInfo.MangledName->getKey().empty() &&
+ AttrInfo.MangledName != AttrInfo.Name)
+ saveTypeRecord(InputDieEntry, AttrInfo.MangledName, OutDIE,
+ InputDieEntry->getTag(),
+ djbHash(AttrInfo.MangledName->getKey()),
+ ObjCClassIsImplementation, TypeEntry);
} break;
case dwarf::DW_TAG_namespace: {
if (AttrInfo.Name == nullptr)
diff --git a/llvm/test/tools/dsymutil/AArch64/debug-names-accel-table-types.ll b/llvm/test/tools/dsymutil/AArch64/debug-names-accel-table-types.ll
index c8e9f4e3598fa..e3db6b40f96b4 100644
--- a/llvm/test/tools/dsymutil/AArch64/debug-names-accel-table-types.ll
+++ b/llvm/test/tools/dsymutil/AArch64/debug-names-accel-table-types.ll
@@ -1,12 +1,12 @@
; RUN: %llc_dwarf -debugger-tune=lldb -accel-tables=Dwarf -filetype=obj -o %t < %s
-; RUN: dsymutil %t -o %t.dSYM
-; RUN: dsymutil --linker parallel %t -o %t.parallel.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
+; This checks the compiler's output. For a linked dSYM, see
+; X86/DWARFLinkerParallel/debug-names-swift-mangled-type.s.
; CHECK: DW_TAG_structure_type
; CHECK: DW_AT_name ("SameName")
@@ -16,7 +16,7 @@
; CHECK: DW_AT_name ("DifferentName")
; CHECK: DW_AT_linkage_name ("UniqueDifferentName")
-; The name count should be 5 (the two variables, "int", "SameName", "DifferentName", "UniqueDifferentName").
+; The name count should be 6 (the two variables, "int", "SameName", "DifferentName", "UniqueDifferentName").
; SAME-NAME: Name count: 6
; The accelarator should only have one entry for the three following names.
diff --git a/llvm/test/tools/dsymutil/AArch64/lit.local.cfg b/llvm/test/tools/dsymutil/AArch64/lit.local.cfg
index 923d126d8707b..ddbbcd565b68b 100644
--- a/llvm/test/tools/dsymutil/AArch64/lit.local.cfg
+++ b/llvm/test/tools/dsymutil/AArch64/lit.local.cfg
@@ -7,4 +7,4 @@ if config.llvm_use_sanitizer:
)
config.environment["LSAN_OPTIONS"] = "suppressions={}".format(suppr)
-config.suffixes = [".test", ".cpp", ".c"]
+config.suffixes = [".test", ".cpp", ".c", ".ll"]
diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/debug-names-swift-mangled-type.s b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/debug-names-swift-mangled-type.s
new file mode 100644
index 0000000000000..040c985823ff7
--- /dev/null
+++ b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/debug-names-swift-mangled-type.s
@@ -0,0 +1,213 @@
+# A Swift type's mangled name, from DW_AT_linkage_name, is indexed as a type
+# name alongside the short DW_AT_name by both linkers.
+
+# RUN: llvm-mc -triple x86_64-apple-darwin -filetype=obj %s -o %t.o
+# RUN: llvm-dwarfdump --verify %t.o
+
+# RUN: echo '---' > %t.map
+# RUN: echo "triple: 'x86_64-apple-darwin'" >> %t.map
+# RUN: echo 'objects:' >> %t.map
+# RUN: echo " - filename: '%t.o'" >> %t.map
+# RUN: echo ' symbols:' >> %t.map
+# RUN: echo ' - { sym: _foo, objAddr: 0x0, binAddr: 0x10000, size: 0x1 }' >> %t.map
+# RUN: echo '...' >> %t.map
+
+# RUN: dsymutil --linker=parallel -accelerator=Dwarf -y %t.map -f -o %t.parallel.dSYM
+# RUN: llvm-dwarfdump --verify %t.parallel.dSYM
+# RUN: llvm-dwarfdump --debug-names %t.parallel.dSYM > %t.parallel.names
+
+# RUN: dsymutil --linker=classic -accelerator=Dwarf -y %t.map -f -o %t.classic.dSYM
+# RUN: llvm-dwarfdump --verify %t.classic.dSYM
+# RUN: llvm-dwarfdump --debug-names %t.classic.dSYM > %t.classic.names
+
+# The qualified name hash reaches only the Apple tables.
+
+# RUN: dsymutil --linker=parallel -accelerator=Apple -y %t.map -f -o %t.parallel.apple.dSYM
+# RUN: llvm-dwarfdump --apple-types %t.parallel.apple.dSYM > %t.parallel.apple
+
+# RUN: dsymutil --linker=classic -accelerator=Apple -y %t.map -f -o %t.classic.apple.dSYM
+# RUN: llvm-dwarfdump --apple-types %t.classic.apple.dSYM > %t.classic.apple
+
+# One FileCheck run per name, so that no prefix depends on the bucket a linker
+# assigns to the other names.
+
+# RUN: FileCheck %s --check-prefix=MANGLED --input-file %t.parallel.names
+# RUN: FileCheck %s --check-prefix=MANGLED --input-file %t.classic.names
+# RUN: FileCheck %s --check-prefix=SHORT --input-file %t.parallel.names
+# RUN: FileCheck %s --check-prefix=SHORT --input-file %t.classic.names
+# RUN: FileCheck %s --check-prefix=SPEC --input-file %t.parallel.names
+# RUN: FileCheck %s --check-prefix=SPEC --input-file %t.classic.names
+# RUN: FileCheck %s --check-prefix=DEDUP --input-file %t.parallel.names
+# RUN: FileCheck %s --check-prefix=DEDUP --input-file %t.classic.names
+# RUN: FileCheck %s --check-prefix=APPLE --input-file %t.parallel.apple
+# RUN: FileCheck %s --check-prefix=APPLE --input-file %t.classic.apple
+
+# The tag is checked so that the entry is known to describe the type rather
+# than another DIE carrying the same string.
+
+# MANGLED: String: {{.*}} "$sSSD"
+# MANGLED-NEXT: Entry @
+# MANGLED-NEXT: Abbrev:
+# MANGLED-NEXT: Tag: DW_TAG_structure_type
+
+# SHORT: String: {{.*}} "String"
+# SHORT-NEXT: Entry @
+# SHORT-NEXT: Abbrev:
+# SHORT-NEXT: Tag: DW_TAG_structure_type
+
+# A mangled name reachable only through DW_AT_specification.
+
+# SPEC: String: {{.*}} "$sSpecD"
+# SPEC-NEXT: Entry @
+# SPEC-NEXT: Abbrev:
+# SPEC-NEXT: Tag: DW_TAG_structure_type
+
+# A type whose two names are equal is indexed once.
+
+# DEDUP: String: {{.*}} "Same"
+# DEDUP-NOT: String: {{.*}} "Same"
+
+# Atom[3] is djbHash of the mangled name, not the qualified name hash that the
+# short name records.
+
+# APPLE: String: {{.*}} "$sSSD"
+# APPLE-NEXT: Data 0 [
+# APPLE-NEXT: Atom[0]:
+# APPLE-NEXT: Atom[1]: 0x0013 (DW_TAG_structure_type)
+# APPLE-NEXT: Atom[2]: 0x00
+# APPLE-NEXT: Atom[3]: 0x0acaede6
+
+ .section __TEXT,__text,regular,pure_instructions
+ .globl _foo
+_foo:
+Lfunc_begin0:
+ retq
+Lfunc_end0:
+
+ .section __DWARF,__debug_abbrev,regular,debug
+Lsection_abbrev:
+ .byte 1 ## Abbreviation Code
+ .byte 17 ## DW_TAG_compile_unit
+ .byte 1 ## DW_CHILDREN_yes
+ .byte 37 ## DW_AT_producer
+ .byte 8 ## DW_FORM_string
+ .byte 19 ## DW_AT_language
+ .byte 5 ## DW_FORM_data2
+ .byte 3 ## DW_AT_name
+ .byte 8 ## DW_FORM_string
+ .byte 0, 0
+
+ .byte 2 ## Abbreviation Code
+ .byte 46 ## DW_TAG_subprogram
+ .byte 1 ## DW_CHILDREN_yes
+ .byte 3 ## DW_AT_name
+ .byte 8 ## DW_FORM_string
+ .byte 73 ## DW_AT_type
+ .byte 19 ## DW_FORM_ref4
+ .byte 17 ## DW_AT_low_pc
+ .byte 1 ## DW_FORM_addr
+ .byte 18 ## DW_AT_high_pc
+ .byte 6 ## DW_FORM_data4
+ .byte 0, 0
+
+ .byte 3 ## Abbreviation Code
+ .byte 19 ## DW_TAG_structure_type
+ .byte 0 ## DW_CHILDREN_no
+ .byte 3 ## DW_AT_name
+ .byte 8 ## DW_FORM_string
+ .byte 110 ## DW_AT_linkage_name
+ .byte 8 ## DW_FORM_string
+ .byte 11 ## DW_AT_byte_size
+ .byte 11 ## DW_FORM_data1
+ .byte 0xe6, 0x7f ## DW_AT_APPLE_runtime_class (0x3fe6)
+ .byte 5 ## DW_FORM_data2
+ .byte 0, 0
+
+ .byte 4 ## Abbreviation Code
+ .byte 5 ## DW_TAG_formal_parameter
+ .byte 0 ## DW_CHILDREN_no
+ .byte 73 ## DW_AT_type
+ .byte 19 ## DW_FORM_ref4
+ .byte 0, 0
+
+ .byte 5 ## Abbreviation Code
+ .byte 19 ## DW_TAG_structure_type
+ .byte 0 ## DW_CHILDREN_no
+ .byte 3 ## DW_AT_name
+ .byte 8 ## DW_FORM_string
+ .byte 110 ## DW_AT_linkage_name
+ .byte 8 ## DW_FORM_string
+ .byte 60 ## DW_AT_declaration
+ .byte 25 ## DW_FORM_flag_present
+ .byte 0, 0
+
+ .byte 6 ## Abbreviation Code
+ .byte 19 ## DW_TAG_structure_type
+ .byte 0 ## DW_CHILDREN_no
+ .byte 71 ## DW_AT_specification
+ .byte 19 ## DW_FORM_ref4
+ .byte 11 ## DW_AT_byte_size
+ .byte 11 ## DW_FORM_data1
+ .byte 0xe6, 0x7f ## DW_AT_APPLE_runtime_class (0x3fe6)
+ .byte 5 ## DW_FORM_data2
+ .byte 0, 0
+
+ .byte 0 ## EOM(3)
+
+ .section __DWARF,__debug_info,regular,debug
+Lsection_info:
+ .long Lcu_end - Lcu_start ## Length of Unit
+Lcu_start:
+ .short 4 ## DWARF version number
+ .long 0 ## Offset Into Abbrev. Section
+ .byte 8 ## Address Size (in bytes)
+
+ .byte 1 ## Abbrev [1] DW_TAG_compile_unit
+ .asciz "hand-written" ## DW_AT_producer
+ .short 0x001e ## DW_AT_language (DW_LANG_Swift)
+ .asciz "swift-mangled-type.swift" ## DW_AT_name
+
+ .byte 2 ## Abbrev [2] DW_TAG_subprogram
+ .asciz "foo" ## DW_AT_name
+ .long Lstring - Lsection_info ## DW_AT_type
+ .quad Lfunc_begin0 ## DW_AT_low_pc
+ .long Lfunc_end0 - Lfunc_begin0 ## DW_AT_high_pc
+
+ .byte 4 ## Abbrev [4] DW_TAG_formal_parameter
+ .long Lsame - Lsection_info ## DW_AT_type
+
+ .byte 4 ## Abbrev [4] DW_TAG_formal_parameter
+ .long Lspec_defn - Lsection_info ## DW_AT_type
+
+ .byte 0 ## End Of Children Mark (subprogram)
+
+Lstring:
+ .byte 3 ## Abbrev [3] DW_TAG_structure_type
+ .asciz "String" ## DW_AT_name
+ .asciz "$sSSD" ## DW_AT_linkage_name
+ .byte 16 ## DW_AT_byte_size
+ .short 0x001e ## DW_AT_APPLE_runtime_class (DW_LANG_Swift)
+
+# DW_AT_name and DW_AT_linkage_name are the same string.
+Lsame:
+ .byte 3 ## Abbrev [3] DW_TAG_structure_type
+ .asciz "Same" ## DW_AT_name
+ .asciz "Same" ## DW_AT_linkage_name
+ .byte 8 ## DW_AT_byte_size
+ .short 0x001e ## DW_AT_APPLE_runtime_class (DW_LANG_Swift)
+
+# Neither name is on the definition, so both come from the declaration.
+Lspec_decl:
+ .byte 5 ## Abbrev [5] DW_TAG_structure_type
+ .asciz "Spec" ## DW_AT_name
+ .asciz "$sSpecD" ## DW_AT_linkage_name
+ ## DW_AT_declaration
+
+Lspec_defn:
+ .byte 6 ## Abbrev [6] DW_TAG_structure_type
+ .long Lspec_decl - Lsection_info ## DW_AT_specification
+ .byte 8 ## DW_AT_byte_size
+ .short 0x001e ## DW_AT_APPLE_runtime_class (DW_LANG_Swift)
+
+ .byte 0 ## End Of Children Mark (CU)
+Lcu_end:
More information about the llvm-commits
mailing list