//===-- 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 "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDeclContext.h"
#include "DWARFDIECollection.h"
#include "DWARFFormValue.h"
#include "DWARFDebugRanges.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(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->DebugInfo()->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;  
                }
                // Fall through...
            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(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(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() ? " *" : "");
    }
}


