zturner created this revision.
zturner added reviewers: clayborg, aprantl, labath.
Herald added a subscriber: jdoerfert.

This hits the next batch of classes and adds better error handling and recovery 
to them.  After this, the only remaining case is the line table stuff, at which 
point we should be able to get all logging out of the low level DWARF parsing 
entirely.


https://reviews.llvm.org/D59430

Files:
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp

Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -723,18 +723,25 @@
 }
 
 DWARFDebugRangesBase *SymbolFileDWARF::DebugRanges() {
-  if (m_ranges == NULL) {
-    static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
-    Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
-                       static_cast<void *>(this));
+  if (m_ranges)
+    return m_ranges.get();
+
+  static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
+  Timer scoped_timer(func_cat, "%s this = %p", LLVM_PRETTY_FUNCTION,
+                     static_cast<void *>(this));
 
-    if (get_debug_ranges_data().GetByteSize() > 0)
-      m_ranges.reset(new DWARFDebugRanges());
-    else if (get_debug_rnglists_data().GetByteSize() > 0)
-      m_ranges.reset(new DWARFDebugRngLists());
+  if (get_debug_ranges_data().GetByteSize() > 0)
+    m_ranges = llvm::make_unique<DWARFDebugRanges>();
+  else if (get_debug_rnglists_data().GetByteSize() > 0)
+    m_ranges = llvm::make_unique<DWARFDebugRngLists>();
+  else
+    return nullptr;
 
-    if (m_ranges)
-      m_ranges->Extract(this);
+  auto error = m_ranges->extract(this);
+  if (error) {
+    Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO);
+    LLDB_LOG_ERROR(log, std::move(error),
+                   "Unable to get debug range information: {0}");
   }
   return m_ranges.get();
 }
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.h
@@ -12,13 +12,15 @@
 #include "DWARFDIE.h"
 #include "SymbolFileDWARF.h"
 
+#include "llvm/Support/Error.h"
+
 #include <map>
 
 class DWARFDebugRangesBase {
 public:
   virtual ~DWARFDebugRangesBase(){};
 
-  virtual void Extract(SymbolFileDWARF *dwarf2Data) = 0;
+  virtual llvm::Error extract(SymbolFileDWARF *dwarf2Data) = 0;
   virtual bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
                           DWARFRangeList &range_list) const = 0;
   virtual uint64_t GetOffset(size_t Index) const = 0;
@@ -28,7 +30,7 @@
 public:
   DWARFDebugRanges();
 
-  void Extract(SymbolFileDWARF *dwarf2Data) override;
+  llvm::Error extract(SymbolFileDWARF *dwarf2Data) override;
   bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
                   DWARFRangeList &range_list) const override;
   uint64_t GetOffset(size_t Index) const override;
@@ -38,8 +40,9 @@
                    lldb::offset_t *offset_ptr, dw_addr_t cu_base_addr);
 
 protected:
-  bool Extract(SymbolFileDWARF *dwarf2Data, lldb::offset_t *offset_ptr,
-               DWARFRangeList &range_list);
+  llvm::Error extractOne(SymbolFileDWARF *dwarf2Data,
+                         lldb::offset_t *offset_ptr,
+                         DWARFRangeList &range_list);
 
   typedef std::map<dw_offset_t, DWARFRangeList> range_map;
   typedef range_map::iterator range_map_iterator;
@@ -56,7 +59,7 @@
   };
 
 public:
-  void Extract(SymbolFileDWARF *dwarf2Data) override;
+  llvm::Error extract(SymbolFileDWARF *dwarf2Data) override;
   bool FindRanges(const DWARFUnit *cu, dw_offset_t debug_ranges_offset,
                   DWARFRangeList &range_list) const override;
   uint64_t GetOffset(size_t Index) const override;
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugRanges.cpp
@@ -10,6 +10,7 @@
 #include "DWARFUnit.h"
 #include "SymbolFileDWARF.h"
 #include "lldb/Utility/Stream.h"
