[llvm] [DebugInfo] Emit linkage name into DWARF for types for Swift (PR #112802)

Augusto Noronha via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 18 11:31:46 PDT 2024


https://github.com/augusto2112 updated https://github.com/llvm/llvm-project/pull/112802

>From e2a5a6687413f7de8f78358748d0ffd6b23850e2 Mon Sep 17 00:00:00 2001
From: Augusto Noronha <anoronha at apple.com>
Date: Thu, 17 Oct 2024 16:51:02 -0700
Subject: [PATCH] [DebugInfo] Emit linkage name into DWARF for types for Swift

Store Swift mangled names in DW_AT_linkage_name. The Swift compiler
emits only the type mangled name in debug information, and LLDB uses
those mangled names as keys to look up size, alignment, fields, etc
from either reflection metadata or Swift modules.

Additionally, emit types linkage names for types into the accelerator
table if they exist and they're different from the display name.
---
 llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp     | 16 +++++-
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp  | 21 +++++--
 .../Generic/debug-names-accel-table-types.ll  | 55 ++++++++++++++++++
 .../debug-names-accel-table-types.test        | 56 +++++++++++++++++++
 4 files changed, 139 insertions(+), 9 deletions(-)
 create mode 100644 llvm/test/DebugInfo/Generic/debug-names-accel-table-types.ll
 create mode 100644 llvm/test/tools/dsymutil/debug-names-accel-table-types.test

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index e76b0fe2081c07..08154de9418b77 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -645,16 +645,22 @@ void DwarfUnit::updateAcceleratorTables(const DIScope *Context,
 
   // add temporary record for this type to be added later
 
-  bool IsImplementation = false;
+  unsigned Flags = 0;
   if (auto *CT = dyn_cast<DICompositeType>(Ty)) {
     // A runtime language of 0 actually means C/C++ and that any
     // non-negative value is some version of Objective-C/C++.
-    IsImplementation = CT->getRuntimeLang() == 0 || CT->isObjcClassComplete();
+    if (CT->getRuntimeLang() == 0 || CT->isObjcClassComplete())
+      Flags = dwarf::DW_FLAG_type_implementation;
   }
-  unsigned Flags = IsImplementation ? dwarf::DW_FLAG_type_implementation : 0;
+
   DD->addAccelType(*this, CUNode->getNameTableKind(), Ty->getName(), TyDIE,
                    Flags);
 
+  if (auto *CT = dyn_cast<DICompositeType>(Ty))
+    if (Ty->getName() != CT->getIdentifier())
+      DD->addAccelType(*this, CUNode->getNameTableKind(), CT->getIdentifier(),
+                       TyDIE, Flags);
+
   addGlobalType(Ty, TyDIE, Context);
 }
 
@@ -1042,6 +1048,10 @@ void DwarfUnit::constructTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
   if (!Name.empty())
     addString(Buffer, dwarf::DW_AT_name, Name);
 
+  // For Swift, mangled names are put into DW_AT_linkage_name.
+  if (CTy->getRuntimeLang() == dwarf::DW_LANG_Swift && CTy->getRawIdentifier())
+    addString(Buffer, dwarf::DW_AT_linkage_name, CTy->getIdentifier());
+
   addAnnotation(Buffer, CTy->getAnnotations());
 
   if (Tag == dwarf::DW_TAG_enumeration_type ||
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 280d3f1861ff00..adfb920abb9387 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -1837,10 +1837,8 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
     Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
   } else if (Tag == dwarf::DW_TAG_imported_declaration && AttrInfo.Name) {
     Unit.addNamespaceAccelerator(Die, AttrInfo.Name);
-  } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration &&
-             getDIENames(InputDIE, AttrInfo, DebugStrPool) && AttrInfo.Name &&
-             AttrInfo.Name.getString()[0]) {
-    uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit, File);
+  } else if (isTypeTag(Tag) && !AttrInfo.IsDeclaration) {
+    bool Success = getDIENames(InputDIE, AttrInfo, DebugStrPool);
     uint64_t RuntimeLang =
         dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_runtime_class))
             .value_or(0);
