//===-- DWARFDebugInfoEntry.cpp ---------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "DWARFDebugInfoEntry.h"

#include <assert.h>

#include <algorithm>

#include "lldb/Core/Module.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Utility/Stream.h"

#include "DWARFCompileUnit.h"
#include "DWARFDIECollection.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
#include "DWARFFormValue.h"
#include "SymbolFileDWARF.h"
#include "SymbolFileDWARFDwo.h"

using namespace lldb_private;
using namespace std;
extern int g_verbose;

bool DWARFDebugInfoEntry::FastExtract(
    const DWARFDataExtractor &debug_info_data, const DWARFCompileUnit *cu,
    const DWARFFormValue::FixedFormSizes &fixed_form_sizes,
    lldb::offset_t *offset_ptr) {
  m_offset = *offset_ptr;
  m_parent_idx = 0;
  m_sibling_idx = 0;
  m_empty_children = false;
  const uint64_t abbr_idx = debug_info_data.GetULEB128(offset_ptr);
  assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
  m_abbr_idx = abbr_idx;

  // assert (fixed_form_sizes);  // For best performance this should be
  // specified!

  if (m_abbr_idx) {
    lldb::offset_t offset = *offset_ptr;

    const DWARFAbbreviationDeclaration *abbrevDecl =
        cu->GetAbbreviations()->GetAbbreviationDeclaration(m_abbr_idx);

    if (abbrevDecl == NULL) {
      cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
          "{0x%8.8x}: invalid abbreviation code %u, please file a bug and "
          "attach the file at the start of this error message",
          m_offset, (unsigned)abbr_idx);
      // WE can't parse anymore if the DWARF is borked...
      *offset_ptr = UINT32_MAX;
      return false;
    }
    m_tag = abbrevDecl->Tag();
    m_has_children = abbrevDecl->HasChildren();
    // Skip all data in the .debug_info for the attributes
    const uint32_t numAttributes = abbrevDecl->NumAttributes();
    uint32_t i;
    dw_form_t form;
    for (i = 0; i < numAttributes; ++i) {
      form = abbrevDecl->GetFormByIndexUnchecked(i);

      const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
      if (fixed_skip_size)
        offset += fixed_skip_size;
      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_unchecked(&offset);
            break;
          case DW_FORM_block2:
            form_size = debug_info_data.GetU16_unchecked(&offset);
            break;
          case DW_FORM_block4:
            form_size = debug_info_data.GetU32_unchecked(&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 = cu->IsDWARF64() ? 8 : 4;
            break;

          // 0 sized form
          case DW_FORM_flag_present:
            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_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_is_indirect = true;
            form = debug_info_data.GetULEB128(&offset);
            break;

          case DW_FORM_strp:
          case DW_FORM_sec_offset:
            if (cu->IsDWARF64())
              debug_info_data.GetU64(offset_ptr);
            else
              debug_info_data.GetU32(offset_ptr);
            break;

          default:
            *offset_ptr = m_offset;
            return false;
          }
          offset += form_size;

        } while (form_is_indirect);
      }
    }
    *offset_ptr = offset;
    return true;
  } else {
    m_tag = 0;
    m_has_children = false;
    return true; // NULL debug tag entry
  }

  return false;
}

//----------------------------------------------------------------------
// Extract
//
// Extract a debug info entry for a given compile unit from the
// .debug_info and .debug_abbrev data within the SymbolFileDWARF class
// starting at the given offset
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::Extract(SymbolFileDWARF *dwarf2Data,
                                  const DWARFCompileUnit *cu,
                                  lldb::offset_t *offset_ptr) {
  const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
  //    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);
    assert(abbr_idx < (1 << DIE_ABBR_IDX_BITSIZE));
    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();

        bool isCompileUnitTag = m_tag == DW_TAG_compile_unit;
        if (cu && isCompileUnitTag)
          const_cast<DWARFCompileUnit *>(cu)->SetBaseAddress(0);

        // Skip all data in the .debug_info for the attributes
        const uint32_t numAttributes = abbrevDecl->NumAttributes();
        uint32_t i;
        dw_attr_t attr;
        dw_form_t form;
        for (i = 0; i < numAttributes; ++i) {
          abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);

          if (isCompileUnitTag &&
              ((attr == DW_AT_entry_pc) || (attr == DW_AT_low_pc))) {
            DWARFFormValue form_value(cu, form);
            if (form_value.ExtractValue(debug_info_data, &offset)) {
              if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
                const_cast<DWARFCompileUnit *>(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 = cu->IsDWARF64() ? 8 : 4;
                break;

              // 0 sized form
              case DW_FORM_flag_present:
                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_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:
                if (cu->IsDWARF64())
                  debug_info_data.GetU64(offset_ptr);
                else
                  debug_info_data.GetU32(offset_ptr);
                break;

              default:
                *offset_ptr = offset;
                return false;
              }

              offset += form_size;
            } while (form_is_indirect);
          }
        }
        *offset_ptr = offset;
        return true;
      }
    } else {
      m_tag = 0;
      m_has_children = false;
      *offset_ptr = offset;
      return true; // NULL debug tag entry
    }
  }

  return false;
}

//----------------------------------------------------------------------
// DumpAncestry
//
// Dumps all of a debug information entries parents up until oldest and
// all of it's attributes to the specified stream.
//----------------------------------------------------------------------
void DWARFDebugInfoEntry::DumpAncestry(SymbolFileDWARF *dwarf2Data,
                                       const DWARFCompileUnit *cu,
                                       const DWARFDebugInfoEntry *oldest,
                                       Stream &s,
                                       uint32_t recurse_depth) const {
  const DWARFDebugInfoEntry *parent = GetParent();
  if (parent && parent != oldest)
    parent->DumpAncestry(dwarf2Data, cu, oldest, s, 0);
  Dump(dwarf2Data, cu, s, recurse_depth);
}

