Skip to content

Commit 7568a99

Browse files
authored
[dsymutil] Fix parallel linker's self-recursive typedef DIE by including referred-to types into synthetic name (#166767)
**TL;DR:** See #166675 for description of the problem, the root cause, and one solution. This patch is the "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 debug prints 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 #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 #166673 to be fixed. A **hypothetical** caveat is that it would 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). # Tests ``` cd ~/public_llvm/build bin/llvm-lit -a \ ../llvm-project/llvm/test/tools/dsymutil/typedefs-with-same-name.test \ ../llvm-project/llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-fwd-declaration.test ```
1 parent 92e2404 commit 7568a99

File tree

4 files changed

+49
-6
lines changed

4 files changed

+49
-6
lines changed

llvm/lib/DWARFLinker/Parallel/SyntheticTypeNameBuilder.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,10 @@ Error SyntheticTypeNameBuilder::addTypeName(UnitEntryPairTy InputUnitEntryPair,
377377
} break;
378378
}
379379

380-
// If name for the DIE is not determined yet add referenced types to the name.
381-
if (!HasLinkageName && !HasShortName && !HasDeclFileName) {
380+
// If name for the DIE is not determined yet or if the DIE is a typedef, add
381+
// referenced types to the name.
382+
if ((!HasLinkageName && !HasShortName && !HasDeclFileName) ||
383+
InputUnitEntryPair.DieEntry->getTag() == dwarf::DW_TAG_typedef) {
382384
if (InputUnitEntryPair.CU->find(InputUnitEntryPair.DieEntry,
383385
getODRAttributes()))
384386
if (Error Err = addReferencedODRDies(InputUnitEntryPair, AddParentNames,
2.03 KB
Binary file not shown.

llvm/test/tools/dsymutil/X86/DWARFLinkerParallel/odr-fwd-declaration.test

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ void foo() { Sptrptr ptr1 = 0; }
3535
// CHECK: DW_TAG_member
3636
// CHECK-NEXT: DW_AT_name{{.*}}"field"
3737

38-
// CHECK: 0x[[TYPEDEF_PTR_S]]: DW_TAG_typedef
39-
// CHECK-NEXT: DW_AT_type{{.*}}{0x[[PTR_S]]} "S *"
40-
// CHECK-NEXT: DW_AT_name{{.*}}"Sptr"
41-
4238
// CHECK: 0x[[TYPEDEF_PTR_PTR_S:[a-f0-9]*]]: DW_TAG_typedef
4339
// CHECK-NEXT: DW_AT_type{{.*}}{0x[[PTR_PTR_S]]} "Sptr *"
4440
// CHECK-NEXT: DW_AT_name{{.*}}"Sptrptr"
4541

42+
// CHECK: 0x[[TYPEDEF_PTR_S]]: DW_TAG_typedef
43+
// CHECK-NEXT: DW_AT_type{{.*}}{0x[[PTR_S]]} "S *"
44+
// CHECK-NEXT: DW_AT_name{{.*}}"Sptr"
45+
4646
// First we confirm that first compile unit properly references type.
4747
//
4848
// CHECK: DW_TAG_compile_unit
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#RUN: dsymutil --linker=parallel -f -oso-prepend-path=%p/Inputs/ -y %s -o %t.dwarf
2+
#RUN: llvm-dwarfdump %t.dwarf | FileCheck %s
3+
4+
# There should be two typedef DIE named "BarInt" in the resultant .dwarf file.
5+
# The second should refer to the first, which refer to "Foo<int>".
6+
# CHECK: 0x[[FIRST_BARINT_ADDR:[0-9a-f]*]]: DW_TAG_typedef
7+
# CHECK-NEXT: DW_AT_type (0x{{([[:xdigit:]]*)}} "Foo<int>")
8+
# CHECK-NEXT: DW_AT_name ("BarInt")
9+
# CHECK: 0x{{([[:xdigit:]]*)}}: DW_TAG_typedef
10+
# CHECK-NEXT: DW_AT_type (0x[[FIRST_BARINT_ADDR]] "BarInt")
11+
# CHECK-NEXT: DW_AT_name ("BarInt")
12+
13+
# Source:
14+
#
15+
# template <typename T> struct Foo;
16+
# typedef Foo<int> BarInt;
17+
# template <typename T>
18+
# struct [[clang::preferred_name(BarInt)]] Foo{};
19+
# int main() {
20+
# BarInt barInt;
21+
# return 0;
22+
# }
23+
#
24+
# Compile with:
25+
#
26+
# $ clang++ -g -O0 -c typedefs-with-same-name.cpp -o typedefs-with-same-name.o
27+
#
28+
# To generate the debug map:
29+
#
30+
# $ clang++ typedefs-with-same-name.o -o typedefs-with-same-name
31+
# $ dsymutil -dump-debug-map typedefs-with-same-name
32+
33+
---
34+
triple: 'arm64-apple-darwin'
35+
objects:
36+
- filename: '/typedefs-with-same-name.o'
37+
timestamp: 1762438746
38+
type: 102
39+
symbols:
40+
- { sym: _main, objAddr: 0x0, binAddr: 0x100000360, size: 0x14 }
41+
...

0 commit comments

Comments
 (0)