@@ -1849,8 +1847,19 @@ DIE *DWARFLinker::DIECloner::cloneDIE(const DWARFDie &InputDIE,
          RuntimeLang == dwarf::DW_LANG_ObjC_plus_plus) &&
         dwarf::toUnsigned(InputDIE.find(dwarf::DW_AT_APPLE_objc_complete_type))
             .value_or(0);
-    Unit.addTypeAccelerator(Die, AttrInfo.Name, ObjCClassIsImplementation,
-                            Hash);
+    if (Success && AttrInfo.Name && !AttrInfo.Name.getString().empty()) {
+      uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit, File);
+      Unit.addTypeAccelerator(Die, AttrInfo.Name, ObjCClassIsImplementation,
+                              Hash);
+    }
+
+    if (Success && AttrInfo.MangledName &&
+        !AttrInfo.MangledName.getString().empty() &&
+        AttrInfo.MangledName != AttrInfo.Name) {
+      auto Hash = djbHash(AttrInfo.MangledName.getString().data());
+      Unit.addTypeAccelerator(Die, AttrInfo.MangledName,
+                              ObjCClassIsImplementation, Hash);
+    }
   }
 
   // Determine whether there are any children that we want to keep.
diff --git a/llvm/test/DebugInfo/Generic/debug-names-accel-table-types.ll b/llvm/test/DebugInfo/Generic/debug-names-accel-table-types.ll
new file mode 100644
index 00000000000000..e88afe1b4c5118
--- /dev/null
+++ b/llvm/test/DebugInfo/Generic/debug-names-accel-table-types.ll
@@ -0,0 +1,55 @@
+; RUN: %llc_dwarf -debugger-tune=lldb -accel-tables=Dwarf -filetype=obj -o %t < %s
+; RUN: llvm-dwarfdump %t | FileCheck %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=SAME-NAME %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=DIFFERENT-NAME %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=UNIQUE-DIFFERENT-NAME %s
+; RUN: llvm-dwarfdump -debug-names -verify %t | FileCheck --check-prefix=VERIFY %s
+
+
+; CHECK: DW_TAG_structure_type
+; CHECK: DW_AT_name ("SameName")
+; CHECK: DW_AT_linkage_name ("SameName")
+
+; CHECK: DW_TAG_structure_type
+; CHECK: DW_AT_name ("DifferentName")
+; CHECK: DW_AT_linkage_name ("UniqueDifferentName")
+
+; The name count should be 5 (the two variables, the two human readable names, one mangled name).
+; SAME-NAME: Name count: 5
+
+; The accelarator should only have one entry for the three following names.
+; SAME-NAME: "SameName" 
+; SAME-NAME-NOT: "SameName" 
+
+; DIFFERENT-NAME: "DifferentName"
+; DIFFERENT-NAME-NOT: "DifferentName"
+
+; UNIQUE-DIFFERENT-NAME: "UniqueDifferentName"
+; UNIQUE-DIFFERENT-NAME-NOT: "UniqueDifferentName"
+
+; Verification should succeed.
+; VERIFY: No errors.
+
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+ at q = common global i8* null, align 8, !dbg !102
+ at r = common global i8* null, align 8, !dbg !105
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!6, !7}
+
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5)
+!3 = !DIFile(filename: "/tmp/p.c", directory: "/")
+!4 = !{}
+!5 = !{!102, !105}
+!6 = !{i32 2, !"Dwarf Version", i32 4}
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+
+; marking the types as Swift is necessary because we only emit the linkage names for Swift types.
+!11 = !DICompositeType(tag: DW_TAG_structure_type, name: "SameName", file: !3, size: 64, runtimeLang: DW_LANG_Swift, identifier: "SameName")
+!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "DifferentName", file: !3, size: 64, runtimeLang: DW_LANG_Swift, identifier: "UniqueDifferentName")
+
+!102 = !DIGlobalVariableExpression(var: !103, expr: !DIExpression())
+!103 = distinct !DIGlobalVariable(name: "q", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true)
+!104 = distinct !DIGlobalVariable(name: "r", scope: !2, file: !3, line: 1, type: !12, isLocal: false, isDefinition: true)
+!105 = !DIGlobalVariableExpression(var: !104, expr: !DIExpression())
diff --git a/llvm/test/tools/dsymutil/debug-names-accel-table-types.test b/llvm/test/tools/dsymutil/debug-names-accel-table-types.test
new file mode 100644
index 00000000000000..90cdaded8523a9
--- /dev/null
+++ b/llvm/test/tools/dsymutil/debug-names-accel-table-types.test
@@ -0,0 +1,56 @@
+; RUN: %llc_dwarf -debugger-tune=lldb -accel-tables=Dwarf -filetype=obj -o %t < %s
+; RUN: dsymutil %t -o %t.dSYM
+; RUN: llvm-dwarfdump %t | FileCheck %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=SAME-NAME %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=DIFFERENT-NAME %s
+; RUN: llvm-dwarfdump -debug-names %t | FileCheck --check-prefix=UNIQUE-DIFFERENT-NAME %s
+; RUN: llvm-dwarfdump -debug-names -verify %t | FileCheck --check-prefix=VERIFY %s
+
+
+; CHECK: DW_TAG_structure_type
+; CHECK: DW_AT_name ("SameName")
+; CHECK: DW_AT_linkage_name ("SameName")
+
+; CHECK: DW_TAG_structure_type
+; CHECK: DW_AT_name ("DifferentName")
+; CHECK: DW_AT_linkage_name ("UniqueDifferentName")
+
+; The name count should be 5 (the two variables, the two human readable names, one mangled name).
+; SAME-NAME: Name count: 5
+
+; The accelarator should only have one entry for the three following names.
+; SAME-NAME: "SameName" 
+; SAME-NAME-NOT: "SameName" 
+
+; DIFFERENT-NAME: "DifferentName"
+; DIFFERENT-NAME-NOT: "DifferentName"
+
+; UNIQUE-DIFFERENT-NAME: "UniqueDifferentName"
+; UNIQUE-DIFFERENT-NAME-NOT: "UniqueDifferentName"
+
+; Verification should succeed.
+; VERIFY: No errors.
+
+target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128"
+
+ at q = common global i8* null, align 8, !dbg !102
+ at r = common global i8* null, align 8, !dbg !105
+
+!llvm.dbg.cu = !{!2}
+!llvm.module.flags = !{!6, !7}
+
+!2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, emissionKind: FullDebug, globals: !5)
+!3 = !DIFile(filename: "/tmp/p.c", directory: "/")
+!4 = !{}
+!5 = !{!102, !105}
+!6 = !{i32 2, !"Dwarf Version", i32 4}
+!7 = !{i32 2, !"Debug Info Version", i32 3}
+
+; marking the types as Swift is necessary because we only emit the linkage names for Swift types.
+!11 = !DICompositeType(tag: DW_TAG_structure_type, name: "SameName", file: !3, size: 64, runtimeLang: DW_LANG_Swift, identifier: "SameName")
+!12 = !DICompositeType(tag: DW_TAG_structure_type, name: "DifferentName", file: !3, size: 64, runtimeLang: DW_LANG_Swift, identifier: "UniqueDifferentName")
+
+!102 = !DIGlobalVariableExpression(var: !103, expr: !DIExpression())
+!103 = distinct !DIGlobalVariable(name: "q", scope: !2, file: !3, line: 1, type: !11, isLocal: false, isDefinition: true)
+!104 = distinct !DIGlobalVariable(name: "r", scope: !2, file: !3, line: 1, type: !12, isLocal: false, isDefinition: true)
+!105 = !DIGlobalVariableExpression(var: !104, expr: !DIExpression())



More information about the llvm-commits mailing list