//----------------------------------------------------------------------
// GetDIENamesAndRanges
//
// Gets the valid address ranges for a given DIE by looking for a
// DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges
// attributes.
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, const char *&name,
    const char *&mangled, DWARFRangeList &ranges, int &decl_file,
    int &decl_line, int &decl_column, int &call_file, int &call_line,
    int &call_column, DWARFExpression *frame_base) const {
  if (dwarf2Data == nullptr)
    return false;

  SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
  if (dwo_symbol_file)
    return GetDIENamesAndRanges(
        dwo_symbol_file, dwo_symbol_file->GetCompileUnit(), name, mangled,
        ranges, decl_file, decl_line, decl_column, call_file, call_line,
        call_column, frame_base);

  dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
  dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
  std::vector<DIERef> die_refs;
  bool set_frame_base_loclist_addr = false;

  lldb::offset_t offset;
  const DWARFAbbreviationDeclaration *abbrevDecl =
      GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);

  lldb::ModuleSP module = dwarf2Data->GetObjectFile()->GetModule();

  if (abbrevDecl) {
    const DWARFDataExtractor &debug_info_data =
        dwarf2Data->get_debug_info_data();

    if (!debug_info_data.ValidOffset(offset))
      return false;

    const uint32_t numAttributes = abbrevDecl->NumAttributes();
    uint32_t i;
    dw_attr_t attr;
    dw_form_t form;
    bool do_offset = false;

    for (i = 0; i < numAttributes; ++i) {
      abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);
      DWARFFormValue form_value(cu, form);
      if (form_value.ExtractValue(debug_info_data, &offset)) {
        switch (attr) {
        case DW_AT_low_pc:
          lo_pc = form_value.Address();

          if (do_offset)
            hi_pc += lo_pc;
          do_offset = false;
          break;

        case DW_AT_entry_pc:
          lo_pc = form_value.Address();
          break;

        case DW_AT_high_pc:
          if (form_value.Form() == DW_FORM_addr ||
              form_value.Form() == DW_FORM_GNU_addr_index) {
            hi_pc = form_value.Address();
          } else {
            hi_pc = form_value.Unsigned();
            if (lo_pc == LLDB_INVALID_ADDRESS)
              do_offset = hi_pc != LLDB_INVALID_ADDRESS;
            else
              hi_pc += lo_pc; // DWARF 4 introduces <offset-from-lo-pc> to save
                              // on relocations
          }
          break;

        case DW_AT_ranges: {
          const DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
          if (debug_ranges) {
            debug_ranges->FindRanges(cu->GetRangesBase(), form_value.Unsigned(), ranges);
            // All DW_AT_ranges are relative to the base address of the
            // compile unit. We add the compile unit base address to make
            // sure all the addresses are properly fixed up.
            ranges.Slide(cu->GetBaseAddress());
          } else {
            cu->GetSymbolFileDWARF()->GetObjectFile()->GetModule()->ReportError(
                "{0x%8.8x}: DIE has DW_AT_ranges(0x%" PRIx64
                ") attribute yet DWARF has no .debug_ranges, please file a bug "
                "and attach the file at the start of this error message",
                m_offset, form_value.Unsigned());
          }
        } break;

        case DW_AT_name:
          if (name == NULL)
            name = form_value.AsCString();
          break;

        case DW_AT_MIPS_linkage_name:
        case DW_AT_linkage_name:
          if (mangled == NULL)
            mangled = form_value.AsCString();
          break;

        case DW_AT_abstract_origin:
          die_refs.emplace_back(form_value);
          break;

        case DW_AT_specification:
          die_refs.emplace_back(form_value);
          break;

        case DW_AT_decl_file:
          if (decl_file == 0)
            decl_file = form_value.Unsigned();
          break;

        case DW_AT_decl_line:
          if (decl_line == 0)
            decl_line = form_value.Unsigned();
          break;

        case DW_AT_decl_column:
          if (decl_column == 0)
            decl_column = form_value.Unsigned();
          break;

        case DW_AT_call_file:
          if (call_file == 0)
            call_file = form_value.Unsigned();
          break;

        case DW_AT_call_line:
          if (call_line == 0)
            call_line = form_value.Unsigned();
          break;

        case DW_AT_call_column:
          if (call_column == 0)
            call_column = form_value.Unsigned();
          break;

        case DW_AT_frame_base:
          if (frame_base) {
            if (form_value.BlockData()) {
              uint32_t block_offset =
                  form_value.BlockData() - debug_info_data.GetDataStart();
              uint32_t block_length = form_value.Unsigned();
              frame_base->SetOpcodeData(module, debug_info_data, block_offset,
                                        block_length);
            } else {
              const DWARFDataExtractor &debug_loc_data =
                  dwarf2Data->get_debug_loc_data();
              const dw_offset_t debug_loc_offset = form_value.Unsigned();

              size_t loc_list_length = DWARFExpression::LocationListSize(
                  cu, debug_loc_data, debug_loc_offset);
              if (loc_list_length > 0) {
                frame_base->SetOpcodeData(module, debug_loc_data,
                                          debug_loc_offset, loc_list_length);
                if (lo_pc != LLDB_INVALID_ADDRESS) {
                  assert(lo_pc >= cu->GetBaseAddress());
                  frame_base->SetLocationListSlide(lo_pc -
                                                   cu->GetBaseAddress());
                } else {
                  set_frame_base_loclist_addr = true;
                }
              }
            }
          }
          break;

        default:
          break;
        }
      }
    }
  }

  if (ranges.IsEmpty()) {
    if (lo_pc != LLDB_INVALID_ADDRESS) {
      if (hi_pc != LLDB_INVALID_ADDRESS && hi_pc > lo_pc)
        ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
      else
        ranges.Append(DWARFRangeList::Entry(lo_pc, 0));
    }
  }

  if (set_frame_base_loclist_addr) {
    dw_addr_t lowest_range_pc = ranges.GetMinRangeBase(0);
    assert(lowest_range_pc >= cu->GetBaseAddress());
    frame_base->SetLocationListSlide(lowest_range_pc - cu->GetBaseAddress());
  }

  if (ranges.IsEmpty() || name == NULL || mangled == NULL) {
    for (const DIERef &die_ref : die_refs) {
      if (die_ref.die_offset != DW_INVALID_OFFSET) {
        DWARFDIE die = dwarf2Data->GetDIE(die_ref);
        if (die)
          die.GetDIE()->GetDIENamesAndRanges(
              die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file,
              decl_line, decl_column, call_file, call_line, call_column);
      }
    }
  }
  return !ranges.IsEmpty();
}

