DWARF: Provide accessors to DIERef fields
authorPavel Labath <pavel@labath.sk>
Thu, 20 Jun 2019 08:24:46 +0000 (08:24 +0000)
committerPavel Labath <pavel@labath.sk>
Thu, 20 Jun 2019 08:24:46 +0000 (08:24 +0000)
Summary:
Instead of accessing the fields directly, use accessor functions to
provide access to the DIERef components. This allows us to decouple the
external interface, from the internal representation. The external
interface can use llvm::Optional and similar goodies, while the data can
still be stored internally in a more compact representation.

I also document the purpose of the existing DIERef fields.

The main motivation for this change is a need to introduce an additional
field to the DIERef class, but I believe the change has its own merit.

Reviewers: JDevlieghere, aprantl, clayborg

Subscribers: arphaman, lldb-commits

Differential Revision: https://reviews.llvm.org/D63400

llvm-svn: 363910

lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp
lldb/source/Plugins/SymbolFile/DWARF/DIERef.cpp
lldb/source/Plugins/SymbolFile/DWARF/DIERef.h
lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp

index 9e990ae17626b5d021aaa62b261913add7f83892..bc435bc54ae48e6dc18dce3ea9e1730b9d59dbed 100644 (file)
@@ -160,7 +160,7 @@ void AppleDWARFIndex::ReportInvalidDIERef(const DIERef &ref,
   m_module.ReportErrorIfModifyDetected(
       "the DWARF debug information has been modified (accelerator table had "
       "bad die 0x%8.8x for '%s')\n",
-      ref.die_offset, name.str().c_str());
+      ref.die_offset(), name.str().c_str());
 }
 
 void AppleDWARFIndex::Dump(Stream &s) {
index c95188760d40dd1ece3244c7d97cca5104270f64..11dbe3c0a1fbc7d4a9d42fd045bba16018200230 100644 (file)
@@ -7,3 +7,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "DIERef.h"
+#include "llvm/Support/Format.h"
+
+void llvm::format_provider<DIERef>::format(const DIERef &ref, raw_ostream &OS,
+                                           StringRef Style) {
+  OS << (ref.section() == DIERef::DebugInfo ? "INFO" : "TYPE");
+  if (ref.unit_offset())
+    OS << "/" << format_hex_no_prefix(*ref.unit_offset(), 8);
+  OS << "/" << format_hex_no_prefix(ref.die_offset(), 8);
+}
index e7843da404af10855d7fb2703f4d8fde6444ec91..476539bf84031646c46e6a85d432832001f33c42 100644 (file)
 #define SymbolFileDWARF_DIERef_h_
 
 #include "lldb/Core/dwarf.h"
+#include "llvm/ADT/Optional.h"
+#include "llvm/Support/FormatProviders.h"
 #include <vector>
 
-struct DIERef {
+/// Identifies a DWARF debug info entry within a given Module. It contains three
+/// "coordinates":
+/// - section: identifies the section of the debug info entry: debug_info or
+///   debug_types
+/// - unit_offset: the offset of the unit containing the debug info entry. For
+///   regular (unsplit) units, this field is optional, as the die_offset is
+///   enough to uniquely identify the containing unit. For split units, this
+///   field must contain the offset of the skeleton unit in the main object
+///   file.
+/// - die_offset: The offset of te debug info entry as an absolute offset from
+///   the beginning of the section specified in the section field.
+class DIERef {
+public:
   enum Section : uint8_t { DebugInfo, DebugTypes };
 
-  DIERef(Section s, dw_offset_t c, dw_offset_t d)
-      : section(s), cu_offset(c), die_offset(d) {}
+  DIERef(Section s, llvm::Optional<dw_offset_t> u, dw_offset_t d)
+      : m_section(s), m_unit_offset(u.getValueOr(DW_INVALID_OFFSET)),
+        m_die_offset(d) {}
 
-  Section section;
-  dw_offset_t cu_offset;
-  dw_offset_t die_offset;
+  Section section() const { return static_cast<Section>(m_section); }
+
+  llvm::Optional<dw_offset_t> unit_offset() const {
+    if (m_unit_offset != DW_INVALID_OFFSET)
+      return m_unit_offset;
+    return llvm::None;
+  }
+
+  dw_offset_t die_offset() const { return m_die_offset; }
+
+private:
+  unsigned m_section : 1;
+  dw_offset_t m_unit_offset;
+  dw_offset_t m_die_offset;
 };
 
 typedef std::vector<DIERef> DIEArray;
 
+namespace llvm {
+template<> struct format_provider<DIERef> {
+  static void format(const DIERef &ref, raw_ostream &OS, StringRef Style);
+};
+} // namespace llvm
+
 #endif // SymbolFileDWARF_DIERef_h_
index fc04580da96253fb30a6ea6a08efb08b38f888a1..cd2dfbc39f091cb9dc1e7c300674b7a35b3807bc 100644 (file)
@@ -149,10 +149,9 @@ DWARFUnit *DWARFDebugInfo::GetUnitAtOffset(DIERef::Section section,
 }
 
 DWARFUnit *DWARFDebugInfo::GetUnit(const DIERef &die_ref) {
-  if (die_ref.cu_offset == DW_INVALID_OFFSET)
-    return GetUnitContainingDIEOffset(die_ref.section, die_ref.die_offset);
-  else
-    return GetUnitAtOffset(die_ref.section, die_ref.cu_offset);
+  if (die_ref.unit_offset())
+    return GetUnitAtOffset(die_ref.section(), *die_ref.unit_offset());
+  return GetUnitContainingDIEOffset(die_ref.section(), die_ref.die_offset());
 }
 
 DWARFUnit *
@@ -194,7 +193,7 @@ DWARFDIE
 DWARFDebugInfo::GetDIE(const DIERef &die_ref) {
   DWARFUnit *cu = GetUnit(die_ref);
   if (cu)
-    return cu->GetDIE(die_ref.die_offset);
+    return cu->GetDIE(die_ref.die_offset());
   return DWARFDIE(); // Not found
 }
 
index 5e1624a82d811238396a6f2747aa5c8f83b8d10f..b7bbe41a7a8317324e9827faaad79b3b989381e1 100644 (file)
@@ -166,7 +166,7 @@ void DebugNamesDWARFIndex::GetCompleteObjCClass(ConstString class_name,
       continue;
 
     DWARFUnit *cu = m_debug_info.GetUnitAtOffset(DIERef::Section::DebugInfo,
-                                                 ref->cu_offset);
+                                                 *ref->unit_offset());
     if (!cu || !cu->Supports_DW_AT_APPLE_objc_complete_type()) {
       incomplete_types.push_back(*ref);
       continue;
index 06e157ea5e6d56893d1b2c3099ff4e8257b006de..ddb01de02a450ba9c661fbc0c87e93f3aee77c54 100644 (file)
@@ -61,7 +61,7 @@ public:
     DIEInfo(dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
 
     explicit operator DIERef() const {
-      return DIERef(DIERef::Section::DebugInfo, DW_INVALID_OFFSET, die_offset);
+      return DIERef(DIERef::Section::DebugInfo, llvm::None, die_offset);
     }
   };
 
index 6710ae1f2c6d02505fe30cdebe41dfa1d0f195c0..26b6dde781e751f2c713534fdc9090197c00a1e5 100644 (file)
@@ -26,6 +26,7 @@ void NameToDIE::Finalize() {
 }
 
 void NameToDIE::Insert(ConstString name, const DIERef &die_ref) {
+  assert(die_ref.unit_offset().hasValue());
   m_map.Append(name, die_ref);
 }
 
@@ -44,7 +45,7 @@ size_t NameToDIE::FindAllEntriesForCompileUnit(dw_offset_t cu_offset,
   const uint32_t size = m_map.GetSize();
   for (uint32_t i = 0; i < size; ++i) {
     const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
-    if (cu_offset == die_ref.cu_offset)
+    if (cu_offset == *die_ref.unit_offset())
       info_array.push_back(die_ref);
   }
   return info_array.size() - initial_size;
@@ -53,10 +54,8 @@ size_t NameToDIE::FindAllEntriesForCompileUnit(dw_offset_t cu_offset,
 void NameToDIE::Dump(Stream *s) {
   const uint32_t size = m_map.GetSize();
   for (uint32_t i = 0; i < size; ++i) {
-    ConstString cstr = m_map.GetCStringAtIndex(i);
-    const DIERef &die_ref = m_map.GetValueAtIndexUnchecked(i);
-    s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", (const void *)cstr.GetCString(),
-              die_ref.cu_offset, die_ref.die_offset, cstr.GetCString());
+    s->Format("{0} \"{1}\"\n", m_map.GetValueAtIndexUnchecked(i),
+              m_map.GetCStringAtIndexUnchecked(i));
   }
 }
 
index 947cca13282574cfedd93a645f0366471ede070d..d5e2eb873eaf47b2d743639be8a1fe79b78c40d6 100644 (file)
@@ -277,8 +277,9 @@ public:
   }
 
   lldb::user_id_t GetUID(const DIERef &ref) {
-    return GetID() | ref.die_offset |
-           (lldb::user_id_t(ref.section == DIERef::Section::DebugTypes) << 63);
+    return GetID() | ref.die_offset() |
+           (lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes)
+            << 63);
   }
 
   virtual std::unique_ptr<SymbolFileDWARFDwo>
index e3c178c89d5e824f6effc09cd50c48863d9ff5ac..5ddbbd0c6067d7900c9226efa9a1ed6bfda8864c 100644 (file)
@@ -124,7 +124,8 @@ SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
 
 DWARFDIE
 SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) {
-  lldbassert(die_ref.cu_offset == m_base_dwarf_cu.GetOffset() ||
-             die_ref.cu_offset == DW_INVALID_OFFSET);
-  return DebugInfo()->GetDIEForDIEOffset(die_ref.section, die_ref.die_offset);
+  lldbassert(!die_ref.unit_offset() ||
+             *die_ref.unit_offset() == m_base_dwarf_cu.GetOffset());
+  return DebugInfo()->GetDIEForDIEOffset(die_ref.section(),
+                                         die_ref.die_offset());
 }