[Lldb-commits] [lldb] [lldb][[DWARFDeclContext] Add function to extract qualified names as vector (PR #77349)

Felipe de Azevedo Piovezan via lldb-commits lldb-commits at lists.llvm.org
Mon Jan 8 10:15:22 PST 2024


https://github.com/felipepiovezan created https://github.com/llvm/llvm-project/pull/77349

This functionality will support the efforts to implement the IDX_Parent attribute of accelerator table entries, and it will allow us to more easily compare each of the names in a DIE parent chain hierarchy.

>From 1b444a334fdfd5c88e263e9804cffbd7574a670b Mon Sep 17 00:00:00 2001
From: Felipe de Azevedo Piovezan <fpiovezan at apple.com>
Date: Mon, 11 Dec 2023 12:42:40 -0300
Subject: [PATCH] [lldb][[DWARFDeclContext] Add function to extract qualified
 names as vector

This functionality will support the efforts to implement the IDX_Parent
attribute of accelerator table entries, and it will allow us to more easily
compare each of the names in a DIE parent chain hierarchy.
---
 .../SymbolFile/DWARF/DWARFDeclContext.cpp     |   6 +
 .../SymbolFile/DWARF/DWARFDeclContext.h       |   5 +
 .../SymbolFile/DWARF/DWARFDIETest.cpp         | 109 ++++++++++++++++++
 3 files changed, 120 insertions(+)

diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
index 44421c0eda3eec..3cdb47d50bbfc0 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp
@@ -55,6 +55,12 @@ const char *DWARFDeclContext::GetQualifiedName() const {
   return m_qualified_name.c_str();
 }
 
+llvm::SmallVector<llvm::StringRef>
+DWARFDeclContext::GetQualifiedNameAsVector() const {
+  return llvm::to_vector_of<llvm::StringRef>(
+      llvm::map_range(m_entries, GetName));
+}
+
 bool DWARFDeclContext::operator==(const DWARFDeclContext &rhs) const {
   if (m_entries.size() != rhs.m_entries.size())
     return false;
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
index a20a862d340296..40ebb72c91d8f0 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h
@@ -68,6 +68,11 @@ class DWARFDeclContext {
 
   const char *GetQualifiedName() const;
 
+  /// Returns a vector of string, one string per entry in the fully qualified
+  /// name. For example, for the name `A::B::C`, this methods returns `{"A",
+  /// "B", "C"}`
+  llvm::SmallVector<llvm::StringRef> GetQualifiedNameAsVector() const;
+
   // Same as GetQualifiedName, but the life time of the returned string will
   // be that of the LLDB session.
   ConstString GetQualifiedNameAsConstString() const {
diff --git a/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
index 8497855b2f3db5..5672270ee31f89 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
@@ -7,8 +7,10 @@
 //===----------------------------------------------------------------------===//
 
 #include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
+#include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
 #include "TestingSupport/Symbol/YAMLModuleTester.h"
 #include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/StringRef.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
 
@@ -104,3 +106,110 @@ TEST(DWARFDIETest, ChildIteration) {
   DWARFDIE no_children_die(unit, die_child0);
   EXPECT_TRUE(no_children_die.children().empty());
 }
+
+TEST(DWARFDIETest, DeclContext) {
+  const char *yamldata = R"(
+--- !ELF
+FileHeader:
+  Class:   ELFCLASS64
+  Data:    ELFDATA2LSB
+  Type:    ET_EXEC
+  Machine: EM_386
+DWARF:
+  debug_str:
+    - 'mynamespace'
+    - 'mystruct'
+    - 'mytype'
+  debug_abbrev:
+    - Table:
+        - Code:            0x00000001
+          Tag:             DW_TAG_compile_unit
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_language
+              Form:            DW_FORM_data2
+        - Code:            0x00000002
+          Tag:             DW_TAG_structure_type
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+        - Code:            0x00000003
+          Tag:             DW_TAG_base_type
+          Children:        DW_CHILDREN_no
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+        - Code:            0x00000004
+          Tag:             DW_TAG_namespace
+          Children:        DW_CHILDREN_yes
+          Attributes:
+            - Attribute:       DW_AT_name
+              Form:            DW_FORM_strp
+  debug_info:
+    - Version:         4
+      AddrSize:        8
+      Entries:
+        - AbbrCode:        0x00000001 # compile_unit
+          Values:
+            - Value:           0x000000000000000C
+        - AbbrCode:        0x00000004 # namespace
+          Values:
+            - Value:           0x0000000000000000 # DW_ATE_strp
+        - AbbrCode:        0x00000002 # structure_type
+          Values:
+            - Value:           0x000000000000000c # DW_ATE_strp
+        - AbbrCode:        0x00000003 # base_type
+          Values:
+            - Value:           0x0000000000000015 # DW_ATE_strp
+        - AbbrCode:        0x00000000
+)";
+
+  YAMLModuleTester t(yamldata);
+  DWARFUnit *unit = t.GetDwarfUnit();
+  ASSERT_TRUE(unit != nullptr);
+  auto &ctx = unit->GetSymbolFileDWARF();
+
+  auto top_level_die = unit->DIE();
+  {
+    ASSERT_TRUE(top_level_die);
+    auto top_level_ctx = ctx.GetDWARFDeclContext(top_level_die);
+    auto top_level_name = llvm::StringRef(top_level_ctx.GetQualifiedName());
+    ASSERT_EQ(top_level_name, "");
+  }
+
+  auto namespace_die = top_level_die.GetFirstChild();
+  {
+    ASSERT_TRUE(namespace_die);
+    auto namespace_ctx = ctx.GetDWARFDeclContext(namespace_die);
+    auto namespace_name = llvm::StringRef(namespace_ctx.GetQualifiedName());
+    ASSERT_EQ(namespace_name, "::mynamespace");
+    auto namespace_names = namespace_ctx.GetQualifiedNameAsVector();
+    ASSERT_EQ(namespace_names.size(), 1u);
+    ASSERT_EQ(namespace_names.front(), "mynamespace");
+  }
+
+  auto struct_die = namespace_die.GetFirstChild();
+  {
+    ASSERT_TRUE(struct_die);
+    auto struct_ctx = ctx.GetDWARFDeclContext(struct_die);
+    auto struct_name = llvm::StringRef(struct_ctx.GetQualifiedName());
+    ASSERT_EQ(struct_name, "mynamespace::mystruct");
+    auto struct_names = struct_ctx.GetQualifiedNameAsVector();
+    ASSERT_EQ(struct_names.size(), 2u);
+    ASSERT_EQ(struct_names[0], "mystruct");
+    ASSERT_EQ(struct_names[1], "mynamespace");
+  }
+  auto simple_type_die = struct_die.GetFirstChild();
+  {
+    ASSERT_TRUE(simple_type_die);
+    auto simple_type_ctx = ctx.GetDWARFDeclContext(simple_type_die);
+    auto simple_type_name = llvm::StringRef(simple_type_ctx.GetQualifiedName());
+    ASSERT_EQ(simple_type_name, "mynamespace::mystruct::mytype");
+    auto simple_type_names = simple_type_ctx.GetQualifiedNameAsVector();
+    ASSERT_EQ(simple_type_names.size(), 3u);
+    ASSERT_EQ(simple_type_names[0], "mytype");
+    ASSERT_EQ(simple_type_names[1], "mystruct");
+    ASSERT_EQ(simple_type_names[2], "mynamespace");
+  }
+}



More information about the lldb-commits mailing list