//----------------------------------------------------------------------
// Dump
//
// Dumps a debug information entry and all of it's attributes to the
// specified stream.
//----------------------------------------------------------------------
void DWARFDebugInfoEntry::Dump(SymbolFileDWARF *dwarf2Data,
                               const DWARFCompileUnit *cu, Stream &s,
                               uint32_t recurse_depth) const {
  const DWARFDataExtractor &debug_info_data = dwarf2Data->get_debug_info_data();
  lldb::offset_t offset = m_offset;

  if (debug_info_data.ValidOffset(offset)) {
    dw_uleb128_t abbrCode = debug_info_data.GetULEB128(&offset);

    s.Printf("\n0x%8.8x: ", m_offset);
    s.Indent();
    if (abbrCode != m_abbr_idx) {
      s.Printf("error: DWARF has been modified\n");
    } else if (abbrCode) {
      const DWARFAbbreviationDeclaration *abbrevDecl =
          cu->GetAbbreviations()->GetAbbreviationDeclaration(abbrCode);

      if (abbrevDecl) {
        s.PutCString(DW_TAG_value_to_name(abbrevDecl->Tag()));
        s.Printf(" [%u] %c\n", abbrCode, abbrevDecl->HasChildren() ? '*' : ' ');

        // Dump all data in the .debug_info for the attributes
        const uint32_t numAttributes = abbrevDecl->NumAttributes();
        uint32_t i;
        dw_attr_t attr;
        dw_form_t form;
        for (i = 0; i < numAttributes; ++i) {
          abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);

          DumpAttribute(dwarf2Data, cu, debug_info_data, &offset, s, attr,
                        form);
        }

        const DWARFDebugInfoEntry *child = GetFirstChild();
        if (recurse_depth > 0 && child) {
          s.IndentMore();

          while (child) {
            child->Dump(dwarf2Data, cu, s, recurse_depth - 1);
            child = child->GetSibling();
          }
          s.IndentLess();
        }
      } else
        s.Printf("Abbreviation code note found in 'debug_abbrev' class for "
                 "code: %u\n",
                 abbrCode);
    } else {
      s.Printf("NULL\n");
    }
  }
}

void DWARFDebugInfoEntry::DumpLocation(SymbolFileDWARF *dwarf2Data,
                                       DWARFCompileUnit *cu, Stream &s) const {
  const DWARFDIE cu_die = cu->GetCompileUnitDIEOnly();
  const char *cu_name = NULL;
  if (cu_die)
    cu_name = cu_die.GetName();
  const char *obj_file_name = NULL;
  ObjectFile *obj_file = dwarf2Data->GetObjectFile();
  if (obj_file)
    obj_file_name =
        obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>");
  const char *die_name = GetName(dwarf2Data, cu);
  s.Printf("0x%8.8x/0x%8.8x: %-30s (from %s in %s)", cu->GetOffset(),
           GetOffset(), die_name ? die_name : "", cu_name ? cu_name : "<NULL>",
           obj_file_name ? obj_file_name : "<NULL>");
}

//----------------------------------------------------------------------
// DumpAttribute
//
// Dumps a debug information entry attribute along with it's form. Any
// special display of attributes is done (disassemble location lists,
// show enumeration values for attributes, etc).
//----------------------------------------------------------------------
void DWARFDebugInfoEntry::DumpAttribute(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
    const DWARFDataExtractor &debug_info_data, lldb::offset_t *offset_ptr,
    Stream &s, dw_attr_t attr, dw_form_t form) {
  bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);

  s.Printf("            ");
  s.Indent(DW_AT_value_to_name(attr));

  if (show_form) {
    s.Printf("[%s", DW_FORM_value_to_name(form));
  }

  DWARFFormValue form_value(cu, form);

  if (!form_value.ExtractValue(debug_info_data, offset_ptr))
    return;

  if (show_form) {
    if (form == DW_FORM_indirect) {
      s.Printf(" [%s]", DW_FORM_value_to_name(form_value.Form()));
    }

    s.PutCString("] ");
  }

  s.PutCString("( ");

  // Check to see if we have any special attribute formatters
  switch (attr) {
  case DW_AT_stmt_list:
    s.Printf("0x%8.8" PRIx64, form_value.Unsigned());
    break;

  case DW_AT_language:
    s.PutCString(DW_LANG_value_to_name(form_value.Unsigned()));
    break;

  case DW_AT_encoding:
    s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
    break;

  case DW_AT_frame_base:
  case DW_AT_location:
  case DW_AT_data_member_location: {
    const uint8_t *blockData = form_value.BlockData();
    if (blockData) {
      // Location description is inlined in data in the form value
      DWARFDataExtractor locationData(debug_info_data,
                                      (*offset_ptr) - form_value.Unsigned(),
                                      form_value.Unsigned());
      DWARFExpression::PrintDWARFExpression(
          s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false);
    } else {
      // We have a location list offset as the value that is
      // the offset into the .debug_loc section that describes
      // the value over it's lifetime
      uint64_t debug_loc_offset = form_value.Unsigned();
      if (dwarf2Data) {
        DWARFExpression::PrintDWARFLocationList(
            s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
      }
    }
  } break;

  case DW_AT_abstract_origin:
  case DW_AT_specification: {
    uint64_t abstract_die_offset = form_value.Reference();
    form_value.Dump(s);
    //  *ostrm_ptr << HEX32 << abstract_die_offset << " ( ";
    GetName(dwarf2Data, cu, abstract_die_offset, s);
  } break;

  case DW_AT_type: {
    uint64_t type_die_offset = form_value.Reference();
    s.PutCString(" ( ");
    AppendTypeName(dwarf2Data, cu, type_die_offset, s);
    s.PutCString(" )");
  } break;

  case DW_AT_ranges: {
    lldb::offset_t ranges_offset = form_value.Unsigned();
    dw_addr_t base_addr = cu ? cu->GetBaseAddress() : 0;
    if (dwarf2Data)
      DWARFDebugRanges::Dump(s, dwarf2Data->get_debug_ranges_data(),
                             &ranges_offset, base_addr);
  } break;

  default:
    break;
  }

  s.PutCString(" )\n");
}

