[llvm] [dsymutil] Fix parallel linker's self-recursive typedef DIE by including referred-to types into synthetic name (PR #166767)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Nov 6 07:23:15 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-debuginfo
Author: Roy Shi (royitaqi)
<details>
<summary>Changes</summary>
See #<!-- -->166675 for description of the problem, the root cause, and one solution. This patch is a "different implementation" descried there.
This patch tries to fix the problem by recursively including the referred-to types into the synthetic name. This way, the synthetic name of the typedef DIE is canonicalized. See example below:
```
SyntheticTypeNameBuilder::addDIETypeName() is called for DIE at offset 0x0000004c
SyntheticName = {H}BarInt{F}Foo<int>:() <- Two different names
Assigned to type descriptor. TypeEntryPtr = 0x0000004c0x0x150020a38 <- Hence different type entries
SyntheticTypeNameBuilder::addDIETypeName() is called for DIE at offset 0x00000044
SyntheticName = {H}BarInt{H}BarInt{F}Foo<int>:() <- Two different names
Assigned to type descriptor. TypeEntryPtr = 0x000000440x0x150020a60 <- Hence different type entries
```
The advantages of this approach over https://github.com/llvm/llvm-project/pull/166675 are:
1. The resulting synthetic name is more "correct" than using decl file and line (which _can_ still collide).
1. This doesn't depend on https://github.com/llvm/llvm-project/issues/166673 to be fixed.
Caveat is that it won't work if any of the referenced types resolve to the same name for some reason (similar to how the two typedefs resolved to the same name before this patch).
---
Full diff: https://github.com/llvm/llvm-project/pull/166767.diff
3 Files Affected:
- (modified) llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp (+4-2)
- (added) llvm/test/tools/dsymutil/Inputs/typedefs-with-same-name.o ()
- (added) llvm/test/tools/dsymutil/typedefs-with-same-name.test (+41)
``````````diff
diff --git a/llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp b/llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp
index 34174f98b7e37..ca918f6e17b38 100644
--- a/llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp
+++ b/llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp
@@ -377,8 +377,10 @@ Error SyntheticTypeNameBuilder::addTypeName(UnitEntryPairTy InputUnitEntryPair,
} break;
}
- // If name for the DIE is not determined yet add referenced types to the name.
- if (!HasLinkageName && !HasShortName && !HasDeclFileName) {
+ // If name for the DIE is not determined yet or if the DIE is a typedef, add
+ // referenced types to the name.
+ if ((!HasLinkageName && !HasShortName && !HasDeclFileName) ||
+ InputUnitEntryPair.DieEntry->getTag() == dwarf::DW_TAG_typedef) {
if (InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry,
getODRAttributes()))
if (Error Err = addReferencedODRDies(InputUnitEntryPair, AddParentNames,
diff --git a/llvm/test/tools/dsymutil/Inputs/typedefs-with-same-name.o b/llvm/test/tools/dsymutil/Inputs/typedefs-with-same-name.o
new file mode 100644
index 0000000000000..6cc47c1a783b3
Binary files /dev/null and b/llvm/test/tools/dsymutil/Inputs/typedefs-with-same-name.o differ
diff --git a/llvm/test/tools/dsymutil/typedefs-with-same-name.test b/llvm/test/tools/dsymutil/typedefs-with-same-name.test
new file mode 100644
index 0000000000000..96ec583293977
--- /dev/null
+++ b/llvm/test/tools/dsymutil/typedefs-with-same-name.test
@@ -0,0 +1,41 @@
+#RUN: dsymutil --linker=parallel -f -oso-prepend-path=%p/Inputs/ -y %s -o %t.dwarf
+#RUN: llvm-dwarfdump %t.dwarf | FileCheck %s
+
+# There should be two typedef DIE named "BarInt" in the resultant .dwarf file.
+# The second should refer to the first, which refer to "Foo<int>".
+# CHECK: 0x[[FIRST_BARINT_ADDR:[0-9a-f]{8}]]: DW_TAG_typedef
+# CHECK-NEXT: DW_AT_type (0x{{([[:xdigit:]]{8})}} "Foo<int>")
+# CHECK-NEXT: DW_AT_name ("BarInt")
+# CHECK: 0x{{([[:xdigit:]]{8})}}: DW_TAG_typedef
+# CHECK-NEXT: DW_AT_type (0x[[FIRST_BARINT_ADDR]] "BarInt")
+# CHECK-NEXT: DW_AT_name ("BarInt")
+
+# Source:
+#
+# template <typename T> struct Foo;
+# typedef Foo<int> BarInt;
+# template <typename T>
+# struct [[clang::preferred_name(BarInt)]] Foo{};
+# int main() {
+# BarInt barInt;
+# return 0;
+# }
+#
+# Compile with:
+#
+# $ clang++ -g -O0 -c typedefs-with-same-name.cpp -o typedefs-with-same-name.o
+#
+# To generate the debug map:
+#
+# $ clang++ typedefs-with-same-name.o -o typedefs-with-same-name
+# $ dsymutil -dump-debug-map typedefs-with-same-name
+
+---
+triple: 'arm64-apple-darwin'
+objects:
+ - filename: '/typedefs-with-same-name.o'
+ timestamp: 1762438746
+ type: 102
+ symbols:
+ - { sym: _main, objAddr: 0x0, binAddr: 0x100000360, size: 0x14 }
+...
``````````
</details>
https://github.com/llvm/llvm-project/pull/166767
More information about the llvm-commits
mailing list