//===-- 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/Core/Stream.h"
#include "lldb/Expression/DWARFExpression.h"
#include "lldb/Symbol/ObjectFile.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::Error("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 verbose = s.GetVerbose();
  bool show_form = s.GetFlags().Test(DWARFDebugInfo::eDumpFlag_ShowForm);

  if (verbose)
    s.Offset(*offset_ptr);
  else
    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("( ");

  // Always dump form value if verbose is enabled
  if (verbose) {
    form_value.Dump(s);
  }

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

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

  case DW_AT_encoding:
    if (verbose)
      s.PutCString(" ( ");
    s.PutCString(DW_ATE_value_to_name(form_value.Unsigned()));
    if (verbose)
      s.PutCString(" )");
    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) {
      if (!verbose)
        form_value.Dump(s);

      // Location description is inlined in data in the form value
      DWARFDataExtractor locationData(debug_info_data,
                                      (*offset_ptr) - form_value.Unsigned(),
                                      form_value.Unsigned());
      if (verbose)
        s.PutCString(" ( ");
      DWARFExpression::PrintDWARFExpression(
          s, locationData, DWARFCompileUnit::GetAddressByteSize(cu), 4, false);
      if (verbose)
        s.PutCString(" )");
    } 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) {
        if (!verbose)
          form_value.Dump(s);
        DWARFExpression::PrintDWARFLocationList(
            s, cu, dwarf2Data->get_debug_loc_data(), debug_loc_offset);
      } else {
        if (!verbose)
          form_value.Dump(s);
      }
    }
  } 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 << " ( ";
    if (verbose)
      s.PutCString(" ( ");
    GetName(dwarf2Data, cu, abstract_die_offset, s);
    if (verbose)
      s.PutCString(" )");
  } break;

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

  case DW_AT_ranges: {
    if (!verbose)
      form_value.Dump(s);
    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:
    if (!verbose)
      form_value.Dump(s);
    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_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() ? " *" : "");
  }
}