//----------------------------------------------------------------------
// Get all attribute values for a given DIE, including following any
// specification or abstract origin attributes and including those in
// the results. Any duplicate attributes will have the first instance
// take precedence (this can happen for declaration attributes).
//----------------------------------------------------------------------
size_t DWARFDebugInfoEntry::GetAttributes(
    const DWARFCompileUnit *cu, DWARFFormValue::FixedFormSizes fixed_form_sizes,
    DWARFAttributes &attributes, uint32_t curr_depth) const {
  SymbolFileDWARF *dwarf2Data = nullptr;
  const DWARFAbbreviationDeclaration *abbrevDecl = nullptr;
  lldb::offset_t offset = 0;
  if (cu) {
    if (m_tag != DW_TAG_compile_unit) {
      SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
      if (dwo_symbol_file)
        return GetAttributes(dwo_symbol_file->GetCompileUnit(),
                             fixed_form_sizes, attributes, curr_depth);
    }

    dwarf2Data = cu->GetSymbolFileDWARF();
    abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
  }

  if (abbrevDecl) {
    const DWARFDataExtractor &debug_info_data =
        dwarf2Data->get_debug_info_data();

    if (fixed_form_sizes.Empty())
      fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize(
          cu->GetAddressByteSize(), cu->IsDWARF64());

    const uint32_t num_attributes = abbrevDecl->NumAttributes();
    uint32_t i;
    dw_attr_t attr;
    dw_form_t form;
    for (i = 0; i < num_attributes; ++i) {
      abbrevDecl->GetAttrAndFormByIndexUnchecked(i, attr, form);

      // If we are tracking down DW_AT_specification or DW_AT_abstract_origin
      // attributes, the depth will be non-zero. We need to omit certain
      // attributes that don't make sense.
      switch (attr) {
      case DW_AT_sibling:
      case DW_AT_declaration:
        if (curr_depth > 0) {
          // This attribute doesn't make sense when combined with
          // the DIE that references this DIE. We know a DIE is
          // referencing this DIE because curr_depth is not zero
          break;
        }
        LLVM_FALLTHROUGH;
      default:
        attributes.Append(cu, offset, attr, form);
        break;
      }

      if ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin)) {
        DWARFFormValue form_value(cu, form);
        if (form_value.ExtractValue(debug_info_data, &offset)) {
          dw_offset_t die_offset = form_value.Reference();
          DWARFDIE spec_die =
              const_cast<DWARFCompileUnit *>(cu)->GetDIE(die_offset);
          if (spec_die)
            spec_die.GetAttributes(attributes, curr_depth + 1);
        }
      } else {
        const uint8_t fixed_skip_size = fixed_form_sizes.GetSize(form);
        if (fixed_skip_size)
          offset += fixed_skip_size;
        else
          DWARFFormValue::SkipValue(form, debug_info_data, &offset, cu);
      }
    }
  } else {
    attributes.Clear();
  }
  return attributes.Size();
}

//----------------------------------------------------------------------
// GetAttributeValue
//
// Get the value of an attribute and return the .debug_info offset of the
// attribute if it was properly extracted into form_value, or zero
// if we fail since an offset of zero is invalid for an attribute (it
// would be a compile unit header).
//----------------------------------------------------------------------
dw_offset_t DWARFDebugInfoEntry::GetAttributeValue(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
    const dw_attr_t attr, DWARFFormValue &form_value,
    dw_offset_t *end_attr_offset_ptr,
    bool check_specification_or_abstract_origin) const {
  SymbolFileDWARFDwo *dwo_symbol_file = cu->GetDwoSymbolFile();
  if (dwo_symbol_file && m_tag != DW_TAG_compile_unit)
    return GetAttributeValue(dwo_symbol_file, dwo_symbol_file->GetCompileUnit(),
                             attr, form_value, end_attr_offset_ptr,
                             check_specification_or_abstract_origin);

  lldb::offset_t offset;
  const DWARFAbbreviationDeclaration *abbrevDecl =
      GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);

  if (abbrevDecl) {
    uint32_t attr_idx = abbrevDecl->FindAttributeIndex(attr);

    if (attr_idx != DW_INVALID_INDEX) {
      const DWARFDataExtractor &debug_info_data =
          dwarf2Data->get_debug_info_data();

      uint32_t idx = 0;
      while (idx < attr_idx)
        DWARFFormValue::SkipValue(abbrevDecl->GetFormByIndex(idx++),
                                  debug_info_data, &offset, cu);

      const dw_offset_t attr_offset = offset;
      form_value.SetCompileUnit(cu);
      form_value.SetForm(abbrevDecl->GetFormByIndex(idx));
      if (form_value.ExtractValue(debug_info_data, &offset)) {
        if (end_attr_offset_ptr)
          *end_attr_offset_ptr = offset;
        return attr_offset;
      }
    }
  }

  if (check_specification_or_abstract_origin) {
    if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) {
      DWARFDIE die =
          const_cast<DWARFCompileUnit *>(cu)->GetDIE(form_value.Reference());
      if (die) {
        dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
            die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
            false);
        if (die_offset)
          return die_offset;
      }
    }

    if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) {
      DWARFDIE die =
          const_cast<DWARFCompileUnit *>(cu)->GetDIE(form_value.Reference());
      if (die) {
        dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
            die.GetDWARF(), die.GetCU(), attr, form_value, end_attr_offset_ptr,
            false);
        if (die_offset)
          return die_offset;
      }
    }
  }

  if (!dwo_symbol_file)
    return 0;

  DWARFCompileUnit *dwo_cu = dwo_symbol_file->GetCompileUnit();
  if (!dwo_cu)
    return 0;

  DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly();
  if (!dwo_cu_die.IsValid())
    return 0;

  return dwo_cu_die.GetDIE()->GetAttributeValue(
      dwo_symbol_file, dwo_cu, attr, form_value, end_attr_offset_ptr,
      check_specification_or_abstract_origin);
}

//----------------------------------------------------------------------
// GetAttributeValueAsString
//
// Get the value of an attribute as a string return it. The resulting
// pointer to the string data exists within the supplied SymbolFileDWARF
// and will only be available as long as the SymbolFileDWARF is still around
// and it's content doesn't change.
//----------------------------------------------------------------------
const char *DWARFDebugInfoEntry::GetAttributeValueAsString(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
    const dw_attr_t attr, const char *fail_value,
    bool check_specification_or_abstract_origin) const {
  DWARFFormValue form_value;
  if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
                        check_specification_or_abstract_origin))
    return form_value.AsCString();
  return fail_value;
}