+#include "llvm/Object/Error.h"
 #include <assert.h>
 
 using namespace lldb_private;
@@ -29,23 +30,33 @@
 
 DWARFDebugRanges::DWARFDebugRanges() : m_range_map() {}
 
-void DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data) {
+llvm::Error DWARFDebugRanges::extract(SymbolFileDWARF *dwarf2Data) {
   DWARFRangeList range_list;
   lldb::offset_t offset = 0;
   dw_offset_t debug_ranges_offset = offset;
-  while (Extract(dwarf2Data, &offset, range_list)) {
+
+  const DWARFDataExtractor &debug_ranges_data =
+      dwarf2Data->get_debug_ranges_data();
+
+  // Consume the entire debug_ranges section.
+  while (debug_ranges_data.ValidOffset(offset)) {
+    llvm::Error error = extractOne(dwarf2Data, &offset, range_list);
+    if (error)
+      return error;
+
     range_list.Sort();
     m_range_map[debug_ranges_offset] = range_list;
     debug_ranges_offset = offset;
   }
+
+  return llvm::ErrorSuccess();
 }
 
-bool DWARFDebugRanges::Extract(SymbolFileDWARF *dwarf2Data,
-                               lldb::offset_t *offset_ptr,
-                               DWARFRangeList &range_list) {
+llvm::Error DWARFDebugRanges::extractOne(SymbolFileDWARF *dwarf2Data,
+                                         lldb::offset_t *offset_ptr,
+                                         DWARFRangeList &range_list) {
   range_list.Clear();
 
-  lldb::offset_t range_offset = *offset_ptr;
   const DWARFDataExtractor &debug_ranges_data =
       dwarf2Data->get_debug_ranges_data();
   uint32_t addr_size = debug_ranges_data.GetAddressByteSize();
@@ -57,10 +68,8 @@
     dw_addr_t begin = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
     dw_addr_t end = debug_ranges_data.GetMaxU64(offset_ptr, addr_size);
 
-    if (!begin && !end) {
-      // End of range list
-      break;
-    }
+    if (!begin && !end)
+      return llvm::ErrorSuccess();
 
     if (begin == base_addr_marker) {
       base_addr = end;
@@ -72,8 +81,8 @@
       range_list.Append(DWARFRangeList::Entry(begin + base_addr, end - begin));
   }
 
-  // Make sure we consumed at least something
-  return range_offset != *offset_ptr;
+  return llvm::make_error<llvm::object::GenericBinaryError>(
+      "range list not terminated by null entry");
 }
 
 void DWARFDebugRanges::Dump(Stream &s,
@@ -255,7 +264,7 @@
   return false;
 }
 
-void DWARFDebugRngLists::Extract(SymbolFileDWARF *dwarf2Data) {
+llvm::Error DWARFDebugRngLists::extract(SymbolFileDWARF *dwarf2Data) {
   const DWARFDataExtractor &data = dwarf2Data->get_debug_rnglists_data();
   lldb::offset_t offset = 0;
 
@@ -265,15 +274,15 @@
 
   // Check version.
   if (data.GetU16(&offset) < 5)
-    return;
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Unsupported range list version");
 
   uint8_t addrSize = data.GetU8(&offset);
 
   // We do not support non-zero segment selector size.
-  if (data.GetU8(&offset) != 0) {
-    lldbassert(0 && "not implemented");
-    return;
-  }
+  if (data.GetU8(&offset) != 0)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Non-zero segment selector size unsupported");
 
   uint32_t offsetsAmount = data.GetU32(&offset);
   for (uint32_t i = 0; i < offsetsAmount; ++i)
@@ -285,6 +294,7 @@
     m_range_map[listOffset] = rangeList;
     listOffset = offset;
   }
+  return llvm::ErrorSuccess();
 }
 
 uint64_t DWARFDebugRngLists::GetOffset(size_t Index) const {
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -11,10 +11,12 @@
 
 #include "SymbolFileDWARF.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Error.h"
 
 #include "DWARFAbbreviationDeclaration.h"
 #include "DWARFDebugAbbrev.h"
 #include "DWARFDebugRanges.h"
+#include "DWARFDefines.h"
 #include <map>
 #include <set>
 #include <vector>
@@ -74,8 +76,9 @@
                    const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
                    lldb::offset_t *offset_ptr);
 
-  bool Extract(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
-               lldb::offset_t *offset_ptr);
+  llvm::Expected<lldb_private::DWARFEnumState>
+  extract(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
+          lldb::offset_t *offset_ptr);
 
   bool LookupAddress(const dw_addr_t address, SymbolFileDWARF *dwarf2Data,
                      const DWARFUnit *cu,
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -27,6 +27,8 @@
 #include "SymbolFileDWARF.h"
 #include "SymbolFileDWARFDwo.h"
 
+#include "llvm/Object/Error.h"
+
 using namespace lldb_private;
 using namespace std;
 extern int g_verbose;
@@ -206,162 +208,165 @@
 // .debug_abbrev data within the SymbolFileDWARF class starting at the given
 // offset
 //----------------------------------------------------------------------
-bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
-                                  const DWARFUnit *cu,
-                                  lldb::offset_t *offset_ptr) {
+llvm::Expected<DWARFEnumState>
+DWARFDebugInfoEntry::extract(SymbolFileDWARF *dwarf2Data, const DWARFUnit *cu,
+                             lldb::offset_t *offset_ptr) {
   const DWARFDataExtractor &debug_info_data = cu->GetData();
-  //    const DWARFDataExtractor& debug_str_data =
-  //    dwarf2Data->get_debug_str_data();
-  const uint32_t cu_end_offset = cu->GetNextCompileUnitOffset();
   lldb::offset_t offset = *offset_ptr;
-  //  if (offset >= cu_end_offset)
-  //      Log::Status("DIE at offset 0x%8.8x is beyond the end of the current
-  //      compile unit (0x%8.8x)", m_offset, cu_end_offset);
-  if ((offset < cu_end_offset) && debug_info_data.ValidOffset(offset)) {
-    m_offset = offset;
-
-    const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
-    lldbassert(abbr_idx <= UINT16_MAX);
-    m_abbr_idx = abbr_idx;
-    if (abbr_idx) {
-      const DWARFAbbreviationDeclaration *abbrevDecl =
-          cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx);
 
-      if (abbrevDecl) {
-        m_tag = abbrevDecl->Tag();
-        m_has_children = abbrevDecl->HasChildren();
+  assert(offset < cu->GetNextCompileUnitOffset() &&
+         debug_info_data.ValidOffset(offset));
 
-        bool isCompileUnitTag = (m_tag == DW_TAG_compile_unit ||
-                                 m_tag == DW_TAG_partial_unit);
-        if (cu && isCompileUnitTag)
-          const_cast<DWARFUnit *>(cu)->SetBaseAddress(0);
+  m_offset = offset;
 
-        // Skip all data in the .debug_info for the attributes
-        const uint32_t numAttributes = abbrevDecl->NumAttributes();
-        for (uint32_t i = 0; i < numAttributes; ++i) {
-          DWARFFormValue form_value(cu);
-          dw_attr_t attr;
-          abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
-          dw_form_t form = form_value.Form();
-
-          if (isCompileUnitTag &&
-              ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
-            if (form_value.ExtractValue(debug_info_data, &offset)) {
-              if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
-                const_cast<DWARFUnit *>(cu)->SetBaseAddress(
-                    form_value.Address());
-            }
-          } else {
-            bool form_is_indirect = false;
-            do {
-              form_is_indirect = false;
-              uint32_t form_size = 0;
-              switch (form) {
-              // Blocks if inlined data that have a length field and the data
-              // bytes inlined in the .debug_info
-              case DW_FORM_exprloc:
-              case DW_FORM_block:
-                form_size = debug_info_data.GetULEB128(&offset);
-                break;
-              case DW_FORM_block1:
-                form_size = debug_info_data.GetU8(&offset);
-                break;
-              case DW_FORM_block2:
-                form_size = debug_info_data.GetU16(&offset);
-                break;
-              case DW_FORM_block4:
-                form_size = debug_info_data.GetU32(&offset);
-                break;
-
-              // Inlined NULL terminated C-strings
-              case DW_FORM_string:
-                debug_info_data.GetCStr(&offset);
-                break;
-
-              // Compile unit address sized values
-              case DW_FORM_addr:
-                form_size = cu->GetAddressByteSize();
-                break;
-              case DW_FORM_ref_addr:
-                if (cu->GetVersion() <= 2)
-                  form_size = cu->GetAddressByteSize();
-                else
-                  form_size = 4;
-                break;
-
-              // 0 sized form
-              case DW_FORM_flag_present:
-              case DW_FORM_implicit_const:
-                form_size = 0;
-                break;
-
-              // 1 byte values
-              case DW_FORM_data1:
-              case DW_FORM_flag:
-              case DW_FORM_ref1:
-                form_size = 1;
-                break;
-
-              // 2 byte values
-              case DW_FORM_data2:
-              case DW_FORM_ref2:
-                form_size = 2;
-                break;
-
-              // 4 byte values
-              case DW_FORM_data4:
-              case DW_FORM_ref4:
-                form_size = 4;
-                break;
-
-              // 8 byte values
-              case DW_FORM_data8:
-              case DW_FORM_ref8:
-              case DW_FORM_ref_sig8:
-                form_size = 8;
-                break;
-
-              // signed or unsigned LEB 128 values
-              case DW_FORM_addrx:
-              case DW_FORM_sdata:
-              case DW_FORM_udata:
-              case DW_FORM_ref_udata:
-              case DW_FORM_GNU_addr_index:
-              case DW_FORM_GNU_str_index:
-                debug_info_data.Skip_LEB128(&offset);
-                break;
-
-              case DW_FORM_indirect:
-                form = debug_info_data.GetULEB128(&offset);
-                form_is_indirect = true;
-                break;
-
-              case DW_FORM_strp:
-              case DW_FORM_sec_offset:
-                debug_info_data.GetU32(&offset);
-                break;
-
-              default:
-                *offset_ptr = offset;
-                return false;
-              }
+  const uint64_t abbr_idx = debug_info_data.GetULEB128(&offset);
+  if (abbr_idx > UINT16_MAX)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Invalid abbreviation index");
 
-              offset += form_size;
-            } while (form_is_indirect);
-          }
-        }
-        *offset_ptr = offset;
-        return true;
+  m_abbr_idx = abbr_idx;
+
+  // NULL debug tag entry
+  if (abbr_idx == 0) {
+    m_tag = 0;
+    m_has_children = false;
+    *offset_ptr = offset;
+    return DWARFEnumState::Complete;
+  }
+
+  const DWARFAbbreviationDeclaration *abbrevDecl =
+      cu->GetAbbreviations()->GetAbbreviationDeclaration(abbr_idx);
+
+  if (!abbrevDecl)
+    return llvm::make_error<llvm::object::GenericBinaryError>(
+        "Invalid abbrev index for DIE");
+
+  m_tag = abbrevDecl->Tag();
+  m_has_children = abbrevDecl->HasChildren();
+
+  bool isCompileUnitTag =
+      (m_tag == DW_TAG_compile_unit || m_tag == DW_TAG_partial_unit);
+
+  if (cu && isCompileUnitTag)
+    const_cast<DWARFUnit *>(cu)->SetBaseAddress(0);
+
+  // Skip all data in the .debug_info for the attributes
+  const uint32_t numAttributes = abbrevDecl->NumAttributes();
+  for (uint32_t i = 0; i < numAttributes; ++i) {
+    DWARFFormValue form_value(cu);
+    dw_attr_t attr;
+    abbrevDecl->GetAttrAndFormValueByIndex(i, attr, form_value);
+    dw_form_t form = form_value.Form();
+
+    if (isCompileUnitTag &&
+        ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
+      if (form_value.ExtractValue(debug_info_data, &offset)) {
+        if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
+          const_cast<DWARFUnit *>(cu)->SetBaseAddress(form_value.Address());
       }
-    } else {
-      m_tag = 0;
-      m_has_children = false;
-      *offset_ptr = offset;
-      return true; // NULL debug tag entry
+      continue;
     }
-  }
 
-  return false;
+    bool form_is_indirect = false;
+    do {
+      form_is_indirect = false;
+      uint32_t form_size = 0;
+      switch (form) {
+      // Blocks if inlined data that have a length field and the data
+      // bytes inlined in the .debug_info
+      case DW_FORM_exprloc:
+      case DW_FORM_block:
+        form_size = debug_info_data.GetULEB128(&offset);
+        break;
+      case DW_FORM_block1:
+        form_size = debug_info_data.GetU8(&offset);
+        break;
+      case DW_FORM_block2:
+        form_size = debug_info_data.GetU16(&offset);
+        break;
+      case DW_FORM_block4:
+        form_size = debug_info_data.GetU32(&offset);
+        break;
+
+      // Inlined NULL terminated C-strings
+      case DW_FORM_string:
+        debug_info_data.GetCStr(&offset);
+        break;
+
+      // Compile unit address sized values
+      case DW_FORM_addr:
+        form_size = cu->GetAddressByteSize();
+        break;
+      case DW_FORM_ref_addr:
+        if (cu->GetVersion() <= 2)
+          form_size = cu->GetAddressByteSize();
+        else
+          form_size = 4;
+        break;
+
+      // 0 sized form
+      case DW_FORM_flag_present:
+      case DW_FORM_implicit_const:
+        form_size = 0;
+        break;
+
+      // 1 byte values
+      case DW_FORM_data1:
+      case DW_FORM_flag:
+      case DW_FORM_ref1:
+        form_size = 1;
+        break;
+
+      // 2 byte values
+      case DW_FORM_data2:
+      case DW_FORM_ref2:
+        form_size = 2;
+        break;
+
+      // 4 byte values
+      case DW_FORM_data4:
+      case DW_FORM_ref4:
+        form_size = 4;
+        break;
+
+      // 8 byte values
+      case DW_FORM_data8:
+      case DW_FORM_ref8:
+      case DW_FORM_ref_sig8:
+        form_size = 8;
+        break;
+
+      // signed or unsigned LEB 128 values
+      case DW_FORM_addrx:
+      case DW_FORM_sdata:
+      case DW_FORM_udata:
+      case DW_FORM_ref_udata:
+      case DW_FORM_GNU_addr_index:
+      case DW_FORM_GNU_str_index:
+        debug_info_data.Skip_LEB128(&offset);
+        break;
+
+      case DW_FORM_indirect:
+        form = debug_info_data.GetULEB128(&offset);
+        form_is_indirect = true;
+        break;
+
+      case DW_FORM_strp:
+      case DW_FORM_sec_offset:
+        debug_info_data.GetU32(&offset);
+        break;
+
+      default:
+        *offset_ptr = offset;
+        return llvm::make_error<llvm::object::GenericBinaryError>(
+            "Invalid attribute form");
+      }
+
+      offset += form_size;
+    } while (form_is_indirect);
+  }
+  *offset_ptr = offset;
+  return DWARFEnumState::MoreItems;
 }
 
 //----------------------------------------------------------------------
@@ -1162,27 +1167,30 @@
 bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
                                   const DWARFUnit *cu,
                                   const dw_offset_t die_offset, Stream &s) {
-  if (dwarf2Data == NULL) {
-    s.PutCString("NULL");
-    return false;
-  }
+  assert(dwarf2Data);
 
   DWARFDebugInfoEntry die;
   lldb::offset_t offset = die_offset;
-  if (die.Extract(dwarf2Data, cu, &offset)) {
-    if (die.IsNULL()) {
-      s.PutCString("NULL");
-      return true;
-    } else {
-      const char *name = die.GetAttributeValueAsString(
-          dwarf2Data, cu, DW_AT_name, nullptr, true);
-      if (name) {
-        s.PutCString(name);
-        return true;
-      }
-    }
+  auto state = die.extract(dwarf2Data, cu, &offset);
+  if (!state) {
+    llvm::consumeError(state.takeError());
+    return false;
+  } else if (*state == DWARFEnumState::Complete) {
+    return false;
   }
-  return false;
+
+  if (die.IsNULL()) {
+    s.PutCString("NULL");
+    return true;
+  }
+
+  const char *name =
+      die.GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
+  if (!name)
+    return false;
+
+  s.PutCString(name);
+  return true;
 }
 
 //----------------------------------------------------------------------
@@ -1196,125 +1204,127 @@
                                          const DWARFUnit *cu,
                                          const dw_offset_t die_offset,
                                          Stream &s) {
-  if (dwarf2Data == NULL) {
-    s.PutCString("NULL");
-    return false;
-  }
+  assert(dwarf2Data);
 
   DWARFDebugInfoEntry die;
   lldb::offset_t offset = die_offset;
-  if (die.Extract(dwarf2Data, cu, &offset)) {
-    if (die.IsNULL()) {
-      s.PutCString("NULL");
-      return true;
-    } else {
-      const char *name = die.GetPubname(dwarf2Data, cu);
-      if (name)
-        s.PutCString(name);
-      else {
-        bool result = true;
-        const DWARFAbbreviationDeclaration *abbrevDecl =
-            die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
-
-        if (abbrevDecl == NULL)
-          return false;
-
-        switch (abbrevDecl->Tag()) {
-        case DW_TAG_array_type:
-          break; // print out a "[]" after printing the full type of the element
-                 // below
-        case DW_TAG_base_type:
-          s.PutCString("base ");
-          break;
-        case DW_TAG_class_type:
-          s.PutCString("class ");
-          break;
-        case DW_TAG_const_type:
-          s.PutCString("const ");
-          break;
-        case DW_TAG_enumeration_type:
-          s.PutCString("enum ");
-          break;
-        case DW_TAG_file_type:
-          s.PutCString("file ");
-          break;
-        case DW_TAG_interface_type:
-          s.PutCString("interface ");
-          break;
-        case DW_TAG_packed_type:
-          s.PutCString("packed ");
-          break;
-        case DW_TAG_pointer_type:
-          break; // print out a '*' after printing the full type below
-        case DW_TAG_ptr_to_member_type:
-          break; // print out a '*' after printing the full type below
-        case DW_TAG_reference_type:
-          break; // print out a '&' after printing the full type below
-        case DW_TAG_restrict_type:
-          s.PutCString("restrict ");
-          break;
-        case DW_TAG_set_type:
-          s.PutCString("set ");
-          break;
-        case DW_TAG_shared_type:
-          s.PutCString("shared ");
-          break;
-        case DW_TAG_string_type:
-          s.PutCString("string ");
-          break;
-        case DW_TAG_structure_type:
-          s.PutCString("struct ");
-          break;
-        case DW_TAG_subrange_type:
-          s.PutCString("subrange ");
-          break;
-        case DW_TAG_subroutine_type:
-          s.PutCString("function ");
-          break;
-        case DW_TAG_thrown_type:
-          s.PutCString("thrown ");
-          break;
-        case DW_TAG_union_type:
-          s.PutCString("union ");
-          break;
-        case DW_TAG_unspecified_type:
-          s.PutCString("unspecified ");
-          break;
-        case DW_TAG_volatile_type:
-          s.PutCString("volatile ");
-          break;
-        default:
-          return false;
-        }
+  llvm::Expected<DWARFEnumState> state = die.extract(dwarf2Data, cu, &offset);
+  if (!state) {
+    llvm::consumeError(state.takeError());
+    return false;
+  }
+  if (*state == DWARFEnumState::Complete)
+    return false;
 
-        // Follow the DW_AT_type if possible
-        DWARFFormValue form_value;
-        if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) {
-          uint64_t next_die_offset = form_value.Reference();
-          result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
-        }
+  if (die.IsNULL()) {
+    s.PutCString("NULL");
+    return true;
+  }
+  const char *name = die.GetPubname(dwarf2Data, cu);
+  if (name) {
+    s.PutCString(name);
+    return true;
+  }
 
-        switch (abbrevDecl->Tag()) {
-        case DW_TAG_array_type:
-          s.PutCString("[]");
-          break;
-        case DW_TAG_pointer_type:
-          s.PutChar('*');
-          break;
-        case DW_TAG_ptr_to_member_type:
-          s.PutChar('*');
-          break;
-        case DW_TAG_reference_type:
-          s.PutChar('&');
-          break;
-        default:
-          break;
-        }
-        return result;
-      }
-    }
+  const DWARFAbbreviationDeclaration *abbrevDecl =
+      die.GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
+
+  if (!abbrevDecl)
+    return false;
+
+  switch (abbrevDecl->Tag()) {
+  case DW_TAG_array_type:
+    break; // print out a "[]" after printing the full type of the element
+           // below
+  case DW_TAG_base_type:
+    s.PutCString("base ");
+    break;
+  case DW_TAG_class_type:
+    s.PutCString("class ");
+    break;
+  case DW_TAG_const_type:
+    s.PutCString("const ");
+    break;
+  case DW_TAG_enumeration_type:
+    s.PutCString("enum ");
+    break;
+  case DW_TAG_file_type:
+    s.PutCString("file ");
+    break;
+  case DW_TAG_interface_type:
+    s.PutCString("interface ");
+    break;
+  case DW_TAG_packed_type:
+    s.PutCString("packed ");
+    break;
+  case DW_TAG_pointer_type:
+    break; // print out a '*' after printing the full type below
+  case DW_TAG_ptr_to_member_type:
+    break; // print out a '*' after printing the full type below
+  case DW_TAG_reference_type:
+    break; // print out a '&' after printing the full type below
+  case DW_TAG_restrict_type:
+    s.PutCString("restrict ");
+    break;
+  case DW_TAG_set_type:
+    s.PutCString("set ");
+    break;
+  case DW_TAG_shared_type:
+    s.PutCString("shared ");
+    break;
+  case DW_TAG_string_type:
+    s.PutCString("string ");
+    break;
+  case DW_TAG_structure_type:
+    s.PutCString("struct ");
+    break;
+  case DW_TAG_subrange_type:
+    s.PutCString("subrange ");
+    break;
+  case DW_TAG_subroutine_type:
+    s.PutCString("function ");
+    break;
+  case DW_TAG_thrown_type:
+    s.PutCString("thrown ");
+    break;
+  case DW_TAG_union_type:
+    s.PutCString("union ");
+    break;
+  case DW_TAG_unspecified_type:
+    s.PutCString("unspecified ");
+    break;
+  case DW_TAG_volatile_type:
+    s.PutCString("volatile ");
+    break;
+  default:
+    return false;
   }
-  return false;
+
+  // Follow the DW_AT_type if possible
+  DWARFFormValue form_value;
+  bool result = true;
+  if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_type, form_value)) {
+    uint64_t next_die_offset = form_value.Reference();
+    result = AppendTypeName(dwarf2Data, cu, next_die_offset, s);
+  }
+
+  switch (abbrevDecl->Tag()) {
+  case DW_TAG_array_type:
+    s.PutCString("[]");
+    break;
+  case DW_TAG_pointer_type:
+    s.PutChar('*');
+    break;
+  case DW_TAG_ptr_to_member_type:
+    s.PutChar('*');
+    break;
+  case DW_TAG_reference_type:
+    s.PutChar('&');
+    break;
+  default:
+    break;
+  }
+  return result;
 }
 
 //----------------------------------------------------------------------
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to