[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:09:23 PDT 2024


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

>From 8baaddde6f8953662dcec6c8add9cc30fe39eb54 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 1/2] [DebugInfo] Emit linkage name into DWARF for types for
 Swift

Store Swift mangled names in DW_AT_linkage_name.

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     | 18 ++++--
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp  | 20 +++++--
 .../Generic/debug-names-accel-table-types.ll  | 55 ++++++++++++++++++
 .../debug-names-accel-table-types.test        | 56 +++++++++++++++++++
 4 files changed, 139 insertions(+), 10 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..715968c335ca03 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -645,15 +645,21 @@ 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);
+                   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..88bc494439f6cf 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,18 @@ 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()[0]) {
+      uint32_t Hash = hashFullyQualifiedName(InputDIE, Unit, File);
+      Unit.addTypeAccelerator(Die, AttrInfo.Name, ObjCClassIsImplementation,
+                              Hash);
+    }
+
+    if (Success && AttrInfo.MangledName &&
+        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())

>From c5ad77ca513c5a153243614638b862fac7bb2ea4 Mon Sep 17 00:00:00 2001
From: Augusto Noronha <anoronha at apple.com>
Date: Fri, 18 Oct 2024 11:09:12 -0700
Subject: [PATCH 2/2] address comments

---
 llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp    | 2 +-
 llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
index 715968c335ca03..08154de9418b77 100644
--- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp
@@ -654,7 +654,7 @@ void DwarfUnit::updateAcceleratorTables(const DIScope *Context,
   }
 
   DD->addAccelType(*this, CUNode->getNameTableKind(), Ty->getName(), TyDIE,
-                   Flags);;;
+                   Flags);
 
   if (auto *CT = dyn_cast<DICompositeType>(Ty))
     if (Ty->getName() != CT->getIdentifier())
diff --git a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
index 88bc494439f6cf..adfb920abb9387 100644
--- a/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
+++ b/llvm/lib/DWARFLinker/Classic/DWARFLinker.cpp
@@ -1847,13 +1847,14 @@ 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);
-    if (Success && AttrInfo.Name && AttrInfo.Name.getString()[0]) {
+    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,



More information about the llvm-commits mailing list