//----------------------------------------------------------------------
// GetAttributeValueAsUnsigned
//
// Get the value of an attribute as unsigned and return it.
//----------------------------------------------------------------------
uint64_t DWARFDebugInfoEntry::GetAttributeValueAsUnsigned(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
    const dw_attr_t attr, uint64_t fail_value,
    bool check_specification_or_abstract_origin) const {
  DWARFFormValue form_value;
  if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
                        check_specification_or_abstract_origin))
    return form_value.Unsigned();
  return fail_value;
}

//----------------------------------------------------------------------
// GetAttributeValueAsSigned
//
// Get the value of an attribute a signed value and return it.
//----------------------------------------------------------------------
int64_t DWARFDebugInfoEntry::GetAttributeValueAsSigned(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
    const dw_attr_t attr, int64_t fail_value,
    bool check_specification_or_abstract_origin) const {
  DWARFFormValue form_value;
  if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
                        check_specification_or_abstract_origin))
    return form_value.Signed();
  return fail_value;
}

//----------------------------------------------------------------------
// GetAttributeValueAsReference
//
// Get the value of an attribute as reference and fix up and compile
// unit relative offsets as needed.
//----------------------------------------------------------------------
uint64_t DWARFDebugInfoEntry::GetAttributeValueAsReference(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
    const dw_attr_t attr, uint64_t fail_value,
    bool check_specification_or_abstract_origin) const {
  DWARFFormValue form_value;
  if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
                        check_specification_or_abstract_origin))
    return form_value.Reference();
  return fail_value;
}

uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
    const dw_attr_t attr, uint64_t fail_value,
    bool check_specification_or_abstract_origin) const {
  DWARFFormValue form_value;
  if (GetAttributeValue(dwarf2Data, cu, attr, form_value, nullptr,
                        check_specification_or_abstract_origin))
    return form_value.Address();
  return fail_value;
}

//----------------------------------------------------------------------
// GetAttributeHighPC
//
// Get the hi_pc, adding hi_pc to lo_pc when specified
// as an <offset-from-low-pc>.
//
// Returns the hi_pc or fail_value.
//----------------------------------------------------------------------
dw_addr_t DWARFDebugInfoEntry::GetAttributeHighPC(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t lo_pc,
    uint64_t fail_value, bool check_specification_or_abstract_origin) const {
  DWARFFormValue form_value;
  if (GetAttributeValue(dwarf2Data, cu, DW_AT_high_pc, form_value, nullptr,
                        check_specification_or_abstract_origin)) {
    dw_form_t form = form_value.Form();
    if (form == DW_FORM_addr || form == DW_FORM_GNU_addr_index)
      return form_value.Address();

    // DWARF4 can specify the hi_pc as an <offset-from-lowpc>
    return lo_pc + form_value.Unsigned();
  }
  return fail_value;
}

//----------------------------------------------------------------------
// GetAttributeAddressRange
//
// Get the lo_pc and hi_pc, adding hi_pc to lo_pc when specified
// as an <offset-from-low-pc>.
//
// Returns true or sets lo_pc and hi_pc to fail_value.
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::GetAttributeAddressRange(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu, dw_addr_t &lo_pc,
    dw_addr_t &hi_pc, uint64_t fail_value,
    bool check_specification_or_abstract_origin) const {
  lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value,
                                     check_specification_or_abstract_origin);
  if (lo_pc != fail_value) {
    hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value,
                               check_specification_or_abstract_origin);
    if (hi_pc != fail_value)
      return true;
  }
  lo_pc = fail_value;
  hi_pc = fail_value;
  return false;
}

size_t DWARFDebugInfoEntry::GetAttributeAddressRanges(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
    DWARFRangeList &ranges, bool check_hi_lo_pc,
    bool check_specification_or_abstract_origin) const {
  ranges.Clear();

  dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
      dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET,
      check_specification_or_abstract_origin);
  if (debug_ranges_offset != DW_INVALID_OFFSET) {
    DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();

    debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges);
    ranges.Slide(cu->GetBaseAddress());
  } else if (check_hi_lo_pc) {
    dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
    dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
    if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
                                 LLDB_INVALID_ADDRESS,
                                 check_specification_or_abstract_origin)) {
      if (lo_pc < hi_pc)
        ranges.Append(DWARFRangeList::Entry(lo_pc, hi_pc - lo_pc));
    }
  }
  return ranges.GetSize();
}

//----------------------------------------------------------------------
// GetName
//
// Get value of the DW_AT_name attribute and return it if one exists,
// else return NULL.
//----------------------------------------------------------------------
const char *DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
                                         const DWARFCompileUnit *cu) const {
  return GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
}

//----------------------------------------------------------------------
// GetMangledName
//
// Get value of the DW_AT_MIPS_linkage_name attribute and return it if
// one exists, else return the value of the DW_AT_name attribute
//----------------------------------------------------------------------
const char *
DWARFDebugInfoEntry::GetMangledName(SymbolFileDWARF *dwarf2Data,
                                    const DWARFCompileUnit *cu,
                                    bool substitute_name_allowed) const {
  const char *name = nullptr;

  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
                                   nullptr, true);
  if (name)
    return name;

  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
                                   true);
  if (name)
    return name;

  if (!substitute_name_allowed)
    return nullptr;

  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
  return name;
}

//----------------------------------------------------------------------
// GetPubname
//
// Get value the name for a DIE as it should appear for a
// .debug_pubnames or .debug_pubtypes section.
//----------------------------------------------------------------------
const char *DWARFDebugInfoEntry::GetPubname(SymbolFileDWARF *dwarf2Data,
                                            const DWARFCompileUnit *cu) const {
  const char *name = nullptr;
  if (!dwarf2Data)
    return name;

  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name,
                                   nullptr, true);
  if (name)
    return name;

  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr,
                                   true);
  if (name)
    return name;

  name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr, true);
  return name;
}

