[llvm] [llvm][DebugInfo] Support DW_AT_linkage_names that are different between declaration and definition (PR #154137)
Michael Buch via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 18 08:42:51 PDT 2025
https://github.com/Michael137 created https://github.com/llvm/llvm-project/pull/154137
This patch is motivated by https://github.com/llvm/llvm-project/pull/149827, where we plan on using mangled names on structor declarations to find the exact structor definition that LLDB's expression evaluator should call.
So far LLVM expects the declaration and definition linkage names to be identical (or the declaration to just not have a linkage name). But we plan on attaching the GCC-style "unified" mangled name to declarations, which will be different to linkage name on the definition. This patch relaxes this restriction.
>From 62641a7cc6b439c747be0a9ae91b9b266d67816e Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 18 Aug 2025 15:12:45 +0100
Subject: [PATCH] [llvm][DebugInfo] Support DW_AT_linkage_names that are
different between declaration and definition
---
llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp | 7 +-
.../structor-declaration-linkage-names.ll | 68 +++++++++++++++++++
2 files changed, 70 insertions(+), 5 deletions(-)
create mode 100644 llvm/test/DebugInfo/Generic/structor-declaration-linkage-names.ll
diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index b03fac2d22a52..4904ad03199c7 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -1403,11 +1403,8 @@ bool DwarfUnit::applySubprogramDefinitionAttributes(const DISubprogram *SP,
// Add the linkage name if we have one and it isn't in the Decl.
StringRef LinkageName = SP->getLinkageName();
- assert(((LinkageName.empty() || DeclLinkageName.empty()) ||
- LinkageName == DeclLinkageName) &&
- "decl has a linkage name and it is different");
- if (DeclLinkageName.empty() &&
- // Always emit it for abstract subprograms.
+ // Always emit linkage name for abstract subprograms.
+ if (DeclLinkageName != LinkageName &&
(DD->useAllLinkageNames() || DU->getAbstractScopeDIEs().lookup(SP)))
addLinkageName(SPDie, LinkageName);
diff --git a/llvm/test/DebugInfo/Generic/structor-declaration-linkage-names.ll b/llvm/test/DebugInfo/Generic/structor-declaration-linkage-names.ll
new file mode 100644
index 0000000000000..9b1f2a5b2a186
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/structor-declaration-linkage-names.ll
@@ -0,0 +1,68 @@
+; RUN: %llc_dwarf < %s -filetype=obj | llvm-dwarfdump -debug-info - | FileCheck %s
+
+; Make sure we attach DW_AT_linkage_name on function declarations but only
+; attach it on definitions if the value is different than on the declaration.
+
+target triple = "arm64-apple-macosx"
+
+define void @_Z11SameLinkagev() !dbg !4 {
+entry:
+ ret void
+}
+
+; CHECK: DW_AT_linkage_name ("_Z11SameLinkagev")
+; CHECK: DW_AT_declaration (true)
+; CHECK-NOT: DW_AT_linkage_name ("_Z11SameLinkagev")
+
+define void @_Z11DiffLinkagev() !dbg !8 {
+entry:
+ ret void
+}
+
+; CHECK: DW_AT_linkage_name ("SomeName")
+; CHECK: DW_AT_declaration (true)
+; CHECK: DW_AT_linkage_name ("_Z11DiffLinkagev")
+
+define void @_Z15EmptyDefLinkagev() !dbg !10 {
+entry:
+ ret void
+}
+
+; CHECK: DW_AT_linkage_name ("_Z15EmptyDefLinkagev")
+; CHECK: DW_AT_declaration (true)
+; CHECK-NOT: DW_AT_linkage_name
+
+define void @_Z16EmptyDeclLinkagev() !dbg !12 {
+entry:
+ ret void
+}
+
+; CHECK: DW_AT_declaration (true)
+; CHECK: DW_AT_linkage_name ("_Z16EmptyDeclLinkagev")
+
+define void @_Z13EmptyLinkagesv() !dbg !14 {
+entry:
+ ret void
+}
+
+; CHECK-NOT: DW_AT_linkage_name
+
+!llvm.dbg.cu = !{!0}
+!llvm.module.flags = !{!2, !3}
+
+!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus_14, file: !1, producer: "clang", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: Apple, sysroot: "/")
+!1 = !DIFile(filename: "foo.cpp", directory: "/tmp")
+!2 = !{i32 7, !"Dwarf Version", i32 5}
+!3 = !{i32 2, !"Debug Info Version", i32 3}
+!4 = distinct !DISubprogram(name: "SameLinkage", linkageName: "_Z11SameLinkagev", scope: !1, file: !1, line: 3, type: !5, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, declaration: !7)
+!5 = !DISubroutineType(types: !6)
+!6 = !{null}
+!7 = !DISubprogram(name: "SameLinkage", linkageName: "_Z11SameLinkagev", scope: !1, file: !1, line: 3, type: !5, scopeLine: 3, flags: DIFlagPrototyped, spFlags: 0)
+!8 = distinct !DISubprogram(name: "DiffLinkage", linkageName: "_Z11DiffLinkagev", scope: !1, file: !1, line: 5, type: !5, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, declaration: !9)
+!9 = !DISubprogram(name: "DiffLinkage", linkageName: "SomeName", scope: !1, file: !1, line: 3, type: !5, scopeLine: 3, flags: DIFlagPrototyped, spFlags: 0)
+!10 = distinct !DISubprogram(name: "EmptyDefLinkage", linkageName: "", scope: !1, file: !1, line: 5, type: !5, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, declaration: !11)
+!11 = !DISubprogram(name: "EmptyDefLinkage", linkageName: "_Z15EmptyDefLinkagev", scope: !1, file: !1, line: 3, type: !5, scopeLine: 3, flags: DIFlagPrototyped, spFlags: 0)
+!12 = distinct !DISubprogram(name: "EmptyDeclLinkage", linkageName: "_Z16EmptyDeclLinkagev", scope: !1, file: !1, line: 5, type: !5, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, declaration: !13)
+!13 = !DISubprogram(name: "EmptyDeclLinkage", linkageName: "", scope: !1, file: !1, line: 3, type: !5, scopeLine: 3, flags: DIFlagPrototyped, spFlags: 0)
+!14 = distinct !DISubprogram(name: "EmptyLinkages", linkageName: "", scope: !1, file: !1, line: 5, type: !5, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, declaration: !15)
+!15 = !DISubprogram(name: "EmptyLinkages", linkageName: "", scope: !1, file: !1, line: 3, type: !5, scopeLine: 3, flags: DIFlagPrototyped, spFlags: 0)
More information about the llvm-commits
mailing list