[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