//----------------------------------------------------------------------
// GetName
//
// Get value of the DW_AT_name attribute for a debug information entry
// that exists at offset "die_offset" and place that value into the
// supplied stream object. If the DIE is a NULL object "NULL" is placed
// into the stream, and if no DW_AT_name attribute exists for the DIE
// then nothing is printed.
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::GetName(SymbolFileDWARF *dwarf2Data,
                                  const DWARFCompileUnit *cu,
                                  const dw_offset_t die_offset, Stream &s) {
  if (dwarf2Data == NULL) {
    s.PutCString("NULL");
    return false;
  }

  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;
      }
    }
  }
  return false;
}

//----------------------------------------------------------------------
// AppendTypeName
//
// Follows the type name definition down through all needed tags to
// end up with a fully qualified type name and dump the results to
// the supplied stream. This is used to show the name of types given
// a type identifier.
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::AppendTypeName(SymbolFileDWARF *dwarf2Data,
                                         const DWARFCompileUnit *cu,
                                         const dw_offset_t die_offset,
                                         Stream &s) {
  if (dwarf2Data == NULL) {
    s.PutCString("NULL");
    return false;
  }

  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;
        }

        // 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);
        }

        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;
      }
    }
  }
  return false;
}

bool DWARFDebugInfoEntry::Contains(const DWARFDebugInfoEntry *die) const {
  if (die) {
    const dw_offset_t die_offset = die->GetOffset();
    if (die_offset > GetOffset()) {
      const DWARFDebugInfoEntry *sibling = GetSibling();
      assert(sibling); // TODO: take this out
      if (sibling)
        return die_offset < sibling->GetOffset();
    }
  }
  return false;
}

//----------------------------------------------------------------------
// BuildAddressRangeTable
//----------------------------------------------------------------------
void DWARFDebugInfoEntry::BuildAddressRangeTable(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
    DWARFDebugAranges *debug_aranges) const {
  if (m_tag) {
    if (m_tag == DW_TAG_subprogram) {
      dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
      dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
      if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
                                   LLDB_INVALID_ADDRESS)) {
        /// printf("BuildAddressRangeTable() 0x%8.8x: %30s: [0x%8.8x -
        /// 0x%8.8x)\n", m_offset, DW_TAG_value_to_name(tag), lo_pc, hi_pc);
        debug_aranges->AppendRange(cu->GetOffset(), lo_pc, hi_pc);
      }
    }

    const DWARFDebugInfoEntry *child = GetFirstChild();
    while (child) {
      child->BuildAddressRangeTable(dwarf2Data, cu, debug_aranges);
      child = child->GetSibling();
    }
  }
}

//----------------------------------------------------------------------
// BuildFunctionAddressRangeTable
//
// This function is very similar to the BuildAddressRangeTable function
// except that the actual DIE offset for the function is placed in the
// table instead of the compile unit offset (which is the way the
// standard .debug_aranges section does it).
//----------------------------------------------------------------------
void DWARFDebugInfoEntry::BuildFunctionAddressRangeTable(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
    DWARFDebugAranges *debug_aranges) const {
  if (m_tag) {
    if (m_tag == DW_TAG_subprogram) {
      dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
      dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
      if (GetAttributeAddressRange(dwarf2Data, cu, lo_pc, hi_pc,
                                   LLDB_INVALID_ADDRESS)) {
        //  printf("BuildAddressRangeTable() 0x%8.8x: [0x%16.16" PRIx64 " -
        //  0x%16.16" PRIx64 ")\n", m_offset, lo_pc, hi_pc); // DEBUG ONLY
        debug_aranges->AppendRange(GetOffset(), lo_pc, hi_pc);
      }
    }

    const DWARFDebugInfoEntry *child = GetFirstChild();
    while (child) {
      child->BuildFunctionAddressRangeTable(dwarf2Data, cu, debug_aranges);
      child = child->GetSibling();
    }
  }
}

void DWARFDebugInfoEntry::GetDeclContextDIEs(
    DWARFCompileUnit *cu, DWARFDIECollection &decl_context_dies) const {

  DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
  die.GetDeclContextDIEs(decl_context_dies);
}

void DWARFDebugInfoEntry::GetDWARFDeclContext(
    SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
    DWARFDeclContext &dwarf_decl_ctx) const {
  const dw_tag_t tag = Tag();
  if (tag != DW_TAG_compile_unit) {
    dwarf_decl_ctx.AppendDeclContext(tag, GetName(dwarf2Data, cu));
    DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
    if (parent_decl_ctx_die && parent_decl_ctx_die.GetDIE() != this) {
      if (parent_decl_ctx_die.Tag() != DW_TAG_compile_unit)
        parent_decl_ctx_die.GetDIE()->GetDWARFDeclContext(
            parent_decl_ctx_die.GetDWARF(), parent_decl_ctx_die.GetCU(),
            dwarf_decl_ctx);
    }
  }
}

bool DWARFDebugInfoEntry::MatchesDWARFDeclContext(
    SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
    const DWARFDeclContext &dwarf_decl_ctx) const {

  DWARFDeclContext this_dwarf_decl_ctx;
  GetDWARFDeclContext(dwarf2Data, cu, this_dwarf_decl_ctx);
  return this_dwarf_decl_ctx == dwarf_decl_ctx;
}

DWARFDIE
DWARFDebugInfoEntry::GetParentDeclContextDIE(SymbolFileDWARF *dwarf2Data,
                                             DWARFCompileUnit *cu) const {
  DWARFAttributes attributes;
  GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
  return GetParentDeclContextDIE(dwarf2Data, cu, attributes);
}

