[llvm] [DWARFLinker] Preserve source order of member subprograms (PR #196443)
via llvm-commits
llvm-commits at lists.llvm.org
Thu May 7 16:47:11 PDT 2026
llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
Author: Jonas Devlieghere (JDevlieghere)
<details>
<summary>Changes</summary>
DW_TAG_subprogram was missing from tagToArrayIndex, so member functions had no ordering prefix in their synthetic key and ended up sorted alphabetically by TypePool.
---
Full diff: https://github.com/llvm/llvm-project/pull/196443.diff
2 Files Affected:
- (modified) llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp (+15)
- (modified) llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-member-functions.cpp (+17-17)
``````````diff
diff --git a/llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp b/llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp
index ca918f6e17b38..b908ae5da492a 100644
--- a/llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp
@@ -413,6 +413,15 @@ Error SyntheticTypeNameBuilder::addDIETypeName(
if (ChildIndex) {
addOrderedName(*ChildIndex);
+ // Subprograms can legitimately differ at the same source position
+ // across CUs (e.g. distinct template instantiations of the same
+ // class member). Appending the content-based name keeps the ordered
+ // prefix for sort stability while preventing such siblings from
+ // collapsing during type uniquing.
+ if (UnitEntryPair->DieEntry->getTag() == dwarf::DW_TAG_subprogram) {
+ if (Error Err = addTypeName(*UnitEntryPair, AssignNameToTypeDescriptor))
+ return Err;
+ }
} else {
if (Error Err = addTypeName(*UnitEntryPair, AssignNameToTypeDescriptor))
return Err;
@@ -741,6 +750,12 @@ std::optional<size_t> OrderedChildrenIndexAssigner::tagToArrayIndex(
case dwarf::DW_TAG_namelist_item:
return 6;
case dwarf::DW_TAG_member:
+ case dwarf::DW_TAG_subprogram:
+ // Subprograms share this bucket with data members so that class members
+ // retain source order in the output. Unlike data members, subprograms
+ // also keep their content-based name (see addDIETypeName) so that
+ // siblings at the same position but with different signatures or
+ // template arguments remain distinguishable.
return 7;
default:
return std::nullopt;
diff --git a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-member-functions.cpp b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-member-functions.cpp
index 480cef1bf2648..0200377e3701d 100644
--- a/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-member-functions.cpp
+++ b/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-member-functions.cpp
@@ -37,6 +37,23 @@ void foo() { S s; }
// CHECK: 0x[[STRUCT_S]]:{{.*}}DW_TAG_structure_type
// CHECK-NEXT: DW_AT_name{{.*}}"S"
+// CHECK: 0x[[FOO_Ev:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram
+// CHECK: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S3fooEv"
+// CHECK: DW_AT_name{{.*}}"foo"
+
+// CHECK: DW_TAG_formal_parameter
+// CHECK-NEXT: DW_AT_type{{.*}}0x[[PTR_S]] "S *"
+
+// CHECK: 0x[[FOO_Ei:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram
+// CHECK: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S3fooEi"
+// CHECK: DW_AT_name{{.*}}"foo"
+
+// CHECK: DW_TAG_formal_parameter
+// CHECK-NEXT: DW_AT_type{{.*}}0x[[PTR_S]] "S *"
+
+// CHECK: DW_TAG_formal_parameter
+// CHECK-NEXT: DW_AT_type{{.*}}0x[[INT_BASE]] "int"
+
// CHECK: DW_TAG_subprogram
// CHECK: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S3barEv"
// CHECK: DW_AT_name{{.*}}"bar"
@@ -58,23 +75,6 @@ void foo() { S s; }
// CHECK-NEXT: DW_AT_type{{.*}}0x[[INT_BASE]] "int"
// CHECK-NEXT: DW_AT_name{{.*}}"T"
-// CHECK: 0x[[FOO_Ei:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram
-// CHECK: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S3fooEi"
-// CHECK: DW_AT_name{{.*}}"foo"
-
-// CHECK: DW_TAG_formal_parameter
-// CHECK-NEXT: DW_AT_type{{.*}}0x[[PTR_S]] "S *"
-
-// CHECK: DW_TAG_formal_parameter
-// CHECK-NEXT: DW_AT_type{{.*}}0x[[INT_BASE]] "int"
-
-// CHECK: 0x[[FOO_Ev:[0-9a-f]*]]:{{.*}}DW_TAG_subprogram
-// CHECK: DW_AT_MIPS_linkage_name{{.*}}"_ZN1S3fooEv"
-// CHECK: DW_AT_name{{.*}}"foo"
-
-// CHECK: DW_TAG_formal_parameter
-// CHECK-NEXT: DW_AT_type{{.*}}0x[[PTR_S]] "S *"
-
// For the second unit check that it references structure "S"
// CHECK: TAG_compile_unit
``````````
</details>
https://github.com/llvm/llvm-project/pull/196443
More information about the llvm-commits
mailing list