DWARFDIE
DWARFDebugInfoEntry::GetParentDeclContextDIE(
    SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
    const DWARFAttributes &attributes) const {
  DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));

  while (die) {
    // If this is the original DIE that we are searching for a declaration
    // for, then don't look in the cache as we don't want our own decl
    // context to be our decl context...
    if (die.GetDIE() != this) {
      switch (die.Tag()) {
      case DW_TAG_compile_unit:
      case DW_TAG_namespace:
      case DW_TAG_structure_type:
      case DW_TAG_union_type:
      case DW_TAG_class_type:
        return die;

      default:
        break;
      }
    }

    dw_offset_t die_offset;

    die_offset =
        attributes.FormValueAsUnsigned(DW_AT_specification, DW_INVALID_OFFSET);
    if (die_offset != DW_INVALID_OFFSET) {
      DWARFDIE spec_die = cu->GetDIE(die_offset);
      if (spec_die) {
        DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
        if (decl_ctx_die)
          return decl_ctx_die;
      }
    }

    die_offset = attributes.FormValueAsUnsigned(DW_AT_abstract_origin,
                                                DW_INVALID_OFFSET);
    if (die_offset != DW_INVALID_OFFSET) {
      DWARFDIE abs_die = cu->GetDIE(die_offset);
      if (abs_die) {
        DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
        if (decl_ctx_die)
          return decl_ctx_die;
      }
    }

    die = die.GetParent();
  }
  return DWARFDIE();
}

const char *DWARFDebugInfoEntry::GetQualifiedName(SymbolFileDWARF *dwarf2Data,
                                                  DWARFCompileUnit *cu,
                                                  std::string &storage) const {
  DWARFAttributes attributes;
  GetAttributes(cu, DWARFFormValue::FixedFormSizes(), attributes);
  return GetQualifiedName(dwarf2Data, cu, attributes, storage);
}

const char *DWARFDebugInfoEntry::GetQualifiedName(
    SymbolFileDWARF *dwarf2Data, DWARFCompileUnit *cu,
    const DWARFAttributes &attributes, std::string &storage) const {

  const char *name = GetName(dwarf2Data, cu);

  if (name) {
    DWARFDIE parent_decl_ctx_die = GetParentDeclContextDIE(dwarf2Data, cu);
    storage.clear();
    // TODO: change this to get the correct decl context parent....
    while (parent_decl_ctx_die) {
      const dw_tag_t parent_tag = parent_decl_ctx_die.Tag();
      switch (parent_tag) {
      case DW_TAG_namespace: {
        const char *namespace_name = parent_decl_ctx_die.GetName();
        if (namespace_name) {
          storage.insert(0, "::");
          storage.insert(0, namespace_name);
        } else {
          storage.insert(0, "(anonymous namespace)::");
        }
        parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
      } break;

      case DW_TAG_class_type:
      case DW_TAG_structure_type:
      case DW_TAG_union_type: {
        const char *class_union_struct_name = parent_decl_ctx_die.GetName();

        if (class_union_struct_name) {
          storage.insert(0, "::");
          storage.insert(0, class_union_struct_name);
        }
        parent_decl_ctx_die = parent_decl_ctx_die.GetParentDeclContextDIE();
      } break;

      default:
        parent_decl_ctx_die.Clear();
        break;
      }
    }

    if (storage.empty())
      storage.append("::");

    storage.append(name);
  }
  if (storage.empty())
    return NULL;
  return storage.c_str();
}

//----------------------------------------------------------------------
// LookupAddress
//----------------------------------------------------------------------
bool DWARFDebugInfoEntry::LookupAddress(const dw_addr_t address,
                                        SymbolFileDWARF *dwarf2Data,
                                        const DWARFCompileUnit *cu,
                                        DWARFDebugInfoEntry **function_die,
                                        DWARFDebugInfoEntry **block_die) {
  bool found_address = false;
  if (m_tag) {
    bool check_children = false;
    bool match_addr_range = false;
    //  printf("0x%8.8x: %30s: address = 0x%8.8x - ", m_offset,
    //  DW_TAG_value_to_name(tag), address);
    switch (m_tag) {
    case DW_TAG_array_type:
      break;
    case DW_TAG_class_type:
      check_children = true;
      break;
    case DW_TAG_entry_point:
      break;
    case DW_TAG_enumeration_type:
      break;
    case DW_TAG_formal_parameter:
      break;
    case DW_TAG_imported_declaration:
      break;
    case DW_TAG_label:
      break;
    case DW_TAG_lexical_block:
      check_children = true;
      match_addr_range = true;
      break;
    case DW_TAG_member:
      break;
    case DW_TAG_pointer_type:
      break;
    case DW_TAG_reference_type:
      break;
    case DW_TAG_compile_unit:
      match_addr_range = true;
      break;
    case DW_TAG_string_type:
      break;
    case DW_TAG_structure_type:
      check_children = true;
      break;
    case DW_TAG_subroutine_type:
      break;
    case DW_TAG_typedef:
      break;
    case DW_TAG_union_type:
      break;
    case DW_TAG_unspecified_parameters:
      break;
    case DW_TAG_variant:
      break;
    case DW_TAG_common_block:
      check_children = true;
      break;
    case DW_TAG_common_inclusion:
      break;
    case DW_TAG_inheritance:
      break;
    case DW_TAG_inlined_subroutine:
      check_children = true;
      match_addr_range = true;
      break;
    case DW_TAG_module:
      match_addr_range = true;
      break;
    case DW_TAG_ptr_to_member_type:
      break;
    case DW_TAG_set_type:
      break;
    case DW_TAG_subrange_type:
      break;
    case DW_TAG_with_stmt:
      break;
    case DW_TAG_access_declaration:
      break;
    case DW_TAG_base_type:
      break;
    case DW_TAG_catch_block:
      match_addr_range = true;
      break;
    case DW_TAG_const_type:
      break;
    case DW_TAG_constant:
      break;
    case DW_TAG_enumerator:
      break;
    case DW_TAG_file_type:
      break;
    case DW_TAG_friend:
      break;
    case DW_TAG_namelist:
      break;
    case DW_TAG_namelist_item:
      break;
    case DW_TAG_packed_type:
      break;
    case DW_TAG_subprogram:
      match_addr_range = true;
      break;
    case DW_TAG_template_type_parameter:
      break;
    case DW_TAG_template_value_parameter:
      break;
    case DW_TAG_GNU_template_parameter_pack:
      break;
    case DW_TAG_thrown_type:
      break;
    case DW_TAG_try_block:
      match_addr_range = true;
      break;
    case DW_TAG_variant_part:
      break;
    case DW_TAG_variable:
      break;
    case DW_TAG_volatile_type:
      break;
    case DW_TAG_dwarf_procedure:
      break;
    case DW_TAG_restrict_type:
      break;
    case DW_TAG_interface_type:
      break;
    case DW_TAG_namespace:
      check_children = true;
      break;
    case DW_TAG_imported_module:
      break;
    case DW_TAG_unspecified_type:
      break;
    case DW_TAG_partial_unit:
      break;
    case DW_TAG_imported_unit:
      break;
    case DW_TAG_shared_type:
      break;
    default:
      break;
    }

    if (match_addr_range) {
      dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc,
                                                   LLDB_INVALID_ADDRESS);
      if (lo_pc != LLDB_INVALID_ADDRESS) {
        dw_addr_t hi_pc =
            GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
        if (hi_pc != LLDB_INVALID_ADDRESS) {
          //  printf("\n0x%8.8x: %30s: address = 0x%8.8x  [0x%8.8x - 0x%8.8x) ",
          //  m_offset, DW_TAG_value_to_name(tag), address, lo_pc, hi_pc);
          if ((lo_pc <= address) && (address < hi_pc)) {
            found_address = true;
            //  puts("***MATCH***");
            switch (m_tag) {
            case DW_TAG_compile_unit: // File
              check_children = ((function_die != NULL) || (block_die != NULL));
              break;

            case DW_TAG_subprogram: // Function
              if (function_die)
                *function_die = this;
              check_children = (block_die != NULL);
              break;

            case DW_TAG_inlined_subroutine: // Inlined Function
            case DW_TAG_lexical_block:      // Block { } in code
              if (block_die) {
                *block_die = this;
                check_children = true;
              }
              break;

            default:
              check_children = true;
              break;
            }
          }
        } else { // compile units may not have a valid high/low pc when there
          // are address gaps in subroutines so we must always search
          // if there is no valid high and low PC
          check_children = (m_tag == DW_TAG_compile_unit) &&
                           ((function_die != NULL) || (block_die != NULL));
        }
      } else {
        dw_offset_t debug_ranges_offset = GetAttributeValueAsUnsigned(
            dwarf2Data, cu, DW_AT_ranges, DW_INVALID_OFFSET);
        if (debug_ranges_offset != DW_INVALID_OFFSET) {
          DWARFRangeList ranges;
          DWARFDebugRanges *debug_ranges = dwarf2Data->DebugRanges();
          debug_ranges->FindRanges(cu->GetRangesBase(), debug_ranges_offset, ranges);
          // All DW_AT_ranges are relative to the base address of the
          // compile unit. We add the compile unit base address to make
          // sure all the addresses are properly fixed up.
          ranges.Slide(cu->GetBaseAddress());
          if (ranges.FindEntryThatContains(address)) {
            found_address = true;
            //  puts("***MATCH***");
            switch (m_tag) {
            case DW_TAG_compile_unit: // File
              check_children = ((function_die != NULL) || (block_die != NULL));
              break;

            case DW_TAG_subprogram: // Function
              if (function_die)
                *function_die = this;
              check_children = (block_die != NULL);
              break;

            case DW_TAG_inlined_subroutine: // Inlined Function
            case DW_TAG_lexical_block:      // Block { } in code
              if (block_die) {
                *block_die = this;
                check_children = true;
              }
              break;

            default:
              check_children = true;
              break;
            }
          } else {
            check_children = false;
          }
        }
      }
    }

    if (check_children) {
      //  printf("checking children\n");
      DWARFDebugInfoEntry *child = GetFirstChild();
      while (child) {
        if (child->LookupAddress(address, dwarf2Data, cu, function_die,
                                 block_die))
          return true;
        child = child->GetSibling();
      }
    }
  }
  return found_address;
}

const DWARFAbbreviationDeclaration *
DWARFDebugInfoEntry::GetAbbreviationDeclarationPtr(
    SymbolFileDWARF *dwarf2Data, const DWARFCompileUnit *cu,
    lldb::offset_t &offset) const {
  if (dwarf2Data) {
    offset = GetOffset();

    const DWARFAbbreviationDeclarationSet *abbrev_set = cu->GetAbbreviations();
    if (abbrev_set) {
      const DWARFAbbreviationDeclaration *abbrev_decl =
          abbrev_set->GetAbbreviationDeclaration(m_abbr_idx);
      if (abbrev_decl) {
        // Make sure the abbreviation code still matches. If it doesn't and
        // the DWARF data was mmap'ed, the backing file might have been modified
        // which is bad news.
        const uint64_t abbrev_code =
            dwarf2Data->get_debug_info_data().GetULEB128(&offset);

        if (abbrev_decl->Code() == abbrev_code)
          return abbrev_decl;

        dwarf2Data->GetObjectFile()->GetModule()->ReportErrorIfModifyDetected(
            "0x%8.8x: the DWARF debug information has been modified (abbrev "
            "code was %u, and is now %u)",
            GetOffset(), (uint32_t)abbrev_decl->Code(), (uint32_t)abbrev_code);
      }
    }
  }
  offset = DW_INVALID_OFFSET;
  return NULL;
}

bool DWARFDebugInfoEntry::OffsetLessThan(const DWARFDebugInfoEntry &a,
                                         const DWARFDebugInfoEntry &b) {
  return a.GetOffset() < b.GetOffset();
}

void DWARFDebugInfoEntry::DumpDIECollection(
    Stream &strm, DWARFDebugInfoEntry::collection &die_collection) {
  DWARFDebugInfoEntry::const_iterator pos;
  DWARFDebugInfoEntry::const_iterator end = die_collection.end();
  strm.PutCString("\noffset    parent   sibling  child\n");
  strm.PutCString("--------  -------- -------- --------\n");
  for (pos = die_collection.begin(); pos != end; ++pos) {
    const DWARFDebugInfoEntry &die_ref = *pos;
    const DWARFDebugInfoEntry *p = die_ref.GetParent();
    const DWARFDebugInfoEntry *s = die_ref.GetSibling();
    const DWARFDebugInfoEntry *c = die_ref.GetFirstChild();
    strm.Printf("%.8x: %.8x %.8x %.8x 0x%4.4x %s%s\n", die_ref.GetOffset(),
                p ? p->GetOffset() : 0, s ? s->GetOffset() : 0,
                c ? c->GetOffset() : 0, die_ref.Tag(),
                DW_TAG_value_to_name(die_ref.Tag()),
                die_ref.HasChildren() ? " *" : "");
  }
}
