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

#include "SymbolFileDWARF.h"

// Other libraries and framework includes
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
#include "clang/Basic/Builtins.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LangOptions.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Specifiers.h"
#include "clang/Sema/DeclSpec.h"

#include "llvm/Support/Casting.h"

#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/ModuleList.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Core/Timer.h"
#include "lldb/Core/Value.h"

#include "lldb/Expression/ClangModulesDeclVendor.h"

#include "lldb/Host/Host.h"

#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
#include "lldb/Symbol/CompileUnit.h"
#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"

#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/CPPLanguageRuntime.h"

#include "DWARFCompileUnit.h"
#include "DWARFDebugAbbrev.h"
#include "DWARFDebugAranges.h"
#include "DWARFDebugInfo.h"
#include "DWARFDebugInfoEntry.h"
#include "DWARFDebugLine.h"
#include "DWARFDebugPubnames.h"
#include "DWARFDebugRanges.h"
#include "DWARFDeclContext.h"
#include "DWARFDIECollection.h"
#include "DWARFFormValue.h"
#include "DWARFLocationList.h"
#include "LogChannelDWARF.h"
#include "SymbolFileDWARFDebugMap.h"

#include <map>

#include <ctype.h>
#include <string.h>

//#define ENABLE_DEBUG_PRINTF // COMMENT OUT THIS LINE PRIOR TO CHECKIN

#ifdef ENABLE_DEBUG_PRINTF
#include <stdio.h>
#define DEBUG_PRINTF(fmt, ...) printf(fmt, __VA_ARGS__)
#else
#define DEBUG_PRINTF(fmt, ...)
#endif

#define DIE_IS_BEING_PARSED ((lldb_private::Type*)1)

using namespace lldb;
using namespace lldb_private;

//static inline bool
//child_requires_parent_class_union_or_struct_to_be_completed (dw_tag_t tag)
//{
//    switch (tag)
//    {
//    default:
//        break;
//    case DW_TAG_subprogram:
//    case DW_TAG_inlined_subroutine:
//    case DW_TAG_class_type:
//    case DW_TAG_structure_type:
//    case DW_TAG_union_type:
//        return true;
//    }
//    return false;
//}
//
static AccessType
DW_ACCESS_to_AccessType (uint32_t dwarf_accessibility)
{
    switch (dwarf_accessibility)
    {
        case DW_ACCESS_public:      return eAccessPublic;
        case DW_ACCESS_private:     return eAccessPrivate;
        case DW_ACCESS_protected:   return eAccessProtected;
        default:                    break;
    }
    return eAccessNone;
}

static const char*
removeHostnameFromPathname(const char* path_from_dwarf)
{
    if (!path_from_dwarf || !path_from_dwarf[0])
    {
        return path_from_dwarf;
    }

    const char *colon_pos = strchr(path_from_dwarf, ':');
    if (!colon_pos)
    {
        return path_from_dwarf;
    }
    
    // check whether we have a windows path, and so the first character
    // is a drive-letter not a hostname.
    if (
        colon_pos == path_from_dwarf + 1 &&
        isalpha(*path_from_dwarf) &&
        strlen(path_from_dwarf) > 2 &&
        '\\' == path_from_dwarf[2])
    {
        return path_from_dwarf;
    }

    return colon_pos + 1;
}

#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)

class DIEStack
{
public:
    
    void Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
    {
        m_dies.push_back (DIEInfo(cu, die));
    }

    
    void LogDIEs (Log *log, SymbolFileDWARF *dwarf)
    {
        StreamString log_strm;
        const size_t n = m_dies.size();
        log_strm.Printf("DIEStack[%" PRIu64 "]:\n", (uint64_t)n);
        for (size_t i=0; i<n; i++)
        {
            DWARFCompileUnit *cu = m_dies[i].cu;
            const DWARFDebugInfoEntry *die = m_dies[i].die;
            std::string qualified_name;
            die->GetQualifiedName(dwarf, cu, qualified_name);
            log_strm.Printf ("[%" PRIu64 "] 0x%8.8x: %s name='%s'\n",
                             (uint64_t)i,
                             die->GetOffset(), 
                             DW_TAG_value_to_name(die->Tag()), 
                             qualified_name.c_str());
        }
        log->PutCString(log_strm.GetData());
    }
    void Pop ()
    {
        m_dies.pop_back();
    }
    
    class ScopedPopper
    {
    public:
        ScopedPopper (DIEStack &die_stack) :
            m_die_stack (die_stack),
            m_valid (false)
        {
        }
        
        void
        Push (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
        {
            m_valid = true;
            m_die_stack.Push (cu, die);
        }
        
        ~ScopedPopper ()
        {
            if (m_valid)
                m_die_stack.Pop();
        }
        
        
        
    protected:
        DIEStack &m_die_stack;
        bool m_valid;
    };

protected:
    struct DIEInfo {
        DIEInfo (DWARFCompileUnit *c, const DWARFDebugInfoEntry *d) :
            cu(c),
            die(d)
        {
        }
        DWARFCompileUnit *cu;
        const DWARFDebugInfoEntry *die;
    };
    typedef std::vector<DIEInfo> Stack;
    Stack m_dies;
};
#endif

void
SymbolFileDWARF::Initialize()
{
    LogChannelDWARF::Initialize();
    PluginManager::RegisterPlugin (GetPluginNameStatic(),
                                   GetPluginDescriptionStatic(),
                                   CreateInstance);
}

void
SymbolFileDWARF::Terminate()
{
    PluginManager::UnregisterPlugin (CreateInstance);
    LogChannelDWARF::Initialize();
}


lldb_private::ConstString
SymbolFileDWARF::GetPluginNameStatic()
{
    static ConstString g_name("dwarf");
    return g_name;
}

const char *
SymbolFileDWARF::GetPluginDescriptionStatic()
{
    return "DWARF and DWARF3 debug symbol file reader.";
}


SymbolFile*
SymbolFileDWARF::CreateInstance (ObjectFile* obj_file)
{
    return new SymbolFileDWARF(obj_file);
}

TypeList *          
SymbolFileDWARF::GetTypeList ()
{
    if (GetDebugMapSymfile ())
        return m_debug_map_symfile->GetTypeList();
    return m_obj_file->GetModule()->GetTypeList();

}
void
SymbolFileDWARF::GetTypes (DWARFCompileUnit* cu,
                           const DWARFDebugInfoEntry *die,
                           dw_offset_t min_die_offset,
                           dw_offset_t max_die_offset,
                           uint32_t type_mask,
                           TypeSet &type_set)
{
    if (cu)
    {
        if (die)
        {
            const dw_offset_t die_offset = die->GetOffset();
            
            if (die_offset >= max_die_offset)
                return;
            
            if (die_offset >= min_die_offset)
            {
                const dw_tag_t tag = die->Tag();
                
                bool add_type = false;

                switch (tag)
                {
                    case DW_TAG_array_type:         add_type = (type_mask & eTypeClassArray         ) != 0; break;
                    case DW_TAG_unspecified_type:
                    case DW_TAG_base_type:          add_type = (type_mask & eTypeClassBuiltin       ) != 0; break;
                    case DW_TAG_class_type:         add_type = (type_mask & eTypeClassClass         ) != 0; break;
                    case DW_TAG_structure_type:     add_type = (type_mask & eTypeClassStruct        ) != 0; break;
                    case DW_TAG_union_type:         add_type = (type_mask & eTypeClassUnion         ) != 0; break;
                    case DW_TAG_enumeration_type:   add_type = (type_mask & eTypeClassEnumeration   ) != 0; break;
                    case DW_TAG_subroutine_type:
                    case DW_TAG_subprogram:
                    case DW_TAG_inlined_subroutine: add_type = (type_mask & eTypeClassFunction      ) != 0; break;
                    case DW_TAG_pointer_type:       add_type = (type_mask & eTypeClassPointer       ) != 0; break;
                    case DW_TAG_rvalue_reference_type:
                    case DW_TAG_reference_type:     add_type = (type_mask & eTypeClassReference     ) != 0; break;
                    case DW_TAG_typedef:            add_type = (type_mask & eTypeClassTypedef       ) != 0; break;
                    case DW_TAG_ptr_to_member_type: add_type = (type_mask & eTypeClassMemberPointer ) != 0; break;
                }

                if (add_type)
                {
                    const bool assert_not_being_parsed = true;
                    Type *type = ResolveTypeUID (cu, die, assert_not_being_parsed);
                    if (type)
                    {
                        if (type_set.find(type) == type_set.end())
                            type_set.insert(type);
                    }
                }
            }
            
            for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild();
                 child_die != NULL;
                 child_die = child_die->GetSibling())
            {
                GetTypes (cu, child_die, min_die_offset, max_die_offset, type_mask, type_set);
            }
        }
    }
}

size_t
SymbolFileDWARF::GetTypes (SymbolContextScope *sc_scope,
                           uint32_t type_mask,
                           TypeList &type_list)

{
    TypeSet type_set;
    
    CompileUnit *comp_unit = NULL;
    DWARFCompileUnit* dwarf_cu = NULL;
    if (sc_scope)
        comp_unit = sc_scope->CalculateSymbolContextCompileUnit();

    if (comp_unit)
    {
        dwarf_cu = GetDWARFCompileUnit(comp_unit);
        if (dwarf_cu == 0)
            return 0;
        GetTypes (dwarf_cu,
                  dwarf_cu->DIE(),
                  dwarf_cu->GetOffset(),
                  dwarf_cu->GetNextCompileUnitOffset(),
                  type_mask,
                  type_set);
    }
    else
    {
        DWARFDebugInfo* info = DebugInfo();
        if (info)
        {
            const size_t num_cus = info->GetNumCompileUnits();
            for (size_t cu_idx=0; cu_idx<num_cus; ++cu_idx)
            {
                dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
                if (dwarf_cu)
                {
                    GetTypes (dwarf_cu,
                              dwarf_cu->DIE(),
                              0,
                              UINT32_MAX,
                              type_mask,
                              type_set);
                }
            }
        }
    }
//    if (m_using_apple_tables)
//    {
//        DWARFMappedHash::MemoryTable *apple_types = m_apple_types_ap.get();
//        if (apple_types)
//        {
//            apple_types->ForEach([this, &type_set, apple_types, type_mask](const DWARFMappedHash::DIEInfoArray &die_info_array) -> bool {
//
//                for (auto die_info: die_info_array)
//                {
//                    bool add_type = TagMatchesTypeMask (type_mask, 0);
//                    if (!add_type)
//                    {
//                        dw_tag_t tag = die_info.tag;
//                        if (tag == 0)
//                        {
//                            const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtr(die_info.offset, NULL);
//                            tag = die->Tag();
//                        }
//                        add_type = TagMatchesTypeMask (type_mask, tag);
//                    }
//                    if (add_type)
//                    {
//                        Type *type = ResolveTypeUID(die_info.offset);
//                        
//                        if (type_set.find(type) == type_set.end())
//                            type_set.insert(type);
//                    }
//                }
//                return true; // Keep iterating
//            });
//        }
//    }
//    else
//    {
//        if (!m_indexed)
//            Index ();
//        
//        m_type_index.ForEach([this, &type_set, type_mask](const char *name, uint32_t die_offset) -> bool {
//            
//            bool add_type = TagMatchesTypeMask (type_mask, 0);
//
//            if (!add_type)
//            {
//                const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtr(die_offset, NULL);
//                if (die)
//                {
//                    const dw_tag_t tag = die->Tag();
//                    add_type = TagMatchesTypeMask (type_mask, tag);
//                }
//            }
//            
//            if (add_type)
//            {
//                Type *type = ResolveTypeUID(die_offset);
//                
//                if (type_set.find(type) == type_set.end())
//                    type_set.insert(type);
//            }
//            return true; // Keep iterating
//        });
//    }
    
    std::set<ClangASTType> clang_type_set;
    size_t num_types_added = 0;
    for (Type *type : type_set)
    {
        ClangASTType clang_type = type->GetClangForwardType();
        if (clang_type_set.find(clang_type) == clang_type_set.end())
        {
            clang_type_set.insert(clang_type);
            type_list.Insert (type->shared_from_this());
            ++num_types_added;
        }
    }
    return num_types_added;
}


//----------------------------------------------------------------------
// Gets the first parent that is a lexical block, function or inlined
// subroutine, or compile unit.
//----------------------------------------------------------------------
static const DWARFDebugInfoEntry *
GetParentSymbolContextDIE(const DWARFDebugInfoEntry *child_die)
{
    const DWARFDebugInfoEntry *die;
    for (die = child_die->GetParent(); die != NULL; die = die->GetParent())
    {
        dw_tag_t tag = die->Tag();

        switch (tag)
        {
        case DW_TAG_compile_unit:
        case DW_TAG_subprogram:
        case DW_TAG_inlined_subroutine:
        case DW_TAG_lexical_block:
            return die;
        }
    }
    return NULL;
}


SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) :
    SymbolFile (objfile),
    UserID (0),  // Used by SymbolFileDWARFDebugMap to when this class parses .o files to contain the .o file index/ID
    m_debug_map_module_wp (),
    m_debug_map_symfile (NULL),
    m_clang_tu_decl (NULL),
    m_flags(),
    m_data_debug_abbrev (),
    m_data_debug_aranges (),
    m_data_debug_frame (),
    m_data_debug_info (),
    m_data_debug_line (),
    m_data_debug_loc (),
    m_data_debug_ranges (),
    m_data_debug_str (),
    m_data_apple_names (),
    m_data_apple_types (),
    m_data_apple_namespaces (),
    m_abbr(),
    m_info(),
    m_line(),
    m_apple_names_ap (),
    m_apple_types_ap (),
    m_apple_namespaces_ap (),
    m_apple_objc_ap (),
    m_function_basename_index(),
    m_function_fullname_index(),
    m_function_method_index(),
    m_function_selector_index(),
    m_objc_class_selectors_index(),
    m_global_index(),
    m_type_index(),
    m_namespace_index(),
    m_indexed (false),
    m_is_external_ast_source (false),
    m_using_apple_tables (false),
    m_fetched_external_modules (false),
    m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate),
    m_ranges(),
    m_unique_ast_type_map ()
{
}

SymbolFileDWARF::~SymbolFileDWARF()
{
    if (m_is_external_ast_source)
    {
        ModuleSP module_sp (m_obj_file->GetModule());
        if (module_sp)
            module_sp->GetClangASTContext().RemoveExternalSource ();
    }
}

static const ConstString &
GetDWARFMachOSegmentName ()
{
    static ConstString g_dwarf_section_name ("__DWARF");
    return g_dwarf_section_name;
}

UniqueDWARFASTTypeMap &
SymbolFileDWARF::GetUniqueDWARFASTTypeMap ()
{
    if (GetDebugMapSymfile ())
        return m_debug_map_symfile->GetUniqueDWARFASTTypeMap ();
    return m_unique_ast_type_map;
}

ClangASTContext &       
SymbolFileDWARF::GetClangASTContext ()
{
    if (GetDebugMapSymfile ())
        return m_debug_map_symfile->GetClangASTContext ();

    ClangASTContext &ast = m_obj_file->GetModule()->GetClangASTContext();
    if (!m_is_external_ast_source)
    {
        m_is_external_ast_source = true;
        llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> ast_source_ap (
            new ClangExternalASTSourceCallbacks (SymbolFileDWARF::CompleteTagDecl,
                                                 SymbolFileDWARF::CompleteObjCInterfaceDecl,
                                                 SymbolFileDWARF::FindExternalVisibleDeclsByName,
                                                 SymbolFileDWARF::LayoutRecordType,
                                                 this));
        ast.SetExternalSource (ast_source_ap);
    }
    return ast;
}

void
SymbolFileDWARF::InitializeObject()
{
    // Install our external AST source callbacks so we can complete Clang types.
    ModuleSP module_sp (m_obj_file->GetModule());
    if (module_sp)
    {
        const SectionList *section_list = module_sp->GetSectionList();

        const Section* section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();

        // Memory map the DWARF mach-o segment so we have everything mmap'ed
        // to keep our heap memory usage down.
        if (section)
            m_obj_file->MemoryMapSectionData(section, m_dwarf_data);
    }
    get_apple_names_data();
    if (m_data_apple_names.GetByteSize() > 0)
    {
        m_apple_names_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_names, get_debug_str_data(), ".apple_names"));
        if (m_apple_names_ap->IsValid())
            m_using_apple_tables = true;
        else
            m_apple_names_ap.reset();
    }
    get_apple_types_data();
    if (m_data_apple_types.GetByteSize() > 0)
    {
        m_apple_types_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_types, get_debug_str_data(), ".apple_types"));
        if (m_apple_types_ap->IsValid())
            m_using_apple_tables = true;
        else
            m_apple_types_ap.reset();
    }

    get_apple_namespaces_data();
    if (m_data_apple_namespaces.GetByteSize() > 0)
    {
        m_apple_namespaces_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_namespaces, get_debug_str_data(), ".apple_namespaces"));
        if (m_apple_namespaces_ap->IsValid())
            m_using_apple_tables = true;
        else
            m_apple_namespaces_ap.reset();
    }

    get_apple_objc_data();
    if (m_data_apple_objc.GetByteSize() > 0)
    {
        m_apple_objc_ap.reset (new DWARFMappedHash::MemoryTable (m_data_apple_objc, get_debug_str_data(), ".apple_objc"));
        if (m_apple_objc_ap->IsValid())
            m_using_apple_tables = true;
        else
            m_apple_objc_ap.reset();
    }
}

bool
SymbolFileDWARF::SupportedVersion(uint16_t version)
{
    return version == 2 || version == 3 || version == 4;
}

uint32_t
SymbolFileDWARF::CalculateAbilities ()
{
    uint32_t abilities = 0;
    if (m_obj_file != NULL)
    {
        const Section* section = NULL;
        const SectionList *section_list = m_obj_file->GetSectionList();
        if (section_list == NULL)
            return 0;

        uint64_t debug_abbrev_file_size = 0;
        uint64_t debug_info_file_size = 0;
        uint64_t debug_line_file_size = 0;

        section = section_list->FindSectionByName(GetDWARFMachOSegmentName ()).get();
        
        if (section)
            section_list = &section->GetChildren ();
        
        section = section_list->FindSectionByType (eSectionTypeDWARFDebugInfo, true).get();
        if (section != NULL)
        {
            debug_info_file_size = section->GetFileSize();

            section = section_list->FindSectionByType (eSectionTypeDWARFDebugAbbrev, true).get();
            if (section)
                debug_abbrev_file_size = section->GetFileSize();
            else
                m_flags.Set (flagsGotDebugAbbrevData);

            section = section_list->FindSectionByType (eSectionTypeDWARFDebugAranges, true).get();
            if (!section)
                m_flags.Set (flagsGotDebugArangesData);

            section = section_list->FindSectionByType (eSectionTypeDWARFDebugFrame, true).get();
            if (!section)
                m_flags.Set (flagsGotDebugFrameData);

            section = section_list->FindSectionByType (eSectionTypeDWARFDebugLine, true).get();
            if (section)
                debug_line_file_size = section->GetFileSize();
            else
                m_flags.Set (flagsGotDebugLineData);

            section = section_list->FindSectionByType (eSectionTypeDWARFDebugLoc, true).get();
            if (!section)
                m_flags.Set (flagsGotDebugLocData);

            section = section_list->FindSectionByType (eSectionTypeDWARFDebugMacInfo, true).get();
            if (!section)
                m_flags.Set (flagsGotDebugMacInfoData);

            section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubNames, true).get();
            if (!section)
                m_flags.Set (flagsGotDebugPubNamesData);

            section = section_list->FindSectionByType (eSectionTypeDWARFDebugPubTypes, true).get();
            if (!section)
                m_flags.Set (flagsGotDebugPubTypesData);

            section = section_list->FindSectionByType (eSectionTypeDWARFDebugRanges, true).get();
            if (!section)
                m_flags.Set (flagsGotDebugRangesData);

            section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
            if (!section)
                m_flags.Set (flagsGotDebugStrData);
        }
        else
        {
            const char *symfile_dir_cstr = m_obj_file->GetFileSpec().GetDirectory().GetCString();
            if (symfile_dir_cstr)
            {
                if (strcasestr(symfile_dir_cstr, ".dsym"))
                {
                    if (m_obj_file->GetType() == ObjectFile::eTypeDebugInfo)
                    {
                        // We have a dSYM file that didn't have a any debug info.
                        // If the string table has a size of 1, then it was made from
                        // an executable with no debug info, or from an executable that
                        // was stripped.
                        section = section_list->FindSectionByType (eSectionTypeDWARFDebugStr, true).get();
                        if (section && section->GetFileSize() == 1)
                        {
                            m_obj_file->GetModule()->ReportWarning ("empty dSYM file detected, dSYM was created with an executable with no debug info.");
                        }
                    }
                }
            }
        }

        if (debug_abbrev_file_size > 0 && debug_info_file_size > 0)
            abilities |= CompileUnits | Functions | Blocks | GlobalVariables | LocalVariables | VariableTypes;

        if (debug_line_file_size > 0)
            abilities |= LineTables;
    }
    return abilities;
}

const DWARFDataExtractor&
SymbolFileDWARF::GetCachedSectionData (uint32_t got_flag, SectionType sect_type, DWARFDataExtractor &data)
{
    if (m_flags.IsClear (got_flag))
    {
        ModuleSP module_sp (m_obj_file->GetModule());
        m_flags.Set (got_flag);
        const SectionList *section_list = module_sp->GetSectionList();
        if (section_list)
        {
            SectionSP section_sp (section_list->FindSectionByType(sect_type, true));
            if (section_sp)
            {
                // See if we memory mapped the DWARF segment?
                if (m_dwarf_data.GetByteSize())
                {
                    data.SetData(m_dwarf_data, section_sp->GetOffset (), section_sp->GetFileSize());
                }
                else
                {
                    if (m_obj_file->ReadSectionData (section_sp.get(), data) == 0)
                        data.Clear();
                }
            }
        }
    }
    return data;
}

const DWARFDataExtractor&
SymbolFileDWARF::get_debug_abbrev_data()
{
    return GetCachedSectionData (flagsGotDebugAbbrevData, eSectionTypeDWARFDebugAbbrev, m_data_debug_abbrev);
}

const DWARFDataExtractor&
SymbolFileDWARF::get_debug_aranges_data()
{
    return GetCachedSectionData (flagsGotDebugArangesData, eSectionTypeDWARFDebugAranges, m_data_debug_aranges);
}

const DWARFDataExtractor&
SymbolFileDWARF::get_debug_frame_data()
{
    return GetCachedSectionData (flagsGotDebugFrameData, eSectionTypeDWARFDebugFrame, m_data_debug_frame);
}

const DWARFDataExtractor&
SymbolFileDWARF::get_debug_info_data()
{
    return GetCachedSectionData (flagsGotDebugInfoData, eSectionTypeDWARFDebugInfo, m_data_debug_info);
}

const DWARFDataExtractor&
SymbolFileDWARF::get_debug_line_data()
{
    return GetCachedSectionData (flagsGotDebugLineData, eSectionTypeDWARFDebugLine, m_data_debug_line);
}

const DWARFDataExtractor&
SymbolFileDWARF::get_debug_loc_data()
{
    return GetCachedSectionData (flagsGotDebugLocData, eSectionTypeDWARFDebugLoc, m_data_debug_loc);
}

const DWARFDataExtractor&
SymbolFileDWARF::get_debug_ranges_data()
{
    return GetCachedSectionData (flagsGotDebugRangesData, eSectionTypeDWARFDebugRanges, m_data_debug_ranges);
}

const DWARFDataExtractor&
SymbolFileDWARF::get_debug_str_data()
{
    return GetCachedSectionData (flagsGotDebugStrData, eSectionTypeDWARFDebugStr, m_data_debug_str);
}

const DWARFDataExtractor&
SymbolFileDWARF::get_apple_names_data()
{
    return GetCachedSectionData (flagsGotAppleNamesData, eSectionTypeDWARFAppleNames, m_data_apple_names);
}

const DWARFDataExtractor&
SymbolFileDWARF::get_apple_types_data()
{
    return GetCachedSectionData (flagsGotAppleTypesData, eSectionTypeDWARFAppleTypes, m_data_apple_types);
}

const DWARFDataExtractor&
SymbolFileDWARF::get_apple_namespaces_data()
{
    return GetCachedSectionData (flagsGotAppleNamespacesData, eSectionTypeDWARFAppleNamespaces, m_data_apple_namespaces);
}

const DWARFDataExtractor&
SymbolFileDWARF::get_apple_objc_data()
{
    return GetCachedSectionData (flagsGotAppleObjCData, eSectionTypeDWARFAppleObjC, m_data_apple_objc);
}


DWARFDebugAbbrev*
SymbolFileDWARF::DebugAbbrev()
{
    if (m_abbr.get() == NULL)
    {
        const DWARFDataExtractor &debug_abbrev_data = get_debug_abbrev_data();
        if (debug_abbrev_data.GetByteSize() > 0)
        {
            m_abbr.reset(new DWARFDebugAbbrev());
            if (m_abbr.get())
                m_abbr->Parse(debug_abbrev_data);
        }
    }
    return m_abbr.get();
}

const DWARFDebugAbbrev*
SymbolFileDWARF::DebugAbbrev() const
{
    return m_abbr.get();
}


DWARFDebugInfo*
SymbolFileDWARF::DebugInfo()
{
    if (m_info.get() == NULL)
    {
        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
                           __PRETTY_FUNCTION__, static_cast<void*>(this));
        if (get_debug_info_data().GetByteSize() > 0)
        {
            m_info.reset(new DWARFDebugInfo());
            if (m_info.get())
            {
                m_info->SetDwarfData(this);
            }
        }
    }
    return m_info.get();
}

const DWARFDebugInfo*
SymbolFileDWARF::DebugInfo() const
{
    return m_info.get();
}

DWARFCompileUnit*
SymbolFileDWARF::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
{
    DWARFDebugInfo* info = DebugInfo();
    if (info)
    {
        if (GetDebugMapSymfile ())
        {
            // The debug map symbol file made the compile units for this DWARF
            // file which is .o file with DWARF in it, and we should have
            // only 1 compile unit which is at offset zero in the DWARF.
            // TODO: modify to support LTO .o files where each .o file might
            // have multiple DW_TAG_compile_unit tags.
            
            DWARFCompileUnit *dwarf_cu = info->GetCompileUnit(0).get();
            if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
                dwarf_cu->SetUserData(comp_unit);
            return dwarf_cu;
        }
        else
        {
            // Just a normal DWARF file whose user ID for the compile unit is
            // the DWARF offset itself

            DWARFCompileUnit *dwarf_cu = info->GetCompileUnit((dw_offset_t)comp_unit->GetID()).get();
            if (dwarf_cu && dwarf_cu->GetUserData() == NULL)
                dwarf_cu->SetUserData(comp_unit);
            return dwarf_cu;

        }
    }
    return NULL;
}


DWARFDebugRanges*
SymbolFileDWARF::DebugRanges()
{
    if (m_ranges.get() == NULL)
    {
        Timer scoped_timer(__PRETTY_FUNCTION__, "%s this = %p",
                           __PRETTY_FUNCTION__, static_cast<void*>(this));
        if (get_debug_ranges_data().GetByteSize() > 0)
        {
            m_ranges.reset(new DWARFDebugRanges());
            if (m_ranges.get())
                m_ranges->Extract(this);
        }
    }
    return m_ranges.get();
}

const DWARFDebugRanges*
SymbolFileDWARF::DebugRanges() const
{
    return m_ranges.get();
}

lldb::CompUnitSP
SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
{
    CompUnitSP cu_sp;
    if (dwarf_cu)
    {
        CompileUnit *comp_unit = (CompileUnit*)dwarf_cu->GetUserData();
        if (comp_unit)
        {
            // We already parsed this compile unit, had out a shared pointer to it
            cu_sp = comp_unit->shared_from_this();
        }
        else
        {
            if (GetDebugMapSymfile ())
            {
                // Let the debug map create the compile unit
                cu_sp = m_debug_map_symfile->GetCompileUnit(this);
                dwarf_cu->SetUserData(cu_sp.get());
            }
            else
            {
                ModuleSP module_sp (m_obj_file->GetModule());
                if (module_sp)
                {
                    const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly ();
                    if (cu_die)
                    {
                        FileSpec cu_file_spec{cu_die->GetName(this, dwarf_cu), false};
                        if (cu_file_spec)
                        {
                            // If we have a full path to the compile unit, we don't need to resolve
                            // the file.  This can be expensive e.g. when the source files are NFS mounted.
                            if (cu_file_spec.IsRelative())
                            {
                                // DWARF2/3 suggests the form hostname:pathname for compilation directory.
                                // Remove the host part if present.
                                const char *cu_comp_dir{cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, nullptr)};
                                cu_file_spec.PrependPathComponent(removeHostnameFromPathname(cu_comp_dir));
                            }

                            std::string remapped_file;
                            if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file))
                                cu_file_spec.SetFile(remapped_file, false);
                        }

                        LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0));

                        cu_sp.reset(new CompileUnit (module_sp,
                                                     dwarf_cu,
                                                     cu_file_spec, 
                                                     MakeUserID(dwarf_cu->GetOffset()),
                                                     cu_language));
                        if (cu_sp)
                        {
                            // If we just created a compile unit with an invalid file spec, try and get the
                            // first entry in the supports files from the line table as that should be the
                            // compile unit.
                            if (!cu_file_spec)
                            {
                                cu_file_spec = cu_sp->GetSupportFiles().GetFileSpecAtIndex(1);
                                if (cu_file_spec)
                                {
                                    (FileSpec &)(*cu_sp) = cu_file_spec;
                                    // Also fix the invalid file spec which was copied from the compile unit.
                                    cu_sp->GetSupportFiles().Replace(0, cu_file_spec);
                                }
                            }

                            dwarf_cu->SetUserData(cu_sp.get());
                            
                            // Figure out the compile unit index if we weren't given one
                            if (cu_idx == UINT32_MAX)
                                DebugInfo()->GetCompileUnit(dwarf_cu->GetOffset(), &cu_idx);
                            
                            m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(cu_idx, cu_sp);
                        }
                    }
                }
            }
        }
    }
    return cu_sp;
}

uint32_t
SymbolFileDWARF::GetNumCompileUnits()
{
    DWARFDebugInfo* info = DebugInfo();
    if (info)
        return info->GetNumCompileUnits();
    return 0;
}

CompUnitSP
SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx)
{
    CompUnitSP cu_sp;
    DWARFDebugInfo* info = DebugInfo();
    if (info)
    {
        DWARFCompileUnit* dwarf_cu = info->GetCompileUnitAtIndex(cu_idx);
        if (dwarf_cu)
            cu_sp = ParseCompileUnit(dwarf_cu, cu_idx);
    }
    return cu_sp;
}

Function *
SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die)
{
    DWARFDebugRanges::RangeList func_ranges;
    const char *name = NULL;
    const char *mangled = NULL;
    int decl_file = 0;
    int decl_line = 0;
    int decl_column = 0;
    int call_file = 0;
    int call_line = 0;
    int call_column = 0;
    DWARFExpression frame_base;

    assert (die->Tag() == DW_TAG_subprogram);
    
    if (die->Tag() != DW_TAG_subprogram)
        return NULL;

    if (die->GetDIENamesAndRanges (this, 
                                   dwarf_cu, 
                                   name, 
                                   mangled, 
                                   func_ranges, 
                                   decl_file, 
                                   decl_line, 
                                   decl_column, 
                                   call_file, 
                                   call_line, 
                                   call_column, 
                                   &frame_base))
    {
        // Union of all ranges in the function DIE (if the function is discontiguous)
        AddressRange func_range;
        lldb::addr_t lowest_func_addr = func_ranges.GetMinRangeBase (0);
        lldb::addr_t highest_func_addr = func_ranges.GetMaxRangeEnd (0);
        if (lowest_func_addr != LLDB_INVALID_ADDRESS && lowest_func_addr <= highest_func_addr)
        {
            ModuleSP module_sp (m_obj_file->GetModule());
            func_range.GetBaseAddress().ResolveAddressUsingFileSections (lowest_func_addr, module_sp->GetSectionList());
            if (func_range.GetBaseAddress().IsValid())
                func_range.SetByteSize(highest_func_addr - lowest_func_addr);
        }

        if (func_range.GetBaseAddress().IsValid())
        {
            Mangled func_name;
            if (mangled)
                func_name.SetValue(ConstString(mangled), true);
            else if (die->GetParent()->Tag() == DW_TAG_compile_unit &&
                     LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType()) &&
                     name && strcmp(name, "main") != 0)
            {
                // If the mangled name is not present in the DWARF, generate the demangled name
                // using the decl context. We skip if the function is "main" as its name is
                // never mangled.
                bool is_static = false;
                bool is_variadic = false;
                unsigned type_quals = 0;
                std::vector<ClangASTType> param_types;
                std::vector<clang::ParmVarDecl*> param_decls;
                const DWARFDebugInfoEntry *decl_ctx_die = NULL;
                DWARFDeclContext decl_ctx;
                StreamString sstr;

                die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx);
                sstr << decl_ctx.GetQualifiedName();

                clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE(dwarf_cu,
                                                                                           die,
                                                                                           &decl_ctx_die);
                ParseChildParameters(sc,
                                     containing_decl_ctx,
                                     dwarf_cu,
                                     die,
                                     true,
                                     is_static,
                                     is_variadic,
                                     param_types,
                                     param_decls,
                                     type_quals);
                sstr << "(";
                for (size_t i = 0; i < param_types.size(); i++)
                {
                    if (i > 0)
                        sstr << ", ";
                    sstr << param_types[i].GetTypeName();
                }
                if (is_variadic)
                    sstr << ", ...";
                sstr << ")";
                if (type_quals & clang::Qualifiers::Const)
                    sstr << " const";

                func_name.SetValue(ConstString(sstr.GetData()), false);
            }
            else
                func_name.SetValue(ConstString(name), false);

            FunctionSP func_sp;
            std::unique_ptr<Declaration> decl_ap;
            if (decl_file != 0 || decl_line != 0 || decl_column != 0)
                decl_ap.reset(new Declaration (sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), 
                                               decl_line, 
                                               decl_column));

            // Supply the type _only_ if it has already been parsed
            Type *func_type = m_die_to_type.lookup (die);

            assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);

            if (FixupAddress (func_range.GetBaseAddress()))
            {
                const user_id_t func_user_id = MakeUserID(die->GetOffset());
                func_sp.reset(new Function (sc.comp_unit,
                                            MakeUserID(func_user_id),       // UserID is the DIE offset
                                            MakeUserID(func_user_id),
                                            func_name,
                                            func_type,
                                            func_range));           // first address range

                if (func_sp.get() != NULL)
                {
                    if (frame_base.IsValid())
                        func_sp->GetFrameBaseExpression() = frame_base;
                    sc.comp_unit->AddFunction(func_sp);
                    return func_sp.get();
                }
            }
        }
    }
    return NULL;
}

bool
SymbolFileDWARF::FixupAddress (Address &addr)
{
    SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
    if (debug_map_symfile)
    {
        return debug_map_symfile->LinkOSOAddress(addr);
    }
    // This is a normal DWARF file, no address fixups need to happen
    return true;
}
lldb::LanguageType
SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
{
    assert (sc.comp_unit);
    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
    if (dwarf_cu)
    {
        const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly();
        if (die)
            return DWARFCompileUnit::LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0));
    }
    return eLanguageTypeUnknown;
}

size_t
SymbolFileDWARF::ParseCompileUnitFunctions(const SymbolContext &sc)
{
    assert (sc.comp_unit);
    size_t functions_added = 0;
    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
    if (dwarf_cu)
    {
        DWARFDIECollection function_dies;
        const size_t num_functions = dwarf_cu->AppendDIEsWithTag (DW_TAG_subprogram, function_dies);
        size_t func_idx;
        for (func_idx = 0; func_idx < num_functions; ++func_idx)
        {
            const DWARFDebugInfoEntry *die = function_dies.GetDIEPtrAtIndex(func_idx);
            if (sc.comp_unit->FindFunctionByUID (MakeUserID(die->GetOffset())).get() == NULL)
            {
                if (ParseCompileUnitFunction(sc, dwarf_cu, die))
                    ++functions_added;
            }
        }
        //FixupTypes();
    }
    return functions_added;
}

bool
SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files)
{
    assert (sc.comp_unit);
    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
    if (dwarf_cu)
    {
        const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly();

        if (cu_die)
        {
            const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, NULL);

            // DWARF2/3 suggests the form hostname:pathname for compilation directory.
            // Remove the host part if present.
            cu_comp_dir = removeHostnameFromPathname(cu_comp_dir);

            dw_offset_t stmt_list = cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);

            // All file indexes in DWARF are one based and a file of index zero is
            // supposed to be the compile unit itself.
            support_files.Append (*sc.comp_unit);

            return DWARFDebugLine::ParseSupportFiles(sc.comp_unit->GetModule(), get_debug_line_data(), cu_comp_dir, stmt_list, support_files);
        }
    }
    return false;
}

bool
SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules)
{
    assert (sc.comp_unit);
    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
    if (dwarf_cu)
    {
        if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage()))
        {
            UpdateExternalModuleListIfNeeded();
            for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules)
            {
                imported_modules.push_back(external_type_module.second.m_name);
            }
        }
    }
    return false;
}

struct ParseDWARFLineTableCallbackInfo
{
    LineTable* line_table;
    std::unique_ptr<LineSequence> sequence_ap;
};

//----------------------------------------------------------------------
// ParseStatementTableCallback
//----------------------------------------------------------------------
static void
ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
{
    if (state.row == DWARFDebugLine::State::StartParsingLineTable)
    {
        // Just started parsing the line table
    }
    else if (state.row == DWARFDebugLine::State::DoneParsingLineTable)
    {
        // Done parsing line table, nothing to do for the cleanup
    }
    else
    {
        ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
        LineTable* line_table = info->line_table;

        // If this is our first time here, we need to create a
        // sequence container.
        if (!info->sequence_ap.get())
        {
            info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
            assert(info->sequence_ap.get());
        }
        line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
                                               state.address,
                                               state.line,
                                               state.column,
                                               state.file,
                                               state.is_stmt,
                                               state.basic_block,
                                               state.prologue_end,
                                               state.epilogue_begin,
                                               state.end_sequence);
        if (state.end_sequence)
        {
            // First, put the current sequence into the line table.
            line_table->InsertSequence(info->sequence_ap.get());
            // Then, empty it to prepare for the next sequence.
            info->sequence_ap->Clear();
        }
    }
}

bool
SymbolFileDWARF::ParseCompileUnitLineTable (const SymbolContext &sc)
{
    assert (sc.comp_unit);
    if (sc.comp_unit->GetLineTable() != NULL)
        return true;

    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
    if (dwarf_cu)
    {
        const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->GetCompileUnitDIEOnly();
        if (dwarf_cu_die)
        {
            const dw_offset_t cu_line_offset = dwarf_cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_stmt_list, DW_INVALID_OFFSET);
            if (cu_line_offset != DW_INVALID_OFFSET)
            {
                std::unique_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
                if (line_table_ap.get())
                {
                    ParseDWARFLineTableCallbackInfo info;
                    info.line_table = line_table_ap.get();
                    lldb::offset_t offset = cu_line_offset;
                    DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
                    if (m_debug_map_symfile)
                    {
                        // We have an object file that has a line table with addresses
                        // that are not linked. We need to link the line table and convert
                        // the addresses that are relative to the .o file into addresses
                        // for the main executable.
                        sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
                    }
                    else
                    {
                        sc.comp_unit->SetLineTable(line_table_ap.release());
                        return true;
                    }
                }
            }
        }
    }
    return false;
}

size_t
SymbolFileDWARF::ParseFunctionBlocks
(
    const SymbolContext& sc,
    Block *parent_block,
    DWARFCompileUnit* dwarf_cu,
    const DWARFDebugInfoEntry *die,
    addr_t subprogram_low_pc,
    uint32_t depth
)
{
    size_t blocks_added = 0;
    while (die != NULL)
    {
        dw_tag_t tag = die->Tag();

        switch (tag)
        {
        case DW_TAG_inlined_subroutine:
        case DW_TAG_subprogram:
        case DW_TAG_lexical_block:
            {
                Block *block = NULL;
                if (tag == DW_TAG_subprogram)
                {
                    // Skip any DW_TAG_subprogram DIEs that are inside
                    // of a normal or inlined functions. These will be 
                    // parsed on their own as separate entities.

                    if (depth > 0)
                        break;

                    block = parent_block;
                }
                else
                {
                    BlockSP block_sp(new Block (MakeUserID(die->GetOffset())));
                    parent_block->AddChild(block_sp);
                    block = block_sp.get();
                }
                DWARFDebugRanges::RangeList ranges;
                const char *name = NULL;
                const char *mangled_name = NULL;

                int decl_file = 0;
                int decl_line = 0;
                int decl_column = 0;
                int call_file = 0;
                int call_line = 0;
                int call_column = 0;
                if (die->GetDIENamesAndRanges (this, 
                                               dwarf_cu, 
                                               name, 
                                               mangled_name, 
                                               ranges, 
                                               decl_file, decl_line, decl_column,
                                               call_file, call_line, call_column))
                {
                    if (tag == DW_TAG_subprogram)
                    {
                        assert (subprogram_low_pc == LLDB_INVALID_ADDRESS);
                        subprogram_low_pc = ranges.GetMinRangeBase(0);
                    }
                    else if (tag == DW_TAG_inlined_subroutine)
                    {
                        // We get called here for inlined subroutines in two ways.  
                        // The first time is when we are making the Function object 
                        // for this inlined concrete instance.  Since we're creating a top level block at
                        // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS.  So we need to 
                        // adjust the containing address.
                        // The second time is when we are parsing the blocks inside the function that contains
                        // the inlined concrete instance.  Since these will be blocks inside the containing "real"
                        // function the offset will be for that function.  
                        if (subprogram_low_pc == LLDB_INVALID_ADDRESS)
                        {
                            subprogram_low_pc = ranges.GetMinRangeBase(0);
                        }
                    }

                    const size_t num_ranges = ranges.GetSize();
                    for (size_t i = 0; i<num_ranges; ++i)
                    {
                        const DWARFDebugRanges::Range &range = ranges.GetEntryRef (i);
                        const addr_t range_base = range.GetRangeBase();
                        if (range_base >= subprogram_low_pc)
                            block->AddRange(Block::Range (range_base - subprogram_low_pc, range.GetByteSize()));
                        else
                        {
                            GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": adding range [0x%" PRIx64 "-0x%" PRIx64 ") which has a base that is less than the function's low PC 0x%" PRIx64 ". Please file a bug and attach the file at the start of this error message",
                                                                       block->GetID(),
                                                                       range_base,
                                                                       range.GetRangeEnd(),
                                                                       subprogram_low_pc);
                        }
                    }
                    block->FinalizeRanges ();

                    if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL))
                    {
                        std::unique_ptr<Declaration> decl_ap;
                        if (decl_file != 0 || decl_line != 0 || decl_column != 0)
                            decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), 
                                                          decl_line, decl_column));

                        std::unique_ptr<Declaration> call_ap;
                        if (call_file != 0 || call_line != 0 || call_column != 0)
                            call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), 
                                                          call_line, call_column));

                        block->SetInlinedFunctionInfo (name, mangled_name, decl_ap.get(), call_ap.get());
                    }

                    ++blocks_added;

                    if (die->HasChildren())
                    {
                        blocks_added += ParseFunctionBlocks (sc, 
                                                             block, 
                                                             dwarf_cu, 
                                                             die->GetFirstChild(), 
                                                             subprogram_low_pc, 
                                                             depth + 1);
                    }
                }
            }
            break;
        default:
            break;
        }

        // Only parse siblings of the block if we are not at depth zero. A depth
        // of zero indicates we are currently parsing the top level 
        // DW_TAG_subprogram DIE
        
        if (depth == 0)
            die = NULL;
        else
            die = die->GetSibling();
    }
    return blocks_added;
}

bool
SymbolFileDWARF::ParseTemplateDIE (DWARFCompileUnit* dwarf_cu,
                                   const DWARFDebugInfoEntry *die,
                                   ClangASTContext::TemplateParameterInfos &template_param_infos)
{
    const dw_tag_t tag = die->Tag();
    
    switch (tag)
    {
    case DW_TAG_template_type_parameter:
    case DW_TAG_template_value_parameter:
        {
            const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());

            DWARFDebugInfoEntry::Attributes attributes;
            const size_t num_attributes = die->GetAttributes (this, 
                                                              dwarf_cu, 
                                                              fixed_form_sizes, 
                                                              attributes);
            const char *name = NULL;
            Type *lldb_type = NULL;
            ClangASTType clang_type;
            uint64_t uval64 = 0;
            bool uval64_valid = false;
            if (num_attributes > 0)
            {
                DWARFFormValue form_value;
                for (size_t i=0; i<num_attributes; ++i)
                {
                    const dw_attr_t attr = attributes.AttributeAtIndex(i);
                    
                    switch (attr)
                    {
                        case DW_AT_name:
                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                                name = form_value.AsCString(&get_debug_str_data());
                            break;
                            
                        case DW_AT_type:
                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                            {
                                const dw_offset_t type_die_offset = form_value.Reference();
                                lldb_type = ResolveTypeUID(type_die_offset);
                                if (lldb_type)
                                    clang_type = lldb_type->GetClangForwardType();
                            }
                            break;
                            
                        case DW_AT_const_value:
                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                            {
                                uval64_valid = true;
                                uval64 = form_value.Unsigned();
                            }
                            break;
                        default:
                            break;
                    }
                }
                
                clang::ASTContext *ast = GetClangASTContext().getASTContext();
                if (!clang_type)
                    clang_type = GetClangASTContext().GetBasicType(eBasicTypeVoid);

                if (clang_type)
                {
                    bool is_signed = false;
                    if (name && name[0])
                        template_param_infos.names.push_back(name);
                    else
                        template_param_infos.names.push_back(NULL);
    
                    if (tag == DW_TAG_template_value_parameter &&
                        lldb_type != NULL &&
                        clang_type.IsIntegerType (is_signed) &&
                        uval64_valid)
                    {
                        llvm::APInt apint (lldb_type->GetByteSize() * 8, uval64, is_signed);
                        template_param_infos.args.push_back (clang::TemplateArgument (*ast,
                                                                                      llvm::APSInt(apint),
                                                                                      clang_type.GetQualType()));
                    }
                    else
                    {
                        template_param_infos.args.push_back (clang::TemplateArgument (clang_type.GetQualType()));
                    }
                }
                else
                {
                    return false;
                }
                
            }
        }
        return true;

    default:
        break;
    }
    return false;
}

bool
SymbolFileDWARF::ParseTemplateParameterInfos (DWARFCompileUnit* dwarf_cu,
                                              const DWARFDebugInfoEntry *parent_die,
                                              ClangASTContext::TemplateParameterInfos &template_param_infos)
{

    if (parent_die == NULL)
        return false;
    
    Args template_parameter_names;
    for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild(); 
         die != NULL; 
         die = die->GetSibling())
    {
        const dw_tag_t tag = die->Tag();
        
        switch (tag)
        {
            case DW_TAG_template_type_parameter:
            case DW_TAG_template_value_parameter:
                ParseTemplateDIE (dwarf_cu, die, template_param_infos);
            break;
                
        default:
            break;
        }
    }
    if (template_param_infos.args.empty())
        return false;
    return template_param_infos.args.size() == template_param_infos.names.size();
}

clang::ClassTemplateDecl *
SymbolFileDWARF::ParseClassTemplateDecl (clang::DeclContext *decl_ctx,
                                         lldb::AccessType access_type,
                                         const char *parent_name,
                                         int tag_decl_kind,
                                         const ClangASTContext::TemplateParameterInfos &template_param_infos)
{
    if (template_param_infos.IsValid())
    {
        std::string template_basename(parent_name);
        template_basename.erase (template_basename.find('<'));
        ClangASTContext &ast = GetClangASTContext();

        return ast.CreateClassTemplateDecl (decl_ctx,
                                            access_type,
                                            template_basename.c_str(), 
                                            tag_decl_kind, 
                                            template_param_infos);
    }
    return NULL;
}

class SymbolFileDWARF::DelayedAddObjCClassProperty
{
public:
    DelayedAddObjCClassProperty
    (
        const ClangASTType     &class_opaque_type,
        const char             *property_name,
        const ClangASTType     &property_opaque_type,  // The property type is only required if you don't have an ivar decl
        clang::ObjCIvarDecl    *ivar_decl,   
        const char             *property_setter_name,
        const char             *property_getter_name,
        uint32_t                property_attributes,
        const ClangASTMetadata *metadata
    ) :
        m_class_opaque_type     (class_opaque_type),
        m_property_name         (property_name),
        m_property_opaque_type  (property_opaque_type),
        m_ivar_decl             (ivar_decl),
        m_property_setter_name  (property_setter_name),
        m_property_getter_name  (property_getter_name),
        m_property_attributes   (property_attributes)
    {
        if (metadata != NULL)
        {
            m_metadata_ap.reset(new ClangASTMetadata());
            *m_metadata_ap = *metadata;
        }
    }
    
    DelayedAddObjCClassProperty (const DelayedAddObjCClassProperty &rhs)
    {
        *this = rhs;
    }

    DelayedAddObjCClassProperty& operator= (const DelayedAddObjCClassProperty &rhs)
    {
        m_class_opaque_type    = rhs.m_class_opaque_type;
        m_property_name        = rhs.m_property_name;
        m_property_opaque_type = rhs.m_property_opaque_type;
        m_ivar_decl            = rhs.m_ivar_decl;
        m_property_setter_name = rhs.m_property_setter_name;
        m_property_getter_name = rhs.m_property_getter_name;
        m_property_attributes  = rhs.m_property_attributes;
        
        if (rhs.m_metadata_ap.get())
        {
            m_metadata_ap.reset (new ClangASTMetadata());
            *m_metadata_ap = *rhs.m_metadata_ap;
        }
        return *this;
    }
    
    bool
    Finalize()
    {
        return m_class_opaque_type.AddObjCClassProperty (m_property_name,
                                                         m_property_opaque_type,
                                                         m_ivar_decl,
                                                         m_property_setter_name,
                                                         m_property_getter_name,
                                                         m_property_attributes,
                                                         m_metadata_ap.get());
    }
private:
    ClangASTType            m_class_opaque_type;
    const char             *m_property_name;
    ClangASTType            m_property_opaque_type;
    clang::ObjCIvarDecl    *m_ivar_decl;
    const char             *m_property_setter_name;
    const char             *m_property_getter_name;
    uint32_t                m_property_attributes;
    std::unique_ptr<ClangASTMetadata> m_metadata_ap;
};

struct BitfieldInfo
{
    uint64_t bit_size;
    uint64_t bit_offset;
    
    BitfieldInfo () :
        bit_size (LLDB_INVALID_ADDRESS),
        bit_offset (LLDB_INVALID_ADDRESS)
    {
    }
    
    void
    Clear()
    {
        bit_size = LLDB_INVALID_ADDRESS;
        bit_offset = LLDB_INVALID_ADDRESS;
    }

    bool IsValid ()
    {
        return (bit_size != LLDB_INVALID_ADDRESS) &&
               (bit_offset != LLDB_INVALID_ADDRESS);
    }
};


bool
SymbolFileDWARF::ClassOrStructIsVirtual (DWARFCompileUnit* dwarf_cu,
                                         const DWARFDebugInfoEntry *parent_die)
{
    if (parent_die)
    {
        for (const DWARFDebugInfoEntry *die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
        {
            dw_tag_t tag = die->Tag();
            bool check_virtuality = false;
            switch (tag)
            {
                case DW_TAG_inheritance:
                case DW_TAG_subprogram:
                    check_virtuality = true;
                    break;
                default:
                    break;
            }
            if (check_virtuality)
            {
                if (die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_virtuality, 0) != 0)
                    return true;
            }
        }
    }
    return false;
}

size_t
SymbolFileDWARF::ParseChildMembers
(
    const SymbolContext& sc,
    DWARFCompileUnit* dwarf_cu,
    const DWARFDebugInfoEntry *parent_die,
    ClangASTType &class_clang_type,
    const LanguageType class_language,
    std::vector<clang::CXXBaseSpecifier *>& base_classes,
    std::vector<int>& member_accessibilities,
    DWARFDIECollection& member_function_dies,
    DelayedPropertyList& delayed_properties,
    AccessType& default_accessibility,
    bool &is_a_class,
    LayoutInfo &layout_info
)
{
    if (parent_die == NULL)
        return 0;

    size_t count = 0;
    const DWARFDebugInfoEntry *die;
    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
    uint32_t member_idx = 0;
    BitfieldInfo last_field_info;
    ModuleSP module = GetObjectFile()->GetModule();

    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
    {
        dw_tag_t tag = die->Tag();

        switch (tag)
        {
        case DW_TAG_member:
        case DW_TAG_APPLE_property:
            {
                DWARFDebugInfoEntry::Attributes attributes;
                const size_t num_attributes = die->GetAttributes (this, 
                                                                  dwarf_cu, 
                                                                  fixed_form_sizes, 
                                                                  attributes);
                if (num_attributes > 0)
                {
                    Declaration decl;
                    //DWARFExpression location;
                    const char *name = NULL;
                    const char *prop_name = NULL;
                    const char *prop_getter_name = NULL;
                    const char *prop_setter_name = NULL;
                    uint32_t prop_attributes = 0;
                    
                    
                    bool is_artificial = false;
                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
                    AccessType accessibility = eAccessNone;
                    uint32_t member_byte_offset = UINT32_MAX;
                    size_t byte_size = 0;
                    size_t bit_offset = 0;
                    size_t bit_size = 0;
                    bool is_external = false; // On DW_TAG_members, this means the member is static
                    uint32_t i;
                    for (i=0; i<num_attributes && !is_artificial; ++i)
                    {
                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
                        DWARFFormValue form_value;
                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                        {
                            switch (attr)
                            {
                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
                            case DW_AT_type:        encoding_uid = form_value.Reference(); break;
                            case DW_AT_bit_offset:  bit_offset = form_value.Unsigned(); break;
                            case DW_AT_bit_size:    bit_size = form_value.Unsigned(); break;
                            case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
                            case DW_AT_data_member_location:
                                if (form_value.BlockData())
                                {
                                    Value initialValue(0);
                                    Value memberOffset(0);
                                    const DWARFDataExtractor& debug_info_data = get_debug_info_data();
                                    uint32_t block_length = form_value.Unsigned();
                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
                                    if (DWARFExpression::Evaluate(NULL, // ExecutionContext *
                                                                  NULL, // ClangExpressionVariableList *
                                                                  NULL, // ClangExpressionDeclMap *
                                                                  NULL, // RegisterContext *
                                                                  module,
                                                                  debug_info_data, 
                                                                  block_offset, 
                                                                  block_length, 
                                                                  eRegisterKindDWARF, 
                                                                  &initialValue, 
                                                                  memberOffset, 
                                                                  NULL))
                                    {
                                        member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
                                    }
                                }
                                else
                                {
                                    // With DWARF 3 and later, if the value is an integer constant,
                                    // this form value is the offset in bytes from the beginning
                                    // of the containing entity. 
                                    member_byte_offset = form_value.Unsigned(); 
                                }
                                break;

                            case DW_AT_accessibility: accessibility = DW_ACCESS_to_AccessType (form_value.Unsigned()); break;
                            case DW_AT_artificial: is_artificial = form_value.Boolean(); break;
                            case DW_AT_APPLE_property_name:      prop_name = form_value.AsCString(&get_debug_str_data()); break;
                            case DW_AT_APPLE_property_getter:    prop_getter_name = form_value.AsCString(&get_debug_str_data()); break;
                            case DW_AT_APPLE_property_setter:    prop_setter_name = form_value.AsCString(&get_debug_str_data()); break;
                            case DW_AT_APPLE_property_attribute: prop_attributes = form_value.Unsigned(); break;
                            case DW_AT_external:                 is_external = form_value.Boolean(); break;

                            default:
                            case DW_AT_declaration:
                            case DW_AT_description:
                            case DW_AT_mutable:
                            case DW_AT_visibility:
                            case DW_AT_sibling:
                                break;
                            }
                        }
                    }
                                        
                    if (prop_name)
                    {
                        ConstString fixed_getter;
                        ConstString fixed_setter;

                        // Check if the property getter/setter were provided as full
                        // names.  We want basenames, so we extract them.
                        
                        if (prop_getter_name && prop_getter_name[0] == '-')
                        {
                            ObjCLanguageRuntime::MethodName prop_getter_method(prop_getter_name, true);
                            prop_getter_name = prop_getter_method.GetSelector().GetCString();
                        }
                        
                        if (prop_setter_name && prop_setter_name[0] == '-')
                        {
                            ObjCLanguageRuntime::MethodName prop_setter_method(prop_setter_name, true);
                            prop_setter_name = prop_setter_method.GetSelector().GetCString();
                        }
                        
                        // If the names haven't been provided, they need to be
                        // filled in.
                        
                        if (!prop_getter_name)
                        {
                            prop_getter_name = prop_name;
                        }
                        if (!prop_setter_name && prop_name[0] && !(prop_attributes & DW_APPLE_PROPERTY_readonly))
                        {
                            StreamString ss;
                            
                            ss.Printf("set%c%s:",
                                      toupper(prop_name[0]),
                                      &prop_name[1]);
                            
                            fixed_setter.SetCString(ss.GetData());
                            prop_setter_name = fixed_setter.GetCString();
                        }
                    }
                    
                    // Clang has a DWARF generation bug where sometimes it
                    // represents fields that are references with bad byte size
                    // and bit size/offset information such as:
                    //
                    //  DW_AT_byte_size( 0x00 )
                    //  DW_AT_bit_size( 0x40 )
                    //  DW_AT_bit_offset( 0xffffffffffffffc0 )
                    //
                    // So check the bit offset to make sure it is sane, and if 
                    // the values are not sane, remove them. If we don't do this
                    // then we will end up with a crash if we try to use this 
                    // type in an expression when clang becomes unhappy with its
                    // recycled debug info.
                    
                    if (bit_offset > 128)
                    {
                        bit_size = 0;
                        bit_offset = 0;
                    }

                    // FIXME: Make Clang ignore Objective-C accessibility for expressions
                    if (class_language == eLanguageTypeObjC ||
                        class_language == eLanguageTypeObjC_plus_plus)
                        accessibility = eAccessNone; 
                    
                    if (member_idx == 0 && !is_artificial && name && (strstr (name, "_vptr$") == name))
                    {
                        // Not all compilers will mark the vtable pointer
                        // member as artificial (llvm-gcc). We can't have
                        // the virtual members in our classes otherwise it
                        // throws off all child offsets since we end up
                        // having and extra pointer sized member in our 
                        // class layouts.
                        is_artificial = true;
                    }

                    // Handle static members
                    if (is_external && member_byte_offset == UINT32_MAX)
                    {
                        Type *var_type = ResolveTypeUID(encoding_uid);

                        if (var_type)
                        {
                            if (accessibility == eAccessNone)
                                accessibility = eAccessPublic;
                            class_clang_type.AddVariableToRecordType (name,
                                                                      var_type->GetClangLayoutType(),
                                                                      accessibility);
                        }
                        break;
                    }

                    if (is_artificial == false)
                    {
                        Type *member_type = ResolveTypeUID(encoding_uid);
                        
                        clang::FieldDecl *field_decl = NULL;
                        if (tag == DW_TAG_member)
                        {
                            if (member_type)
                            {
                                if (accessibility == eAccessNone)
                                    accessibility = default_accessibility;
                                member_accessibilities.push_back(accessibility);
                                
                                uint64_t field_bit_offset = (member_byte_offset == UINT32_MAX ? 0 : (member_byte_offset * 8));
                                if (bit_size > 0)
                                {
                                    
                                    BitfieldInfo this_field_info;
                                    this_field_info.bit_offset = field_bit_offset;
                                    this_field_info.bit_size = bit_size;
                                    
                                    /////////////////////////////////////////////////////////////
                                    // How to locate a field given the DWARF debug information
                                    //
                                    // AT_byte_size indicates the size of the word in which the
                                    // bit offset must be interpreted.
                                    //
                                    // AT_data_member_location indicates the byte offset of the
                                    // word from the base address of the structure.
                                    //
                                    // AT_bit_offset indicates how many bits into the word
                                    // (according to the host endianness) the low-order bit of
                                    // the field starts.  AT_bit_offset can be negative.
                                    //
                                    // AT_bit_size indicates the size of the field in bits.
                                    /////////////////////////////////////////////////////////////
                                    
                                    if (byte_size == 0)
                                        byte_size = member_type->GetByteSize();
                                        
                                    if (GetObjectFile()->GetByteOrder() == eByteOrderLittle)
                                    {
                                        this_field_info.bit_offset += byte_size * 8;
                                        this_field_info.bit_offset -= (bit_offset + bit_size);
                                    }
                                    else
                                    {
                                        this_field_info.bit_offset += bit_offset;
                                    }
                                    
                                    // Update the field bit offset we will report for layout
                                    field_bit_offset = this_field_info.bit_offset;

                                    // If the member to be emitted did not start on a character boundary and there is
                                    // empty space between the last field and this one, then we need to emit an
                                    // anonymous member filling up the space up to its start.  There are three cases
                                    // here:
                                    //
                                    // 1 If the previous member ended on a character boundary, then we can emit an
                                    //   anonymous member starting at the most recent character boundary.
                                    //
                                    // 2 If the previous member did not end on a character boundary and the distance
                                    //   from the end of the previous member to the current member is less than a
                                    //   word width, then we can emit an anonymous member starting right after the
                                    //   previous member and right before this member.
                                    //
                                    // 3 If the previous member did not end on a character boundary and the distance
                                    //   from the end of the previous member to the current member is greater than
                                    //   or equal a word width, then we act as in Case 1.
                                    
                                    const uint64_t character_width = 8;
                                    const uint64_t word_width = 32;
                                    
                                    // Objective-C has invalid DW_AT_bit_offset values in older versions
                                    // of clang, so we have to be careful and only insert unnamed bitfields
                                    // if we have a new enough clang.
                                    bool detect_unnamed_bitfields = true;
                                    
                                    if (class_language == eLanguageTypeObjC || class_language == eLanguageTypeObjC_plus_plus)
                                        detect_unnamed_bitfields = dwarf_cu->Supports_unnamed_objc_bitfields ();
                                    
                                    if (detect_unnamed_bitfields)
                                    {
                                        BitfieldInfo anon_field_info;
                                        
                                        if ((this_field_info.bit_offset % character_width) != 0) // not char aligned
                                        {
                                            uint64_t last_field_end = 0;
                                            
                                            if (last_field_info.IsValid())
                                                last_field_end = last_field_info.bit_offset + last_field_info.bit_size;
                                            
                                            if (this_field_info.bit_offset != last_field_end)
                                            {                                                
                                                if (((last_field_end % character_width) == 0) ||                    // case 1
                                                    (this_field_info.bit_offset - last_field_end >= word_width))    // case 3
                                                {
                                                    anon_field_info.bit_size = this_field_info.bit_offset % character_width;
                                                    anon_field_info.bit_offset = this_field_info.bit_offset - anon_field_info.bit_size;
                                                }
                                                else                                                                // case 2
                                                {
                                                    anon_field_info.bit_size = this_field_info.bit_offset - last_field_end;
                                                    anon_field_info.bit_offset = last_field_end;
                                                }
                                            }
                                        }
                                        
                                        if (anon_field_info.IsValid())
                                        {
                                            clang::FieldDecl *unnamed_bitfield_decl = class_clang_type.AddFieldToRecordType (NULL,
                                                                                                                             GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width),
                                                                                                                             accessibility,
                                                                                                                             anon_field_info.bit_size);

                                            layout_info.field_offsets.insert(
                                                std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset));
                                        }
                                    }
                                    last_field_info = this_field_info;
                                }
                                else
                                {
                                    last_field_info.Clear();
                                }
                                
                                ClangASTType member_clang_type = member_type->GetClangLayoutType();
                                
                                {
                                    // Older versions of clang emit array[0] and array[1] in the same way (<rdar://problem/12566646>).
                                    // If the current field is at the end of the structure, then there is definitely no room for extra
                                    // elements and we override the type to array[0].
                                    
                                    ClangASTType member_array_element_type;
                                    uint64_t member_array_size;
                                    bool member_array_is_incomplete;
                                    
                                    if (member_clang_type.IsArrayType(&member_array_element_type,
                                                                      &member_array_size,
                                                                      &member_array_is_incomplete) &&
                                        !member_array_is_incomplete)
                                    {
                                        uint64_t parent_byte_size = parent_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, UINT64_MAX);
                                    
                                        if (member_byte_offset >= parent_byte_size)
                                        {
                                            if (member_array_size != 1)
                                            {
                                                GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which extends beyond the bounds of 0x%8.8" PRIx64,
                                                                                           MakeUserID(die->GetOffset()),
                                                                                           name,
                                                                                           encoding_uid,
                                                                                           MakeUserID(parent_die->GetOffset()));
                                            }
                                            
                                            member_clang_type = GetClangASTContext().CreateArrayType(member_array_element_type, 0, false);
                                        }
                                    }
                                }
                                
                                field_decl = class_clang_type.AddFieldToRecordType (name,
                                                                                    member_clang_type,
                                                                                    accessibility,
                                                                                    bit_size);
                                
                                GetClangASTContext().SetMetadataAsUserID (field_decl, MakeUserID(die->GetOffset()));

                                layout_info.field_offsets.insert(std::make_pair(field_decl, field_bit_offset));
                            }
                            else
                            {
                                if (name)
                                    GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
                                                                               MakeUserID(die->GetOffset()),
                                                                               name,
                                                                               encoding_uid);
                                else
                                    GetObjectFile()->GetModule()->ReportError ("0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8" PRIx64 " which was unable to be parsed",
                                                                               MakeUserID(die->GetOffset()),
                                                                               encoding_uid);
                            }
                        }
                        
                        if (prop_name != NULL && member_type)
                        {
                            clang::ObjCIvarDecl *ivar_decl = NULL;
                            
                            if (field_decl)
                            {
                                ivar_decl = clang::dyn_cast<clang::ObjCIvarDecl>(field_decl);
                                assert (ivar_decl != NULL);
                            }
                            
                            ClangASTMetadata metadata;
                            metadata.SetUserID (MakeUserID(die->GetOffset()));
                            delayed_properties.push_back(DelayedAddObjCClassProperty(class_clang_type,
                                                                                     prop_name,
                                                                                     member_type->GetClangLayoutType(),
                                                                                     ivar_decl,
                                                                                     prop_setter_name,
                                                                                     prop_getter_name,
                                                                                     prop_attributes,
                                                                                     &metadata));
                            
                            if (ivar_decl)
                                GetClangASTContext().SetMetadataAsUserID (ivar_decl, MakeUserID(die->GetOffset()));
                        }
                    }
                }
                ++member_idx;
            }
            break;

        case DW_TAG_subprogram:
            // Let the type parsing code handle this one for us. 
            member_function_dies.Append (die);
            break;

        case DW_TAG_inheritance:
            {
                is_a_class = true;
                if (default_accessibility == eAccessNone)
                    default_accessibility = eAccessPrivate;
                // TODO: implement DW_TAG_inheritance type parsing
                DWARFDebugInfoEntry::Attributes attributes;
                const size_t num_attributes = die->GetAttributes (this, 
                                                                  dwarf_cu, 
                                                                  fixed_form_sizes, 
                                                                  attributes);
                if (num_attributes > 0)
                {
                    Declaration decl;
                    DWARFExpression location;
                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;
                    AccessType accessibility = default_accessibility;
                    bool is_virtual = false;
                    bool is_base_of_class = true;
                    off_t member_byte_offset = 0;
                    uint32_t i;
                    for (i=0; i<num_attributes; ++i)
                    {
                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
                        DWARFFormValue form_value;
                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                        {
                            switch (attr)
                            {
                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
                            case DW_AT_type:        encoding_uid = form_value.Reference(); break;
                            case DW_AT_data_member_location:
                                if (form_value.BlockData())
                                {
                                    Value initialValue(0);
                                    Value memberOffset(0);
                                    const DWARFDataExtractor& debug_info_data = get_debug_info_data();
                                    uint32_t block_length = form_value.Unsigned();
                                    uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
                                    if (DWARFExpression::Evaluate (NULL, 
                                                                   NULL, 
                                                                   NULL, 
                                                                   NULL,
                                                                   module,
                                                                   debug_info_data, 
                                                                   block_offset, 
                                                                   block_length, 
                                                                   eRegisterKindDWARF, 
                                                                   &initialValue, 
                                                                   memberOffset, 
                                                                   NULL))
                                    {
                                        member_byte_offset = memberOffset.ResolveValue(NULL).UInt();
                                    }
                                }
                                else
                                {
                                    // With DWARF 3 and later, if the value is an integer constant,
                                    // this form value is the offset in bytes from the beginning
                                    // of the containing entity. 
                                    member_byte_offset = form_value.Unsigned(); 
                                }
                                break;

                            case DW_AT_accessibility:
                                accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned());
                                break;

                            case DW_AT_virtuality:
                                is_virtual = form_value.Boolean();
                                break;
                                                   
                            case DW_AT_sibling:
                                break;

                            default:
                                break;
                            }
                        }
                    }

                    Type *base_class_type = ResolveTypeUID(encoding_uid);
                    if (base_class_type == NULL)
                    {
                        GetObjectFile()->GetModule()->ReportError("0x%8.8x: DW_TAG_inheritance failed to resolve the base class at 0x%8.8" PRIx64 " from enclosing type 0x%8.8x. \nPlease file a bug and attach the file at the start of this error message",
                                                                  die->GetOffset(),
                                                                  encoding_uid,
                                                                  parent_die->GetOffset());
                        break;
                    }

                    ClangASTType base_class_clang_type = base_class_type->GetClangFullType();
                    assert (base_class_clang_type);
                    if (class_language == eLanguageTypeObjC)
                    {
                        class_clang_type.SetObjCSuperClass(base_class_clang_type);
                    }
                    else
                    {
                        base_classes.push_back (base_class_clang_type.CreateBaseClassSpecifier (accessibility,
                                                                                               is_virtual, 
                                                                                               is_base_of_class));
                        
                        if (is_virtual)
                        {
                            // Do not specify any offset for virtual inheritance. The DWARF produced by clang doesn't
                            // give us a constant offset, but gives us a DWARF expressions that requires an actual object
                            // in memory. the DW_AT_data_member_location for a virtual base class looks like:
                            //      DW_AT_data_member_location( DW_OP_dup, DW_OP_deref, DW_OP_constu(0x00000018), DW_OP_minus, DW_OP_deref, DW_OP_plus )
                            // Given this, there is really no valid response we can give to clang for virtual base
                            // class offsets, and this should eventually be removed from LayoutRecordType() in the external
                            // AST source in clang.
                        }
                        else
                        {
                            layout_info.base_offsets.insert(
                                std::make_pair(base_class_clang_type.GetAsCXXRecordDecl(),
                                               clang::CharUnits::fromQuantity(member_byte_offset)));
                        }
                    }
                }
            }
            break;

        default:
            break;
        }
    }
    
    return count;
}


clang::DeclContext*
SymbolFileDWARF::GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid)
{
    DWARFDebugInfo* debug_info = DebugInfo();
    if (debug_info && UserIDMatches(type_uid))
    {
        DWARFCompileUnitSP cu_sp;
        const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(type_uid, &cu_sp);
        if (die)
            return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
    }
    return NULL;
}

clang::DeclContext*
SymbolFileDWARF::GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid)
{
    if (UserIDMatches(type_uid))
        return GetClangDeclContextForDIEOffset (sc, type_uid);
    return NULL;
}

Type*
SymbolFileDWARF::ResolveTypeUID (lldb::user_id_t type_uid)
{
    if (UserIDMatches(type_uid))
    {
        DWARFDebugInfo* debug_info = DebugInfo();
        if (debug_info)
        {
            DWARFCompileUnitSP cu_sp;
            const DWARFDebugInfoEntry* type_die = debug_info->GetDIEPtr(type_uid, &cu_sp);
            const bool assert_not_being_parsed = true;
            return ResolveTypeUID (cu_sp.get(), type_die, assert_not_being_parsed);
        }
    }
    return NULL;
}

Type*
SymbolFileDWARF::ResolveTypeUID (DWARFCompileUnit* cu, const DWARFDebugInfoEntry* die, bool assert_not_being_parsed)
{    
    if (die != NULL)
    {
        Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
        if (log)
            GetObjectFile()->GetModule()->LogMessage (log,
                                                      "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s'", 
                                                      die->GetOffset(), 
                                                      DW_TAG_value_to_name(die->Tag()), 
                                                      die->GetName(this, cu));

        // We might be coming in in the middle of a type tree (a class
        // withing a class, an enum within a class), so parse any needed
        // parent DIEs before we get to this one...
        const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);
        switch (decl_ctx_die->Tag())
        {
            case DW_TAG_structure_type:
            case DW_TAG_union_type:
            case DW_TAG_class_type:
            {
                // Get the type, which could be a forward declaration
                if (log)
                    GetObjectFile()->GetModule()->LogMessage (log,
                                                              "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent forward type for 0x%8.8x", 
                                                              die->GetOffset(), 
                                                              DW_TAG_value_to_name(die->Tag()), 
                                                              die->GetName(this, cu), 
                                                              decl_ctx_die->GetOffset());
//
//                Type *parent_type = ResolveTypeUID (cu, decl_ctx_die, assert_not_being_parsed);
//                if (child_requires_parent_class_union_or_struct_to_be_completed(die->Tag()))
//                {
//                    if (log)
//                        GetObjectFile()->GetModule()->LogMessage (log,
//                                                                  "SymbolFileDWARF::ResolveTypeUID (die = 0x%8.8x) %s '%s' resolve parent full type for 0x%8.8x since die is a function", 
//                                                                  die->GetOffset(), 
//                                                                  DW_TAG_value_to_name(die->Tag()), 
//                                                                  die->GetName(this, cu), 
//                                                                  decl_ctx_die->GetOffset());
//                    // Ask the type to complete itself if it already hasn't since if we
//                    // want a function (method or static) from a class, the class must 
//                    // create itself and add it's own methods and class functions.
//                    if (parent_type)
//                        parent_type->GetClangFullType();
//                }
            }
            break;

            default:
                break;
        }
        return ResolveType (cu, die);
    }
    return NULL;
}

// This function is used when SymbolFileDWARFDebugMap owns a bunch of
// SymbolFileDWARF objects to detect if this DWARF file is the one that
// can resolve a clang_type.
bool
SymbolFileDWARF::HasForwardDeclForClangType (const ClangASTType &clang_type)
{
    ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
    return die != NULL;
}


bool
SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type)
{
    // We have a struct/union/class/enum that needs to be fully resolved.
    ClangASTType clang_type_no_qualifiers = clang_type.RemoveFastQualifiers();
    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
    if (die == NULL)
    {
        // We have already resolved this type...
        return true;
    }
    // Once we start resolving this type, remove it from the forward declaration
    // map in case anyone child members or other types require this type to get resolved.
    // The type will get resolved when all of the calls to SymbolFileDWARF::ResolveClangOpaqueTypeDefinition
    // are done.
    m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers.GetOpaqueQualType());

    // Disable external storage for this type so we don't get anymore 
    // clang::ExternalASTSource queries for this type.
    clang_type.SetHasExternalStorage (false);

    DWARFDebugInfo* debug_info = DebugInfo();

    DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitContainingDIE (die->GetOffset()).get();
    Type *type = m_die_to_type.lookup (die);

    const dw_tag_t tag = die->Tag();

    Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
    if (log)
        GetObjectFile()->GetModule()->LogMessageVerboseBacktrace (log,
                                                                  "0x%8.8" PRIx64 ": %s '%s' resolving forward declaration...",
                                                                  MakeUserID(die->GetOffset()),
                                                                  DW_TAG_value_to_name(tag),
                                                                  type->GetName().AsCString());
    assert (clang_type);
    DWARFDebugInfoEntry::Attributes attributes;

    switch (tag)
    {
    case DW_TAG_structure_type:
    case DW_TAG_union_type:
    case DW_TAG_class_type:
        {
            LayoutInfo layout_info;

            {
                if (die->HasChildren())
                {
                    LanguageType class_language = eLanguageTypeUnknown;
                    if (clang_type.IsObjCObjectOrInterfaceType())
                    {
                        class_language = eLanguageTypeObjC;
                        // For objective C we don't start the definition when
                        // the class is created.
                        clang_type.StartTagDeclarationDefinition ();
                    }

                    int tag_decl_kind = -1;
                    AccessType default_accessibility = eAccessNone;
                    if (tag == DW_TAG_structure_type)
                    {
                        tag_decl_kind = clang::TTK_Struct;
                        default_accessibility = eAccessPublic;
                    }
                    else if (tag == DW_TAG_union_type)
                    {
                        tag_decl_kind = clang::TTK_Union;
                        default_accessibility = eAccessPublic;
                    }
                    else if (tag == DW_TAG_class_type)
                    {
                        tag_decl_kind = clang::TTK_Class;
                        default_accessibility = eAccessPrivate;
                    }

                    SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
                    std::vector<clang::CXXBaseSpecifier *> base_classes;
                    std::vector<int> member_accessibilities;
                    bool is_a_class = false;
                    // Parse members and base classes first
                    DWARFDIECollection member_function_dies;

                    DelayedPropertyList delayed_properties;
                    ParseChildMembers (sc,
                                       dwarf_cu,
                                       die, 
                                       clang_type,
                                       class_language,
                                       base_classes, 
                                       member_accessibilities,
                                       member_function_dies,
                                       delayed_properties,
                                       default_accessibility, 
                                       is_a_class,
                                       layout_info);

                    // Now parse any methods if there were any...
                    size_t num_functions = member_function_dies.Size();                
                    if (num_functions > 0)
                    {
                        for (size_t i=0; i<num_functions; ++i)
                        {
                            ResolveType(dwarf_cu, member_function_dies.GetDIEPtrAtIndex(i));
                        }
                    }

                    if (class_language == eLanguageTypeObjC)
                    {
                        ConstString class_name (clang_type.GetTypeName());
                        if (class_name)
                        {
                            DIEArray method_die_offsets;
                            if (m_using_apple_tables)
                            {
                                if (m_apple_objc_ap.get())
                                    m_apple_objc_ap->FindByName(class_name.GetCString(), method_die_offsets);
                            }
                            else
                            {
                                if (!m_indexed)
                                    Index ();

                                m_objc_class_selectors_index.Find (class_name, method_die_offsets);
                            }

                            if (!method_die_offsets.empty())
                            {
                                DWARFDebugInfo* debug_info = DebugInfo();

                                DWARFCompileUnit* method_cu = NULL;
                                const size_t num_matches = method_die_offsets.size();
                                for (size_t i=0; i<num_matches; ++i)
                                {
                                    const dw_offset_t die_offset = method_die_offsets[i];
                                    DWARFDebugInfoEntry *method_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &method_cu);

                                    if (method_die)
                                        ResolveType (method_cu, method_die);
                                    else
                                    {
                                        if (m_using_apple_tables)
                                        {
                                            GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_objc accelerator table had bad die 0x%8.8x for '%s')\n",
                                                                                                       die_offset, class_name.GetCString());
                                        }
                                    }            
                                }
                            }

                            for (DelayedPropertyList::iterator pi = delayed_properties.begin(), pe = delayed_properties.end();
                                 pi != pe;
                                 ++pi)
                                pi->Finalize();
                        }
                    }

                    // If we have a DW_TAG_structure_type instead of a DW_TAG_class_type we
                    // need to tell the clang type it is actually a class.
                    if (class_language != eLanguageTypeObjC)
                    {
                        if (is_a_class && tag_decl_kind != clang::TTK_Class)
                            clang_type.SetTagTypeKind (clang::TTK_Class);
                    }

                    // Since DW_TAG_structure_type gets used for both classes
                    // and structures, we may need to set any DW_TAG_member
                    // fields to have a "private" access if none was specified.
                    // When we parsed the child members we tracked that actual
                    // accessibility value for each DW_TAG_member in the
                    // "member_accessibilities" array. If the value for the
                    // member is zero, then it was set to the "default_accessibility"
                    // which for structs was "public". Below we correct this
                    // by setting any fields to "private" that weren't correctly
                    // set.
                    if (is_a_class && !member_accessibilities.empty())
                    {
                        // This is a class and all members that didn't have
                        // their access specified are private.
                        clang_type.SetDefaultAccessForRecordFields (eAccessPrivate,
                                                                    &member_accessibilities.front(),
                                                                    member_accessibilities.size());
                    }

                    if (!base_classes.empty())
                    {
                        // Make sure all base classes refer to complete types and not
                        // forward declarations. If we don't do this, clang will crash
                        // with an assertion in the call to clang_type.SetBaseClassesForClassType()
                        bool base_class_error = false;
                        for (auto &base_class : base_classes)
                        {
                            clang::TypeSourceInfo *type_source_info = base_class->getTypeSourceInfo();
                            if (type_source_info)
                            {
                                ClangASTType base_class_type (GetClangASTContext().getASTContext(), type_source_info->getType());
                                if (base_class_type.GetCompleteType() == false)
                                {
                                    if (!base_class_error)
                                    {
                                        GetObjectFile()->GetModule()->ReportError ("DWARF DIE at 0x%8.8x for class '%s' has a base class '%s' that is a forward declaration, not a complete definition.\nPlease file a bug against the compiler and include the preprocessed output for %s",
                                                                                   die->GetOffset(),
                                                                                   die->GetName(this, dwarf_cu),
                                                                                   base_class_type.GetTypeName().GetCString(),
                                                                                   sc.comp_unit ? sc.comp_unit->GetPath().c_str() : "the source file");
                                    }
                                    // We have no choice other than to pretend that the base class
                                    // is complete. If we don't do this, clang will crash when we
                                    // call setBases() inside of "clang_type.SetBaseClassesForClassType()"
                                    // below. Since we provide layout assistance, all ivars in this
                                    // class and other classes will be fine, this is the best we can do
                                    // short of crashing.
                                    base_class_type.StartTagDeclarationDefinition ();
                                    base_class_type.CompleteTagDeclarationDefinition ();
                                }
                            }
                        }
                        clang_type.SetBaseClassesForClassType (&base_classes.front(),
                                                               base_classes.size());

                        // Clang will copy each CXXBaseSpecifier in "base_classes"
                        // so we have to free them all.
                        ClangASTType::DeleteBaseClassSpecifiers (&base_classes.front(),
                                                                 base_classes.size());
                    }
                }
            }

            clang_type.BuildIndirectFields ();
            clang_type.CompleteTagDeclarationDefinition ();

            if (!layout_info.field_offsets.empty() ||
                !layout_info.base_offsets.empty()  ||
                !layout_info.vbase_offsets.empty() )
            {
                if (type)
                    layout_info.bit_size = type->GetByteSize() * 8;
                if (layout_info.bit_size == 0)
                    layout_info.bit_size = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_byte_size, 0) * 8;

                clang::CXXRecordDecl *record_decl = clang_type.GetAsCXXRecordDecl();
                if (record_decl)
                {
                    if (log)
                    {
                        GetObjectFile()->GetModule()->LogMessage (log,
                                                                  "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) caching layout info for record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u], base_offsets[%u], vbase_offsets[%u])",
                                                                  static_cast<void*>(clang_type.GetOpaqueQualType()),
                                                                  static_cast<void*>(record_decl),
                                                                  layout_info.bit_size,
                                                                  layout_info.alignment,
                                                                  static_cast<uint32_t>(layout_info.field_offsets.size()),
                                                                  static_cast<uint32_t>(layout_info.base_offsets.size()),
                                                                  static_cast<uint32_t>(layout_info.vbase_offsets.size()));

                        uint32_t idx;
                        {
                            llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator pos,
                                end = layout_info.field_offsets.end();
                            for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx)
                        {
                            GetObjectFile()->GetModule()->LogMessage(
                                log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = "
                                     "{ bit_offset=%u, name='%s' }",
                                static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
                                static_cast<uint32_t>(pos->second), pos->first->getNameAsString().c_str());
                        }
                        }

                        {
                            llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos,
                                base_end = layout_info.base_offsets.end();
                            for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end;
                                 ++base_pos, ++idx)
                            {
                                GetObjectFile()->GetModule()->LogMessage(
                                    log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] "
                                         "= { byte_offset=%u, name='%s' }",
                                    clang_type.GetOpaqueQualType(), idx, (uint32_t)base_pos->second.getQuantity(),
                                    base_pos->first->getNameAsString().c_str());
                            }
                        }
                        {
                            llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos,
                                vbase_end = layout_info.vbase_offsets.end();
                            for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end;
                                 ++vbase_pos, ++idx)
                            {
                                GetObjectFile()->GetModule()->LogMessage(
                                    log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) "
                                         "vbase[%u] = { byte_offset=%u, name='%s' }",
                                    static_cast<void *>(clang_type.GetOpaqueQualType()), idx,
                                    static_cast<uint32_t>(vbase_pos->second.getQuantity()),
                                    vbase_pos->first->getNameAsString().c_str());
                            }
                        }
                    }
                    m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info));
                }
            }
        }

        return (bool)clang_type;

    case DW_TAG_enumeration_type:
        clang_type.StartTagDeclarationDefinition ();
        if (die->HasChildren())
        {
            SymbolContext sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
            bool is_signed = false;
            clang_type.IsIntegerType(is_signed);
            ParseChildEnumerators(sc, clang_type, is_signed, type->GetByteSize(), dwarf_cu, die);
        }
        clang_type.CompleteTagDeclarationDefinition ();
        return (bool)clang_type;

    default:
        assert(false && "not a forward clang type decl!");
        break;
    }
    return false;
}

Type*
SymbolFileDWARF::ResolveType (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* type_die, bool assert_not_being_parsed)
{
    if (type_die != NULL)
    {
        Type *type = m_die_to_type.lookup (type_die);

        if (type == NULL)
            type = GetTypeForDIE (dwarf_cu, type_die).get();

        if (assert_not_being_parsed)
        { 
            if (type != DIE_IS_BEING_PARSED)
                return type;
            
            GetObjectFile()->GetModule()->ReportError ("Parsing a die that is being parsed die: 0x%8.8x: %s %s",
                                                       type_die->GetOffset(), 
                                                       DW_TAG_value_to_name(type_die->Tag()), 
                                                       type_die->GetName(this, dwarf_cu));

        }
        else
            return type;
    }
    return NULL;
}

CompileUnit*
SymbolFileDWARF::GetCompUnitForDWARFCompUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
{
    // Check if the symbol vendor already knows about this compile unit?
    if (dwarf_cu->GetUserData() == NULL)
    {
        // The symbol vendor doesn't know about this compile unit, we
        // need to parse and add it to the symbol vendor object.
        return ParseCompileUnit(dwarf_cu, cu_idx).get();
    }
    return (CompileUnit*)dwarf_cu->GetUserData();
}

bool
SymbolFileDWARF::GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry* func_die, SymbolContext& sc)
{
    sc.Clear(false);
    // Check if the symbol vendor already knows about this compile unit?
    sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);

    sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(func_die->GetOffset())).get();
    if (sc.function == NULL)
        sc.function = ParseCompileUnitFunction(sc, dwarf_cu, func_die);
        
    if (sc.function)
    {        
        sc.module_sp = sc.function->CalculateSymbolContextModule();
        return true;
    }
    
    return false;
}

void
SymbolFileDWARF::UpdateExternalModuleListIfNeeded()
{
    if (m_fetched_external_modules)
        return;
    m_fetched_external_modules = true;
    
    DWARFDebugInfo * debug_info = DebugInfo();
    debug_info->GetNumCompileUnits();
    
    const uint32_t num_compile_units = GetNumCompileUnits();
    for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
    {
        DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
        
        const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly();
        if (die && die->HasChildren() == false)
        {
            const uint64_t name_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_name, UINT64_MAX);
            const uint64_t dwo_path_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_GNU_dwo_name, UINT64_MAX);
            
            if (name_strp != UINT64_MAX)
            {
                if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end())
                {
                    const char *name = get_debug_str_data().PeekCStr(name_strp);
                    const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp);
                    if (name || dwo_path)
                    {
                        ModuleSP module_sp;
                        if (dwo_path)
                        {
                            ModuleSpec dwo_module_spec;
                            dwo_module_spec.GetFileSpec().SetFile(dwo_path, false);
                            dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture();
                            //printf ("Loading dwo = '%s'\n", dwo_path);
                            Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL);
                        }
                        
                        if (dwo_path_strp != LLDB_INVALID_UID)
                        {
                            m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp };
                        }
                        else
                        {
                            // This hack should be removed promptly once clang emits both.
                            m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp };
                        }
                    }
                }
            }
        }
    }
}

SymbolFileDWARF::GlobalVariableMap &
SymbolFileDWARF::GetGlobalAranges()
{
    if (!m_global_aranges_ap)
    {
        m_global_aranges_ap.reset (new GlobalVariableMap());

        ModuleSP module_sp = GetObjectFile()->GetModule();
        if (module_sp)
        {
            const size_t num_cus = module_sp->GetNumCompileUnits();
            for (size_t i = 0; i < num_cus; ++i)
            {
                CompUnitSP cu_sp = module_sp->GetCompileUnitAtIndex(i);
                if (cu_sp)
                {
                    VariableListSP globals_sp = cu_sp->GetVariableList(true);
                    if (globals_sp)
                    {
                        const size_t num_globals = globals_sp->GetSize();
                        for (size_t g = 0; g < num_globals; ++g)
                        {
                            VariableSP var_sp = globals_sp->GetVariableAtIndex(g);
                            if (var_sp && !var_sp->GetLocationIsConstantValueData())
                            {
                                const DWARFExpression &location = var_sp->LocationExpression();
                                Value location_result;
                                Error error;
                                if (location.Evaluate(NULL, NULL, NULL, LLDB_INVALID_ADDRESS, NULL, location_result, &error))
                                {
                                    if (location_result.GetValueType() == Value::eValueTypeFileAddress)
                                    {
                                        lldb::addr_t file_addr = location_result.GetScalar().ULongLong();
                                        lldb::addr_t byte_size = 1;
                                        if (var_sp->GetType())
                                            byte_size = var_sp->GetType()->GetByteSize();
                                        m_global_aranges_ap->Append(GlobalVariableMap::Entry(file_addr, byte_size, var_sp.get()));
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        m_global_aranges_ap->Sort();
    }
    return *m_global_aranges_ap;
}


uint32_t
SymbolFileDWARF::ResolveSymbolContext (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
    Timer scoped_timer(__PRETTY_FUNCTION__,
                       "SymbolFileDWARF::ResolveSymbolContext (so_addr = { section = %p, offset = 0x%" PRIx64 " }, resolve_scope = 0x%8.8x)",
                       static_cast<void*>(so_addr.GetSection().get()),
                       so_addr.GetOffset(), resolve_scope);
    uint32_t resolved = 0;
    if (resolve_scope & (   eSymbolContextCompUnit  |
                            eSymbolContextFunction  |
                            eSymbolContextBlock     |
                            eSymbolContextLineEntry |
                            eSymbolContextVariable  ))
    {
        lldb::addr_t file_vm_addr = so_addr.GetFileAddress();

        DWARFDebugInfo* debug_info = DebugInfo();
        if (debug_info)
        {
            const dw_offset_t cu_offset = debug_info->GetCompileUnitAranges().FindAddress(file_vm_addr);
            if (cu_offset == DW_INVALID_OFFSET)
            {
                // Global variables are not in the compile unit address ranges. The only way to
                // currently find global variables is to iterate over the .debug_pubnames or the
                // __apple_names table and find all items in there that point to DW_TAG_variable
                // DIEs and then find the address that matches.
                if (resolve_scope & eSymbolContextVariable)
                {
                    GlobalVariableMap &map = GetGlobalAranges();
                    const GlobalVariableMap::Entry *entry = map.FindEntryThatContains(file_vm_addr);
                    if (entry && entry->data)
                    {
                        Variable *variable = entry->data;
                        SymbolContextScope *scc = variable->GetSymbolContextScope();
                        if (scc)
                        {
                            scc->CalculateSymbolContext(&sc);
                            sc.variable = variable;
                        }
                        return sc.GetResolvedMask();
                    }
                }
            }
            else
            {
                uint32_t cu_idx = DW_INVALID_INDEX;
                DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnit(cu_offset, &cu_idx).get();
                if (dwarf_cu)
                {
                    sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
                    if (sc.comp_unit)
                    {
                        resolved |= eSymbolContextCompUnit;

                        bool force_check_line_table = false;
                        if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
                        {
                            DWARFDebugInfoEntry *function_die = NULL;
                            DWARFDebugInfoEntry *block_die = NULL;
                            if (resolve_scope & eSymbolContextBlock)
                            {
                                dwarf_cu->LookupAddress(file_vm_addr, &function_die, &block_die);
                            }
                            else
                            {
                                dwarf_cu->LookupAddress(file_vm_addr, &function_die, NULL);
                            }

                            if (function_die != NULL)
                            {
                                sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
                                if (sc.function == NULL)
                                    sc.function = ParseCompileUnitFunction(sc, dwarf_cu, function_die);
                            }
                            else
                            {
                                // We might have had a compile unit that had discontiguous
                                // address ranges where the gaps are symbols that don't have
                                // any debug info. Discontiguous compile unit address ranges
                                // should only happen when there aren't other functions from
                                // other compile units in these gaps. This helps keep the size
                                // of the aranges down.
                                force_check_line_table = true;
                            }

                            if (sc.function != NULL)
                            {
                                resolved |= eSymbolContextFunction;

                                if (resolve_scope & eSymbolContextBlock)
                                {
                                    Block& block = sc.function->GetBlock (true);

                                    if (block_die != NULL)
                                        sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
                                    else
                                        sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
                                    if (sc.block)
                                        resolved |= eSymbolContextBlock;
                                }
                            }
                        }
                        
                        if ((resolve_scope & eSymbolContextLineEntry) || force_check_line_table)
                        {
                            LineTable *line_table = sc.comp_unit->GetLineTable();
                            if (line_table != NULL)
                            {
                                // And address that makes it into this function should be in terms
                                // of this debug file if there is no debug map, or it will be an
                                // address in the .o file which needs to be fixed up to be in terms
                                // of the debug map executable. Either way, calling FixupAddress()
                                // will work for us.
                                Address exe_so_addr (so_addr);
                                if (FixupAddress(exe_so_addr))
                                {
                                    if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
                                    {
                                        resolved |= eSymbolContextLineEntry;
                                    }
                                }
                            }
                        }
                        
                        if (force_check_line_table && !(resolved & eSymbolContextLineEntry))
                        {
                            // We might have had a compile unit that had discontiguous
                            // address ranges where the gaps are symbols that don't have
                            // any debug info. Discontiguous compile unit address ranges
                            // should only happen when there aren't other functions from
                            // other compile units in these gaps. This helps keep the size
                            // of the aranges down.
                            sc.comp_unit = NULL;
                            resolved &= ~eSymbolContextCompUnit;
                        }
                    }
                    else
                    {
                        GetObjectFile()->GetModule()->ReportWarning ("0x%8.8x: compile unit %u failed to create a valid lldb_private::CompileUnit class.",
                                                                     cu_offset,
                                                                     cu_idx);
                    }
                }
            }
        }
    }
    return resolved;
}



uint32_t
SymbolFileDWARF::ResolveSymbolContext(const FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, SymbolContextList& sc_list)
{
    const uint32_t prev_size = sc_list.GetSize();
    if (resolve_scope & eSymbolContextCompUnit)
    {
        DWARFDebugInfo* debug_info = DebugInfo();
        if (debug_info)
        {
            uint32_t cu_idx;
            DWARFCompileUnit* dwarf_cu = NULL;

            for (cu_idx = 0; (dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx)) != NULL; ++cu_idx)
            {
                CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
                const bool full_match = (bool)file_spec.GetDirectory();
                bool file_spec_matches_cu_file_spec = dc_cu != NULL && FileSpec::Equal(file_spec, *dc_cu, full_match);
                if (check_inlines || file_spec_matches_cu_file_spec)
                {
                    SymbolContext sc (m_obj_file->GetModule());
                    sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, cu_idx);
                    if (sc.comp_unit)
                    {
                        uint32_t file_idx = UINT32_MAX;

                        // If we are looking for inline functions only and we don't
                        // find it in the support files, we are done.
                        if (check_inlines)
                        {
                            file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);
                            if (file_idx == UINT32_MAX)
                                continue;
                        }

                        if (line != 0)
                        {
                            LineTable *line_table = sc.comp_unit->GetLineTable();

                            if (line_table != NULL && line != 0)
                            {
                                // We will have already looked up the file index if
                                // we are searching for inline entries.
                                if (!check_inlines)
                                    file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex (1, file_spec, true);

                                if (file_idx != UINT32_MAX)
                                {
                                    uint32_t found_line;
                                    uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex (0, file_idx, line, false, &sc.line_entry);
                                    found_line = sc.line_entry.line;

                                    while (line_idx != UINT32_MAX)
                                    {
                                        sc.function = NULL;
                                        sc.block = NULL;
                                        if (resolve_scope & (eSymbolContextFunction | eSymbolContextBlock))
                                        {
                                            const lldb::addr_t file_vm_addr = sc.line_entry.range.GetBaseAddress().GetFileAddress();
                                            if (file_vm_addr != LLDB_INVALID_ADDRESS)
                                            {
                                                DWARFDebugInfoEntry *function_die = NULL;
                                                DWARFDebugInfoEntry *block_die = NULL;
                                                dwarf_cu->LookupAddress(file_vm_addr, &function_die, resolve_scope & eSymbolContextBlock ? &block_die : NULL);

                                                if (function_die != NULL)
                                                {
                                                    sc.function = sc.comp_unit->FindFunctionByUID (MakeUserID(function_die->GetOffset())).get();
                                                    if (sc.function == NULL)
                                                        sc.function = ParseCompileUnitFunction(sc, dwarf_cu, function_die);
                                                }

                                                if (sc.function != NULL)
                                                {
                                                    Block& block = sc.function->GetBlock (true);

                                                    if (block_die != NULL)
                                                        sc.block = block.FindBlockByID (MakeUserID(block_die->GetOffset()));
                                                    else if (function_die != NULL)
                                                        sc.block = block.FindBlockByID (MakeUserID(function_die->GetOffset()));
                                                }
                                            }
                                        }

                                        sc_list.Append(sc);
                                        line_idx = line_table->FindLineEntryIndexByFileIndex (line_idx + 1, file_idx, found_line, true, &sc.line_entry);
                                    }
                                }
                            }
                            else if (file_spec_matches_cu_file_spec && !check_inlines)
                            {
                                // only append the context if we aren't looking for inline call sites
                                // by file and line and if the file spec matches that of the compile unit
                                sc_list.Append(sc);
                            }
                        }
                        else if (file_spec_matches_cu_file_spec && !check_inlines)
                        {
                            // only append the context if we aren't looking for inline call sites
                            // by file and line and if the file spec matches that of the compile unit
                            sc_list.Append(sc);
                        }

                        if (!check_inlines)
                            break;
                    }
                }
            }
        }
    }
    return sc_list.GetSize() - prev_size;
}

void
SymbolFileDWARF::Index ()
{
    if (m_indexed)
        return;
    m_indexed = true;
    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "SymbolFileDWARF::Index (%s)",
                        GetObjectFile()->GetFileSpec().GetFilename().AsCString("<Unknown>"));

    DWARFDebugInfo* debug_info = DebugInfo();
    if (debug_info)
    {
        uint32_t cu_idx = 0;
        const uint32_t num_compile_units = GetNumCompileUnits();
        for (cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
        {
            DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);

            bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1;

            dwarf_cu->Index (cu_idx,
                             m_function_basename_index,
                             m_function_fullname_index,
                             m_function_method_index,
                             m_function_selector_index,
                             m_objc_class_selectors_index,
                             m_global_index, 
                             m_type_index,
                             m_namespace_index);
            
            // Keep memory down by clearing DIEs if this generate function
            // caused them to be parsed
            if (clear_dies)
                dwarf_cu->ClearDIEs (true);
        }
        
        m_function_basename_index.Finalize();
        m_function_fullname_index.Finalize();
        m_function_method_index.Finalize();
        m_function_selector_index.Finalize();
        m_objc_class_selectors_index.Finalize();
        m_global_index.Finalize(); 
        m_type_index.Finalize();
        m_namespace_index.Finalize();

#if defined (ENABLE_DEBUG_PRINTF)
        StreamFile s(stdout, false);
        s.Printf ("DWARF index for '%s':",
                  GetObjectFile()->GetFileSpec().GetPath().c_str());
        s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
        s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
        s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
        s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
        s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
        s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s); 
        s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
        s.Printf("\nNamepaces:\n");             m_namespace_index.Dump (&s);
#endif
    }
}

bool
SymbolFileDWARF::NamespaceDeclMatchesThisSymbolFile (const ClangNamespaceDecl *namespace_decl)
{
    if (namespace_decl == NULL)
    {
        // Invalid namespace decl which means we aren't matching only things
        // in this symbol file, so return true to indicate it matches this
        // symbol file.
        return true;
    }
    
    clang::ASTContext *namespace_ast = namespace_decl->GetASTContext();

    if (namespace_ast == NULL)
        return true;    // No AST in the "namespace_decl", return true since it 
                        // could then match any symbol file, including this one

    if (namespace_ast == GetClangASTContext().getASTContext())
        return true;    // The ASTs match, return true
    
    // The namespace AST was valid, and it does not match...
    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));

    if (log)
        GetObjectFile()->GetModule()->LogMessage(log, "Valid namespace does not match symbol file");
    
    return false;
}

bool
SymbolFileDWARF::DIEIsInNamespace (const ClangNamespaceDecl *namespace_decl, 
                                   DWARFCompileUnit* cu, 
                                   const DWARFDebugInfoEntry* die)
{
    // No namespace specified, so the answer is
    if (namespace_decl == NULL)
        return true;
    
    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));

    const DWARFDebugInfoEntry *decl_ctx_die = NULL;
    clang::DeclContext *die_clang_decl_ctx = GetClangDeclContextContainingDIE (cu, die, &decl_ctx_die);
    if (decl_ctx_die)
    { 
        clang::NamespaceDecl *clang_namespace_decl = namespace_decl->GetNamespaceDecl();

        if (clang_namespace_decl)
        {
            if (decl_ctx_die->Tag() != DW_TAG_namespace)
            {
                if (log)
                    GetObjectFile()->GetModule()->LogMessage(log, "Found a match, but its parent is not a namespace");
                return false;
            }
                
            if (clang_namespace_decl == die_clang_decl_ctx)
                return true;
            else
                return false;
        }
        else
        {
            // We have a namespace_decl that was not NULL but it contained
            // a NULL "clang::NamespaceDecl", so this means the global namespace
            // So as long the contained decl context DIE isn't a namespace
            // we should be ok.
            if (decl_ctx_die->Tag() != DW_TAG_namespace)
                return true;
        }
    }
    
    if (log)
        GetObjectFile()->GetModule()->LogMessage(log, "Found a match, but its parent doesn't exist");
    
    return false;
}
uint32_t
SymbolFileDWARF::FindGlobalVariables (const ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, VariableList& variables)
{
    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));

    if (log)
        GetObjectFile()->GetModule()->LogMessage (log,
                                                  "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables)", 
                                                  name.GetCString(), 
                                                  static_cast<const void*>(namespace_decl),
                                                  append, max_matches);

    if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
        return 0;

    DWARFDebugInfo* info = DebugInfo();
    if (info == NULL)
        return 0;

    // If we aren't appending the results to this list, then clear the list
    if (!append)
        variables.Clear();

    // Remember how many variables are in the list before we search in case
    // we are appending the results to a variable list.
    const uint32_t original_size = variables.GetSize();

    DIEArray die_offsets;

    if (m_using_apple_tables)
    {
        if (m_apple_names_ap.get())
        {
            const char *name_cstr = name.GetCString();
            llvm::StringRef basename;
            llvm::StringRef context;

            if (!CPPLanguageRuntime::ExtractContextAndIdentifier(name_cstr, context, basename))
                basename = name_cstr;

            m_apple_names_ap->FindByName (basename.data(), die_offsets);
        }
    }
    else
    {
        // Index the DWARF if we haven't already
        if (!m_indexed)
            Index ();

        m_global_index.Find (name, die_offsets);
    }

    const size_t num_die_matches = die_offsets.size();
    if (num_die_matches)
    {
        SymbolContext sc;
        sc.module_sp = m_obj_file->GetModule();
        assert (sc.module_sp);

        DWARFDebugInfo* debug_info = DebugInfo();
        DWARFCompileUnit* dwarf_cu = NULL;
        const DWARFDebugInfoEntry* die = NULL;
        bool done = false;
        for (size_t i=0; i<num_die_matches && !done; ++i)
        {
            const dw_offset_t die_offset = die_offsets[i];
            die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);

            if (die)
            {
                switch (die->Tag())
                {
                    default:
                    case DW_TAG_subprogram:
                    case DW_TAG_inlined_subroutine:
                    case DW_TAG_try_block:
                    case DW_TAG_catch_block:
                        break;

                    case DW_TAG_variable:
                        {
                            sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);

                            if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
                                continue;

                            ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);

                            if (variables.GetSize() - original_size >= max_matches)
                                done = true;
                        }
                        break;
                }
            }
            else
            {
                if (m_using_apple_tables)
                {
                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')\n",
                                                                               die_offset, name.GetCString());
                }
            }
        }
    }

    // Return the number of variable that were appended to the list
    const uint32_t num_matches = variables.GetSize() - original_size;
    if (log && num_matches > 0)
    {
        GetObjectFile()->GetModule()->LogMessage (log,
                                                  "SymbolFileDWARF::FindGlobalVariables (name=\"%s\", namespace_decl=%p, append=%u, max_matches=%u, variables) => %u",
                                                  name.GetCString(),
                                                  static_cast<const void*>(namespace_decl),
                                                  append, max_matches,
                                                  num_matches);
    }
    return num_matches;
}

uint32_t
SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables)
{
    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));

    if (log)
    {
        GetObjectFile()->GetModule()->LogMessage (log,
                                                  "SymbolFileDWARF::FindGlobalVariables (regex=\"%s\", append=%u, max_matches=%u, variables)", 
                                                  regex.GetText(), append,
                                                  max_matches);
    }

    DWARFDebugInfo* info = DebugInfo();
    if (info == NULL)
        return 0;

    // If we aren't appending the results to this list, then clear the list
    if (!append)
        variables.Clear();

    // Remember how many variables are in the list before we search in case
    // we are appending the results to a variable list.
    const uint32_t original_size = variables.GetSize();

    DIEArray die_offsets;
    
    if (m_using_apple_tables)
    {
        if (m_apple_names_ap.get())
        {
            DWARFMappedHash::DIEInfoArray hash_data_array;
            if (m_apple_names_ap->AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
                DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
        }
    }
    else
    {
        // Index the DWARF if we haven't already
        if (!m_indexed)
            Index ();
        
        m_global_index.Find (regex, die_offsets);
    }

    SymbolContext sc;
    sc.module_sp = m_obj_file->GetModule();
    assert (sc.module_sp);
    
    DWARFCompileUnit* dwarf_cu = NULL;
    const DWARFDebugInfoEntry* die = NULL;
    const size_t num_matches = die_offsets.size();
    if (num_matches)
    {
        DWARFDebugInfo* debug_info = DebugInfo();
        for (size_t i=0; i<num_matches; ++i)
        {
            const dw_offset_t die_offset = die_offsets[i];
            die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
            
            if (die)
            {
                sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);

                ParseVariables(sc, dwarf_cu, LLDB_INVALID_ADDRESS, die, false, false, &variables);

                if (variables.GetSize() - original_size >= max_matches)
                    break;
            }
            else
            {
                if (m_using_apple_tables)
                {
                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for regex '%s')\n",
                                                                               die_offset, regex.GetText());
                }
            }            
        }
    }

    // Return the number of variable that were appended to the list
    return variables.GetSize() - original_size;
}


bool
SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset,
                                  DWARFCompileUnit *&dwarf_cu,
                                  bool include_inlines,
                                  SymbolContextList& sc_list)
{
    const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
    return ResolveFunction (dwarf_cu, die, include_inlines, sc_list);
}
    

bool
SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu,
                                  const DWARFDebugInfoEntry *die,
                                  bool include_inlines,
                                  SymbolContextList& sc_list)
{
    SymbolContext sc;

    if (die == NULL)
        return false;

    // If we were passed a die that is not a function, just return false...
    if (! (die->Tag() == DW_TAG_subprogram || (include_inlines && die->Tag() == DW_TAG_inlined_subroutine)))
        return false;
    
    const DWARFDebugInfoEntry* inlined_die = NULL;
    if (die->Tag() == DW_TAG_inlined_subroutine)
    {
        inlined_die = die;
        
        while ((die = die->GetParent()) != NULL)
        {
            if (die->Tag() == DW_TAG_subprogram)
                break;
        }
    }
    assert (die && die->Tag() == DW_TAG_subprogram);
    if (GetFunction (cu, die, sc))
    {
        Address addr;
        // Parse all blocks if needed
        if (inlined_die)
        {
            Block &function_block = sc.function->GetBlock (true);
            sc.block = function_block.FindBlockByID (MakeUserID(inlined_die->GetOffset()));
            if (sc.block == NULL)
                sc.block = function_block.FindBlockByID (inlined_die->GetOffset());
            if (sc.block == NULL || sc.block->GetStartAddress (addr) == false)
                addr.Clear();
        }
        else 
        {
            sc.block = NULL;
            addr = sc.function->GetAddressRange().GetBaseAddress();
        }

        if (addr.IsValid())
        {
            sc_list.Append(sc);
            return true;
        }
    }
    
    return false;
}

void
SymbolFileDWARF::FindFunctions (const ConstString &name, 
                                const NameToDIE &name_to_die,
                                bool include_inlines,
                                SymbolContextList& sc_list)
{
    DIEArray die_offsets;
    if (name_to_die.Find (name, die_offsets))
    {
        ParseFunctions (die_offsets, include_inlines, sc_list);
    }
}


void
SymbolFileDWARF::FindFunctions (const RegularExpression &regex, 
                                const NameToDIE &name_to_die,
                                bool include_inlines,
                                SymbolContextList& sc_list)
{
    DIEArray die_offsets;
    if (name_to_die.Find (regex, die_offsets))
    {
        ParseFunctions (die_offsets, include_inlines, sc_list);
    }
}


void
SymbolFileDWARF::FindFunctions (const RegularExpression &regex, 
                                const DWARFMappedHash::MemoryTable &memory_table,
                                bool include_inlines,
                                SymbolContextList& sc_list)
{
    DIEArray die_offsets;
    DWARFMappedHash::DIEInfoArray hash_data_array;
    if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array))
    {
        DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
        ParseFunctions (die_offsets, include_inlines, sc_list);
    }
}

void
SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets,
                                 bool include_inlines,
                                 SymbolContextList& sc_list)
{
    const size_t num_matches = die_offsets.size();
    if (num_matches)
    {
        DWARFCompileUnit* dwarf_cu = NULL;
        for (size_t i=0; i<num_matches; ++i)
        {
            const dw_offset_t die_offset = die_offsets[i];
            ResolveFunction (die_offset, dwarf_cu, include_inlines, sc_list);
        }
    }
}

bool
SymbolFileDWARF::FunctionDieMatchesPartialName (const DWARFDebugInfoEntry* die,
                                                const DWARFCompileUnit *dwarf_cu,
                                                uint32_t name_type_mask, 
                                                const char *partial_name,
                                                const char *base_name_start,
                                                const char *base_name_end)
{
    // If we are looking only for methods, throw away all the ones that are or aren't in C++ classes:
    if (name_type_mask == eFunctionNameTypeMethod || name_type_mask == eFunctionNameTypeBase)
    {
        clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIEOffset(die->GetOffset());
        if (!containing_decl_ctx)
            return false;
        
        bool is_cxx_method = DeclKindIsCXXClass(containing_decl_ctx->getDeclKind());
        
        if (name_type_mask == eFunctionNameTypeMethod)
        {
            if (is_cxx_method == false)
                return false;
        }
        
        if (name_type_mask == eFunctionNameTypeBase)
        {
            if (is_cxx_method == true)
                return false;
        }
    }

    // Now we need to check whether the name we got back for this type matches the extra specifications
    // that were in the name we're looking up:
    if (base_name_start != partial_name || *base_name_end != '\0')
    {
        // First see if the stuff to the left matches the full name.  To do that let's see if
        // we can pull out the mips linkage name attribute:
        
        Mangled best_name;
        DWARFDebugInfoEntry::Attributes attributes;
        DWARFFormValue form_value;
        die->GetAttributes(this, dwarf_cu, NULL, attributes);
        uint32_t idx = attributes.FindAttributeIndex(DW_AT_MIPS_linkage_name);
        if (idx == UINT32_MAX)
            idx = attributes.FindAttributeIndex(DW_AT_linkage_name);
        if (idx != UINT32_MAX)
        {
            if (attributes.ExtractFormValueAtIndex(this, idx, form_value))
            {
                const char *mangled_name = form_value.AsCString(&get_debug_str_data());
                if (mangled_name)
                    best_name.SetValue (ConstString(mangled_name), true);
            }
        }

        if (!best_name)
        {
            idx = attributes.FindAttributeIndex(DW_AT_name);
            if (idx != UINT32_MAX && attributes.ExtractFormValueAtIndex(this, idx, form_value))
            {
                const char *name = form_value.AsCString(&get_debug_str_data());
                best_name.SetValue (ConstString(name), false);
            }
        }

        const LanguageType cu_language = const_cast<DWARFCompileUnit *>(dwarf_cu)->GetLanguageType();
        if (best_name.GetDemangledName(cu_language))
        {
            const char *demangled = best_name.GetDemangledName(cu_language).GetCString();
            if (demangled)
            {
                std::string name_no_parens(partial_name, base_name_end - partial_name);
                const char *partial_in_demangled = strstr (demangled, name_no_parens.c_str());
                if (partial_in_demangled == NULL)
                    return false;
                else
                {
                    // Sort out the case where our name is something like "Process::Destroy" and the match is
                    // "SBProcess::Destroy" - that shouldn't be a match.  We should really always match on
                    // namespace boundaries...
                    
                    if (partial_name[0] == ':'  && partial_name[1] == ':')
                    {
                        // The partial name was already on a namespace boundary so all matches are good.
                        return true;
                    }
                    else if (partial_in_demangled == demangled)
                    {
                        // They both start the same, so this is an good match.
                        return true;
                    }
                    else
                    {
                        if (partial_in_demangled - demangled == 1)
                        {
                            // Only one character difference, can't be a namespace boundary...
                            return false;
                        }
                        else if (*(partial_in_demangled - 1) == ':' && *(partial_in_demangled - 2) == ':')
                        {
                            // We are on a namespace boundary, so this is also good.
                            return true;
                        }
                        else
                            return false;
                    }
                }
            }
        }
    }
    
    return true;
}

uint32_t
SymbolFileDWARF::FindFunctions (const ConstString &name, 
                                const lldb_private::ClangNamespaceDecl *namespace_decl, 
                                uint32_t name_type_mask,
                                bool include_inlines,
                                bool append, 
                                SymbolContextList& sc_list)
{
    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "SymbolFileDWARF::FindFunctions (name = '%s')",
                        name.AsCString());

    // eFunctionNameTypeAuto should be pre-resolved by a call to Module::PrepareForFunctionNameLookup()
    assert ((name_type_mask & eFunctionNameTypeAuto) == 0);

    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
    
    if (log)
    {
        GetObjectFile()->GetModule()->LogMessage (log,
                                                  "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list)", 
                                                  name.GetCString(), 
                                                  name_type_mask, 
                                                  append);
    }

    // If we aren't appending the results to this list, then clear the list
    if (!append)
        sc_list.Clear();
    
    if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
        return 0;
        
    // If name is empty then we won't find anything.
    if (name.IsEmpty())
        return 0;

    // Remember how many sc_list are in the list before we search in case
    // we are appending the results to a variable list.

    const char *name_cstr = name.GetCString();

    const uint32_t original_size = sc_list.GetSize();
   
    DWARFDebugInfo* info = DebugInfo();
    if (info == NULL)
        return 0;

    DWARFCompileUnit *dwarf_cu = NULL;
    std::set<const DWARFDebugInfoEntry *> resolved_dies;
    if (m_using_apple_tables)
    {
        if (m_apple_names_ap.get())
        {

            DIEArray die_offsets;

            uint32_t num_matches = 0;
                
            if (name_type_mask & eFunctionNameTypeFull)
            {
                // If they asked for the full name, match what they typed.  At some point we may
                // want to canonicalize this (strip double spaces, etc.  For now, we just add all the
                // dies that we find by exact match.
                num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
                for (uint32_t i = 0; i < num_matches; i++)
                {
                    const dw_offset_t die_offset = die_offsets[i];
                    const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
                    if (die)
                    {
                        if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
                            continue;
                        
                        if (resolved_dies.find(die) == resolved_dies.end())
                        {
                            if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
                                resolved_dies.insert(die);
                        }
                    }
                    else
                    {
                        GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')", 
                                                                                   die_offset, name_cstr);
                    }                                    
                }
            }

            if (name_type_mask & eFunctionNameTypeSelector)
            {
                if (namespace_decl && *namespace_decl)
                    return 0; // no selectors in namespaces
                    
                num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
                // Now make sure these are actually ObjC methods.  In this case we can simply look up the name,
                // and if it is an ObjC method name, we're good.
                
                for (uint32_t i = 0; i < num_matches; i++)
                {
                    const dw_offset_t die_offset = die_offsets[i];
                    const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
                    if (die)
                    {
                        const char *die_name = die->GetName(this, dwarf_cu);
                        if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name))
                        {
                            if (resolved_dies.find(die) == resolved_dies.end())
                            {
                                if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
                                    resolved_dies.insert(die);
                            }
                        }
                    }
                    else
                    {
                        GetObjectFile()->GetModule()->ReportError ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
                                                                   die_offset, name_cstr);
                    }                                    
                }
                die_offsets.clear();
            }
            
            if (((name_type_mask & eFunctionNameTypeMethod) && !namespace_decl) || name_type_mask & eFunctionNameTypeBase)
            {
                // The apple_names table stores just the "base name" of C++ methods in the table.  So we have to
                // extract the base name, look that up, and if there is any other information in the name we were
                // passed in we have to post-filter based on that.
                
                // FIXME: Arrange the logic above so that we don't calculate the base name twice:
                num_matches = m_apple_names_ap->FindByName (name_cstr, die_offsets);
                
                for (uint32_t i = 0; i < num_matches; i++)
                {
                    const dw_offset_t die_offset = die_offsets[i];
                    const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
                    if (die)
                    {
                        if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
                            continue;

                        // If we get to here, the die is good, and we should add it:
                        if (resolved_dies.find(die) == resolved_dies.end())
                        if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
                        {
                            bool keep_die = true;
                            if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod))
                            {
                                // We are looking for either basenames or methods, so we need to
                                // trim out the ones we won't want by looking at the type
                                SymbolContext sc;
                                if (sc_list.GetLastContext(sc))
                                {
                                    if (sc.block)
                                    {
                                        // We have an inlined function
                                    }
                                    else if (sc.function)
                                    {
                                        Type *type = sc.function->GetType();
                                        
                                        if (type)
                                        {
                                            clang::DeclContext* decl_ctx = GetClangDeclContextContainingTypeUID (type->GetID());
                                            if (decl_ctx->isRecord())
                                            {
                                                if (name_type_mask & eFunctionNameTypeBase)
                                                {
                                                    sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
                                                    keep_die = false;
                                                }
                                            }
                                            else
                                            {
                                                if (name_type_mask & eFunctionNameTypeMethod)
                                                {
                                                    sc_list.RemoveContextAtIndex(sc_list.GetSize()-1);
                                                    keep_die = false;
                                                }
                                            }
                                        }
                                        else
                                        {
                                            GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
                                                                                         die_offset);
                                        }
                                    }
                                }
                            }
                            if (keep_die)
                                resolved_dies.insert(die);
                        }
                    }
                    else
                    {
                        GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x for '%s')",
                                                                                   die_offset, name_cstr);
                    }                                    
                }
                die_offsets.clear();
            }
        }
    }
    else
    {

        // Index the DWARF if we haven't already
        if (!m_indexed)
            Index ();

        if (name_type_mask & eFunctionNameTypeFull)
        {
            FindFunctions (name, m_function_fullname_index, include_inlines, sc_list);

            // FIXME Temporary workaround for global/anonymous namespace
            // functions debugging FreeBSD and Linux binaries.
            // If we didn't find any functions in the global namespace try
            // looking in the basename index but ignore any returned
            // functions that have a namespace but keep functions which
            // have an anonymous namespace
            // TODO: The arch in the object file isn't correct for MSVC
            // binaries on windows, we should find a way to make it
            // correct and handle those symbols as well.
            if (sc_list.GetSize() == 0)
            {
                ArchSpec arch;
                if (!namespace_decl &&
                    GetObjectFile()->GetArchitecture(arch) &&
                    (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() ||
                     arch.GetMachine() == llvm::Triple::hexagon))
                {
                    SymbolContextList temp_sc_list;
                    FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list);
                    SymbolContext sc;
                    for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++)
                    {
                        if (temp_sc_list.GetContextAtIndex(i, sc))
                        {
                            ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled);
                            ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled);
                            // Mangled names on Linux and FreeBSD are of the form:
                            // _ZN18function_namespace13function_nameEv.
                            if (strncmp(mangled_name.GetCString(), "_ZN", 3) ||
                                !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21))
                            {
                                sc_list.Append(sc);
                            }
                        }
                    }
                }
            }
        }
        DIEArray die_offsets;
        DWARFCompileUnit *dwarf_cu = NULL;
        
        if (name_type_mask & eFunctionNameTypeBase)
        {
            uint32_t num_base = m_function_basename_index.Find(name, die_offsets);
            for (uint32_t i = 0; i < num_base; i++)
            {
                const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
                if (die)
                {
                    if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
                        continue;
                    
                    // If we get to here, the die is good, and we should add it:
                    if (resolved_dies.find(die) == resolved_dies.end())
                    {
                        if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
                            resolved_dies.insert(die);
                    }
                }
            }
            die_offsets.clear();
        }
        
        if (name_type_mask & eFunctionNameTypeMethod)
        {
            if (namespace_decl && *namespace_decl)
                return 0; // no methods in namespaces

            uint32_t num_base = m_function_method_index.Find(name, die_offsets);
            {
                for (uint32_t i = 0; i < num_base; i++)
                {
                    const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu);
                    if (die)
                    {
                        // If we get to here, the die is good, and we should add it:
                        if (resolved_dies.find(die) == resolved_dies.end())
                        {
                            if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list))
                                resolved_dies.insert(die);
                        }
                    }
                }
            }
            die_offsets.clear();
        }

        if ((name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl))
        {
            FindFunctions (name, m_function_selector_index, include_inlines, sc_list);
        }
        
    }

    // Return the number of variable that were appended to the list
    const uint32_t num_matches = sc_list.GetSize() - original_size;
    
    if (log && num_matches > 0)
    {
        GetObjectFile()->GetModule()->LogMessage (log,
                                                  "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u",
                                                  name.GetCString(), 
                                                  name_type_mask, 
                                                  include_inlines,
                                                  append,
                                                  num_matches);
    }
    return num_matches;
}

uint32_t
SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list)
{
    Timer scoped_timer (__PRETTY_FUNCTION__,
                        "SymbolFileDWARF::FindFunctions (regex = '%s')",
                        regex.GetText());

    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
    
    if (log)
    {
        GetObjectFile()->GetModule()->LogMessage (log,
                                                  "SymbolFileDWARF::FindFunctions (regex=\"%s\", append=%u, sc_list)", 
                                                  regex.GetText(), 
                                                  append);
    }
    

    // If we aren't appending the results to this list, then clear the list
    if (!append)
        sc_list.Clear();

    // Remember how many sc_list are in the list before we search in case
    // we are appending the results to a variable list.
    uint32_t original_size = sc_list.GetSize();

    if (m_using_apple_tables)
    {
        if (m_apple_names_ap.get())
            FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list);
    }
    else
    {
        // Index the DWARF if we haven't already
        if (!m_indexed)
            Index ();

        FindFunctions (regex, m_function_basename_index, include_inlines, sc_list);

        FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list);
    }

    // Return the number of variable that were appended to the list
    return sc_list.GetSize() - original_size;
}

uint32_t
SymbolFileDWARF::FindTypes (const SymbolContext& sc, 
                            const ConstString &name, 
                            const lldb_private::ClangNamespaceDecl *namespace_decl, 
                            bool append, 
                            uint32_t max_matches, 
                            TypeList& types)
{
    DWARFDebugInfo* info = DebugInfo();
    if (info == NULL)
        return 0;

    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));

    if (log)
    {
        if (namespace_decl)
            GetObjectFile()->GetModule()->LogMessage (log,
                                                      "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list)", 
                                                      name.GetCString(),
                                                      static_cast<void*>(namespace_decl->GetNamespaceDecl()),
                                                      namespace_decl->GetQualifiedName().c_str(),
                                                      append, max_matches);
        else
            GetObjectFile()->GetModule()->LogMessage (log,
                                                      "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list)",
                                                      name.GetCString(), append,
                                                      max_matches);
    }

    // If we aren't appending the results to this list, then clear the list
    if (!append)
        types.Clear();

    if (!NamespaceDeclMatchesThisSymbolFile(namespace_decl))
        return 0;

    DIEArray die_offsets;

    if (m_using_apple_tables)
    {
        if (m_apple_types_ap.get())
        {
            const char *name_cstr = name.GetCString();
            m_apple_types_ap->FindByName (name_cstr, die_offsets);
        }
    }
    else
    {
        if (!m_indexed)
            Index ();

        m_type_index.Find (name, die_offsets);
    }

    const size_t num_die_matches = die_offsets.size();

    if (num_die_matches)
    {
        const uint32_t initial_types_size = types.GetSize();
        DWARFCompileUnit* dwarf_cu = NULL;
        const DWARFDebugInfoEntry* die = NULL;
        DWARFDebugInfo* debug_info = DebugInfo();
        for (size_t i=0; i<num_die_matches; ++i)
        {
            const dw_offset_t die_offset = die_offsets[i];
            die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);

            if (die)
            {
                if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die))
                    continue;

                Type *matching_type = ResolveType (dwarf_cu, die);
                if (matching_type)
                {
                    // We found a type pointer, now find the shared pointer form our type list
                    types.InsertUnique (matching_type->shared_from_this());
                    if (types.GetSize() >= max_matches)
                        break;
                }
            }
            else
            {
                if (m_using_apple_tables)
                {
                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
                                                                               die_offset, name.GetCString());
                }
            }            

        }
        const uint32_t num_matches = types.GetSize() - initial_types_size;
        if (log && num_matches)
        {
            if (namespace_decl)
            {
                GetObjectFile()->GetModule()->LogMessage (log,
                                                          "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(%p) \"%s\", append=%u, max_matches=%u, type_list) => %u", 
                                                          name.GetCString(),
                                                          static_cast<void*>(namespace_decl->GetNamespaceDecl()),
                                                          namespace_decl->GetQualifiedName().c_str(),
                                                          append, max_matches,
                                                          num_matches);
            }
            else
            {
                GetObjectFile()->GetModule()->LogMessage (log,
                                                          "SymbolFileDWARF::FindTypes (sc, name=\"%s\", clang::NamespaceDecl(NULL), append=%u, max_matches=%u, type_list) => %u",
                                                          name.GetCString(), 
                                                          append, max_matches,
                                                          num_matches);
            }
        }
        return num_matches;
    }
    return 0;
}


ClangNamespaceDecl
SymbolFileDWARF::FindNamespace (const SymbolContext& sc, 
                                const ConstString &name,
                                const lldb_private::ClangNamespaceDecl *parent_namespace_decl)
{
    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS));
    
    if (log)
    {
        GetObjectFile()->GetModule()->LogMessage (log,
                                                  "SymbolFileDWARF::FindNamespace (sc, name=\"%s\")", 
                                                  name.GetCString());
    }
    
    if (!NamespaceDeclMatchesThisSymbolFile(parent_namespace_decl))
        return ClangNamespaceDecl();

    ClangNamespaceDecl namespace_decl;
    DWARFDebugInfo* info = DebugInfo();
    if (info)
    {
        DIEArray die_offsets;

        // Index if we already haven't to make sure the compile units
        // get indexed and make their global DIE index list
        if (m_using_apple_tables)
        {
            if (m_apple_namespaces_ap.get())
            {
                const char *name_cstr = name.GetCString();
                m_apple_namespaces_ap->FindByName (name_cstr, die_offsets);
            }
        }
        else
        {
            if (!m_indexed)
                Index ();

            m_namespace_index.Find (name, die_offsets);
        }
        
        DWARFCompileUnit* dwarf_cu = NULL;
        const DWARFDebugInfoEntry* die = NULL;
        const size_t num_matches = die_offsets.size();
        if (num_matches)
        {
            DWARFDebugInfo* debug_info = DebugInfo();
            for (size_t i=0; i<num_matches; ++i)
            {
                const dw_offset_t die_offset = die_offsets[i];
                die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);
                
                if (die)
                {
                    if (parent_namespace_decl && !DIEIsInNamespace (parent_namespace_decl, dwarf_cu, die))
                        continue;

                    clang::NamespaceDecl *clang_namespace_decl = ResolveNamespaceDIE (dwarf_cu, die);
                    if (clang_namespace_decl)
                    {
                        namespace_decl.SetASTContext (GetClangASTContext().getASTContext());
                        namespace_decl.SetNamespaceDecl (clang_namespace_decl);
                        break;
                    }
                }
                else
                {
                    if (m_using_apple_tables)
                    {
                        GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_namespaces accelerator table had bad die 0x%8.8x for '%s')\n",
                                                                   die_offset, name.GetCString());
                    }
                }            

            }
        }
    }
    if (log && namespace_decl.GetNamespaceDecl())
    {
        GetObjectFile()->GetModule()->LogMessage (log,
                                                  "SymbolFileDWARF::FindNamespace (sc, name=\"%s\") => clang::NamespaceDecl(%p) \"%s\"",
                                                  name.GetCString(),
                                                  static_cast<const void*>(namespace_decl.GetNamespaceDecl()),
                                                  namespace_decl.GetQualifiedName().c_str());
    }

    return namespace_decl;
}

uint32_t
SymbolFileDWARF::FindTypes(std::vector<dw_offset_t> die_offsets, uint32_t max_matches, TypeList& types)
{
    // Remember how many sc_list are in the list before we search in case
    // we are appending the results to a variable list.
    uint32_t original_size = types.GetSize();

    const uint32_t num_die_offsets = die_offsets.size();
    // Parse all of the types we found from the pubtypes matches
    uint32_t i;
    uint32_t num_matches = 0;
    for (i = 0; i < num_die_offsets; ++i)
    {
        Type *matching_type = ResolveTypeUID (die_offsets[i]);
        if (matching_type)
        {
            // We found a type pointer, now find the shared pointer form our type list
            types.InsertUnique (matching_type->shared_from_this());
            ++num_matches;
            if (num_matches >= max_matches)
                break;
        }
    }

    // Return the number of variable that were appended to the list
    return types.GetSize() - original_size;
}


size_t
SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc,
                                       clang::DeclContext *containing_decl_ctx,
                                       DWARFCompileUnit* dwarf_cu,
                                       const DWARFDebugInfoEntry *parent_die,
                                       bool skip_artificial,
                                       bool &is_static,
                                       bool &is_variadic,
                                       std::vector<ClangASTType>& function_param_types,
                                       std::vector<clang::ParmVarDecl*>& function_param_decls,
                                       unsigned &type_quals) // ,
                                       // ClangASTContext::TemplateParameterInfos &template_param_infos))
{
    if (parent_die == NULL)
        return 0;

    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());

    size_t arg_idx = 0;
    const DWARFDebugInfoEntry *die;
    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
    {
        dw_tag_t tag = die->Tag();
        switch (tag)
        {
        case DW_TAG_formal_parameter:
            {
                DWARFDebugInfoEntry::Attributes attributes;
                const size_t num_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
                if (num_attributes > 0)
                {
                    const char *name = NULL;
                    Declaration decl;
                    dw_offset_t param_type_die_offset = DW_INVALID_OFFSET;
                    bool is_artificial = false;
                    // one of None, Auto, Register, Extern, Static, PrivateExtern

                    clang::StorageClass storage = clang::SC_None;
                    uint32_t i;
                    for (i=0; i<num_attributes; ++i)
                    {
                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
                        DWARFFormValue form_value;
                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                        {
                            switch (attr)
                            {
                            case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
                            case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
                            case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
                            case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
                            case DW_AT_type:        param_type_die_offset = form_value.Reference(); break;
                            case DW_AT_artificial:  is_artificial = form_value.Boolean(); break;
                            case DW_AT_location:
    //                          if (form_value.BlockData())
    //                          {
    //                              const DWARFDataExtractor& debug_info_data = debug_info();
    //                              uint32_t block_length = form_value.Unsigned();
    //                              DWARFDataExtractor location(debug_info_data, form_value.BlockData() - debug_info_data.GetDataStart(), block_length);
    //                          }
    //                          else
    //                          {
    //                          }
    //                          break;
                            case DW_AT_const_value:
                            case DW_AT_default_value:
                            case DW_AT_description:
                            case DW_AT_endianity:
                            case DW_AT_is_optional:
                            case DW_AT_segment:
                            case DW_AT_variable_parameter:
                            default:
                            case DW_AT_abstract_origin:
                            case DW_AT_sibling:
                                break;
                            }
                        }
                    }

                    bool skip = false;
                    if (skip_artificial)
                    {
                        if (is_artificial)
                        {
                            // In order to determine if a C++ member function is
                            // "const" we have to look at the const-ness of "this"...
                            // Ugly, but that
                            if (arg_idx == 0)
                            {
                                if (DeclKindIsCXXClass(containing_decl_ctx->getDeclKind()))
                                {                                    
                                    // Often times compilers omit the "this" name for the
                                    // specification DIEs, so we can't rely upon the name
                                    // being in the formal parameter DIE...
                                    if (name == NULL || ::strcmp(name, "this")==0)
                                    {
                                        Type *this_type = ResolveTypeUID (param_type_die_offset);
                                        if (this_type)
                                        {                              
                                            uint32_t encoding_mask = this_type->GetEncodingMask();
                                            if (encoding_mask & Type::eEncodingIsPointerUID)
                                            {
                                                is_static = false;
                                                
                                                if (encoding_mask & (1u << Type::eEncodingIsConstUID))
                                                    type_quals |= clang::Qualifiers::Const;
                                                if (encoding_mask & (1u << Type::eEncodingIsVolatileUID))
                                                    type_quals |= clang::Qualifiers::Volatile;
                                            }
                                        }
                                    }
                                }
                            }
                            skip = true;
                        }
                        else
                        {

                            // HACK: Objective C formal parameters "self" and "_cmd" 
                            // are not marked as artificial in the DWARF...
                            CompileUnit *comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu, UINT32_MAX);
                            if (comp_unit)
                            {
                                switch (comp_unit->GetLanguage())
                                {
                                    case eLanguageTypeObjC:
                                    case eLanguageTypeObjC_plus_plus:
                                        if (name && name[0] && (strcmp (name, "self") == 0 || strcmp (name, "_cmd") == 0))
                                            skip = true;
                                        break;
                                    default:
                                        break;
                                }
                            }
                        }
                    }

                    if (!skip)
                    {
                        Type *type = ResolveTypeUID(param_type_die_offset);
                        if (type)
                        {
                            function_param_types.push_back (type->GetClangForwardType());

                            clang::ParmVarDecl *param_var_decl = GetClangASTContext().CreateParameterDeclaration (name, 
                                                                                                                  type->GetClangForwardType(), 
                                                                                                                  storage);
                            assert(param_var_decl);
                            function_param_decls.push_back(param_var_decl);
                            
                            GetClangASTContext().SetMetadataAsUserID (param_var_decl, MakeUserID(die->GetOffset()));
                        }
                    }
                }
                arg_idx++;
            }
            break;

        case DW_TAG_unspecified_parameters:
            is_variadic = true;
            break;

        case DW_TAG_template_type_parameter:
        case DW_TAG_template_value_parameter:
            // The one caller of this was never using the template_param_infos,
            // and the local variable was taking up a large amount of stack space
            // in SymbolFileDWARF::ParseType() so this was removed. If we ever need
            // the template params back, we can add them back.
            // ParseTemplateDIE (dwarf_cu, die, template_param_infos);
            break;

        default:
            break;
        }
    }
    return arg_idx;
}

size_t
SymbolFileDWARF::ParseChildEnumerators
(
    const SymbolContext& sc,
    lldb_private::ClangASTType &clang_type,
    bool is_signed,
    uint32_t enumerator_byte_size,
    DWARFCompileUnit* dwarf_cu,
    const DWARFDebugInfoEntry *parent_die
)
{
    if (parent_die == NULL)
        return 0;

    size_t enumerators_added = 0;
    const DWARFDebugInfoEntry *die;
    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());

    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
    {
        const dw_tag_t tag = die->Tag();
        if (tag == DW_TAG_enumerator)
        {
            DWARFDebugInfoEntry::Attributes attributes;
            const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
            if (num_child_attributes > 0)
            {
                const char *name = NULL;
                bool got_value = false;
                int64_t enum_value = 0;
                Declaration decl;

                uint32_t i;
                for (i=0; i<num_child_attributes; ++i)
                {
                    const dw_attr_t attr = attributes.AttributeAtIndex(i);
                    DWARFFormValue form_value;
                    if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                    {
                        switch (attr)
                        {
                        case DW_AT_const_value:
                            got_value = true;
                            if (is_signed)
                                enum_value = form_value.Signed();
                            else
                                enum_value = form_value.Unsigned();
                            break;

                        case DW_AT_name:
                            name = form_value.AsCString(&get_debug_str_data());
                            break;

                        case DW_AT_description:
                        default:
                        case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
                        case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
                        case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
                        case DW_AT_sibling:
                            break;
                        }
                    }
                }

                if (name && name[0] && got_value)
                {
                    clang_type.AddEnumerationValueToEnumerationType (clang_type.GetEnumerationIntegerType(),
                                                                     decl,
                                                                     name,
                                                                     enum_value,
                                                                     enumerator_byte_size * 8);
                    ++enumerators_added;
                }
            }
        }
    }
    return enumerators_added;
}

void
SymbolFileDWARF::ParseChildArrayInfo
(
    const SymbolContext& sc,
    DWARFCompileUnit* dwarf_cu,
    const DWARFDebugInfoEntry *parent_die,
    int64_t& first_index,
    std::vector<uint64_t>& element_orders,
    uint32_t& byte_stride,
    uint32_t& bit_stride
)
{
    if (parent_die == NULL)
        return;

    const DWARFDebugInfoEntry *die;
    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (dwarf_cu->GetAddressByteSize(), dwarf_cu->IsDWARF64());
    for (die = parent_die->GetFirstChild(); die != NULL; die = die->GetSibling())
    {
        const dw_tag_t tag = die->Tag();
        switch (tag)
        {
        case DW_TAG_subrange_type:
            {
                DWARFDebugInfoEntry::Attributes attributes;
                const size_t num_child_attributes = die->GetAttributes(this, dwarf_cu, fixed_form_sizes, attributes);
                if (num_child_attributes > 0)
                {
                    uint64_t num_elements = 0;
                    uint64_t lower_bound = 0;
                    uint64_t upper_bound = 0;
                    bool upper_bound_valid = false;
                    uint32_t i;
                    for (i=0; i<num_child_attributes; ++i)
                    {
                        const dw_attr_t attr = attributes.AttributeAtIndex(i);
                        DWARFFormValue form_value;
                        if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                        {
                            switch (attr)
                            {
                            case DW_AT_name:
                                break;

                            case DW_AT_count:
                                num_elements = form_value.Unsigned();
                                break;

                            case DW_AT_bit_stride:
                                bit_stride = form_value.Unsigned();
                                break;

                            case DW_AT_byte_stride:
                                byte_stride = form_value.Unsigned();
                                break;

                            case DW_AT_lower_bound:
                                lower_bound = form_value.Unsigned();
                                break;

                            case DW_AT_upper_bound:
                                upper_bound_valid = true;
                                upper_bound = form_value.Unsigned();
                                break;

                            default:
                            case DW_AT_abstract_origin:
                            case DW_AT_accessibility:
                            case DW_AT_allocated:
                            case DW_AT_associated:
                            case DW_AT_data_location:
                            case DW_AT_declaration:
                            case DW_AT_description:
                            case DW_AT_sibling:
                            case DW_AT_threads_scaled:
                            case DW_AT_type:
                            case DW_AT_visibility:
                                break;
                            }
                        }
                    }

                    if (num_elements == 0)
                    {
                        if (upper_bound_valid && upper_bound >= lower_bound)
                            num_elements = upper_bound - lower_bound + 1;
                    }

                    element_orders.push_back (num_elements);
                }
            }
            break;
        }
    }
}

TypeSP
SymbolFileDWARF::GetTypeForDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfoEntry* die)
{
    TypeSP type_sp;
    if (die != NULL)
    {
        assert(dwarf_cu != NULL);
        Type *type_ptr = m_die_to_type.lookup (die);
        if (type_ptr == NULL)
        {
            CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(dwarf_cu);
            assert (lldb_cu);
            SymbolContext sc(lldb_cu);
            type_sp = ParseType(sc, dwarf_cu, die, NULL);
        }
        else if (type_ptr != DIE_IS_BEING_PARSED)
        {
            // Grab the existing type from the master types lists
            type_sp = type_ptr->shared_from_this();
        }

    }
    return type_sp;
}

clang::DeclContext *
SymbolFileDWARF::GetClangDeclContextContainingDIEOffset (dw_offset_t die_offset)
{
    if (die_offset != DW_INVALID_OFFSET)
    {
        DWARFCompileUnitSP cu_sp;
        const DWARFDebugInfoEntry* die = DebugInfo()->GetDIEPtr(die_offset, &cu_sp);
        return GetClangDeclContextContainingDIE (cu_sp.get(), die, NULL);
    }
    return NULL;
}

clang::DeclContext *
SymbolFileDWARF::GetClangDeclContextForDIEOffset (const SymbolContext &sc, dw_offset_t die_offset)
{
    if (die_offset != DW_INVALID_OFFSET)
    {
        DWARFDebugInfo* debug_info = DebugInfo();
        if (debug_info)
        {
            DWARFCompileUnitSP cu_sp;
            const DWARFDebugInfoEntry* die = debug_info->GetDIEPtr(die_offset, &cu_sp);
            if (die)
                return GetClangDeclContextForDIE (sc, cu_sp.get(), die);
        }
    }
    return NULL;
}

clang::NamespaceDecl *
SymbolFileDWARF::ResolveNamespaceDIE (DWARFCompileUnit *dwarf_cu, const DWARFDebugInfoEntry *die)
{
    if (die && die->Tag() == DW_TAG_namespace)
    {
        // See if we already parsed this namespace DIE and associated it with a
        // uniqued namespace declaration
        clang::NamespaceDecl *namespace_decl = static_cast<clang::NamespaceDecl *>(m_die_to_decl_ctx[die]);
        if (namespace_decl)
            return namespace_decl;
        else
        {
            const char *namespace_name = die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL);
            clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, NULL);
            namespace_decl = GetClangASTContext().GetUniqueNamespaceDeclaration (namespace_name, containing_decl_ctx);
            Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
            if (log)
            {
                if (namespace_name)
                {
                    GetObjectFile()->GetModule()->LogMessage (log,
                                                              "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace with DW_AT_name(\"%s\") => clang::NamespaceDecl *%p (original = %p)",
                                                              static_cast<void*>(GetClangASTContext().getASTContext()),
                                                              MakeUserID(die->GetOffset()),
                                                              namespace_name,
                                                              static_cast<void*>(namespace_decl),
                                                              static_cast<void*>(namespace_decl->getOriginalNamespace()));
                }
                else
                {
                    GetObjectFile()->GetModule()->LogMessage (log,
                                                              "ASTContext => %p: 0x%8.8" PRIx64 ": DW_TAG_namespace (anonymous) => clang::NamespaceDecl *%p (original = %p)",
                                                              static_cast<void*>(GetClangASTContext().getASTContext()),
                                                              MakeUserID(die->GetOffset()),
                                                              static_cast<void*>(namespace_decl),
                                                              static_cast<void*>(namespace_decl->getOriginalNamespace()));
                }
            }

            if (namespace_decl)
                LinkDeclContextToDIE((clang::DeclContext*)namespace_decl, die);
            return namespace_decl;
        }
    }
    return NULL;
}

clang::DeclContext *
SymbolFileDWARF::GetClangDeclContextForDIE (const SymbolContext &sc, DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
{
    clang::DeclContext *clang_decl_ctx = GetCachedClangDeclContextForDIE (die);
    if (clang_decl_ctx)
        return clang_decl_ctx;
    // If this DIE has a specification, or an abstract origin, then trace to those.
        
    dw_offset_t die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
    if (die_offset != DW_INVALID_OFFSET)
        return GetClangDeclContextForDIEOffset (sc, die_offset);
    
    die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
    if (die_offset != DW_INVALID_OFFSET)
        return GetClangDeclContextForDIEOffset (sc, die_offset);
    
    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
    if (log)
        GetObjectFile()->GetModule()->LogMessage(log, "SymbolFileDWARF::GetClangDeclContextForDIE (die = 0x%8.8x) %s '%s'", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), die->GetName(this, cu));
    // This is the DIE we want.  Parse it, then query our map.
    bool assert_not_being_parsed = true;
    ResolveTypeUID (cu, die, assert_not_being_parsed);    

    clang_decl_ctx = GetCachedClangDeclContextForDIE (die);

    return clang_decl_ctx;
}

clang::DeclContext *
SymbolFileDWARF::GetClangDeclContextContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, const DWARFDebugInfoEntry **decl_ctx_die_copy)
{
    if (m_clang_tu_decl == NULL)
        m_clang_tu_decl = GetClangASTContext().getASTContext()->getTranslationUnitDecl();

    const DWARFDebugInfoEntry *decl_ctx_die = GetDeclContextDIEContainingDIE (cu, die);

    if (decl_ctx_die_copy)
        *decl_ctx_die_copy = decl_ctx_die;
    
    if (decl_ctx_die)
    {

        DIEToDeclContextMap::iterator pos = m_die_to_decl_ctx.find (decl_ctx_die);
        if (pos != m_die_to_decl_ctx.end())
            return pos->second;

        switch (decl_ctx_die->Tag())
        {
        case DW_TAG_compile_unit:
            return m_clang_tu_decl;

        case DW_TAG_namespace:
            return ResolveNamespaceDIE (cu, decl_ctx_die);
            break;

        case DW_TAG_structure_type:
        case DW_TAG_union_type:
        case DW_TAG_class_type:
            {
                Type* type = ResolveType (cu, decl_ctx_die);
                if (type)
                {
                    clang::DeclContext *decl_ctx = type->GetClangForwardType().GetDeclContextForType ();
                    if (decl_ctx)
                    {
                        LinkDeclContextToDIE (decl_ctx, decl_ctx_die);
                        if (decl_ctx)
                            return decl_ctx;
                    }
                }
            }
            break;

        default:
            break;
        }
    }
    return m_clang_tu_decl;
}


const DWARFDebugInfoEntry *
SymbolFileDWARF::GetDeclContextDIEContainingDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die)
{
    if (cu && die)
    {
        const DWARFDebugInfoEntry * const decl_die = die;
    
        while (die != NULL)
        {
            // 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 (decl_die != die)
            {            
                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->GetAttributeValueAsReference(this, cu, DW_AT_specification, DW_INVALID_OFFSET);
            if (die_offset != DW_INVALID_OFFSET)
            {
                DWARFCompileUnit *spec_cu = cu;
                const DWARFDebugInfoEntry *spec_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &spec_cu);
                const DWARFDebugInfoEntry *spec_die_decl_ctx_die = GetDeclContextDIEContainingDIE (spec_cu, spec_die);
                if (spec_die_decl_ctx_die)
                    return spec_die_decl_ctx_die;
            }
            
            die_offset = die->GetAttributeValueAsReference(this, cu, DW_AT_abstract_origin, DW_INVALID_OFFSET);
            if (die_offset != DW_INVALID_OFFSET)
            {
                DWARFCompileUnit *abs_cu = cu;
                const DWARFDebugInfoEntry *abs_die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &abs_cu);
                const DWARFDebugInfoEntry *abs_die_decl_ctx_die = GetDeclContextDIEContainingDIE (abs_cu, abs_die);
                if (abs_die_decl_ctx_die)
                    return abs_die_decl_ctx_die;
            }
            
            die = die->GetParent();
        }
    }
    return NULL;
}


Symbol *
SymbolFileDWARF::GetObjCClassSymbol (const ConstString &objc_class_name)
{
    Symbol *objc_class_symbol = NULL;
    if (m_obj_file)
    {
        Symtab *symtab = m_obj_file->GetSymtab ();
        if (symtab)
        {
            objc_class_symbol = symtab->FindFirstSymbolWithNameAndType (objc_class_name, 
                                                                        eSymbolTypeObjCClass, 
                                                                        Symtab::eDebugNo, 
                                                                        Symtab::eVisibilityAny);
        }
    }
    return objc_class_symbol;
}

// Some compilers don't emit the DW_AT_APPLE_objc_complete_type attribute. If they don't
// then we can end up looking through all class types for a complete type and never find
// the full definition. We need to know if this attribute is supported, so we determine
// this here and cache th result. We also need to worry about the debug map DWARF file
// if we are doing darwin DWARF in .o file debugging.
bool
SymbolFileDWARF::Supports_DW_AT_APPLE_objc_complete_type (DWARFCompileUnit *cu)
{
    if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate)
    {
        m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo;
        if (cu && cu->Supports_DW_AT_APPLE_objc_complete_type())
            m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
        else
        {
            DWARFDebugInfo* debug_info = DebugInfo();
            const uint32_t num_compile_units = GetNumCompileUnits();
            for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
            {
                DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
                if (dwarf_cu != cu && dwarf_cu->Supports_DW_AT_APPLE_objc_complete_type())
                {
                    m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes;
                    break;
                }
            }
        }
        if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolNo && GetDebugMapSymfile ())
            return m_debug_map_symfile->Supports_DW_AT_APPLE_objc_complete_type (this);
    }
    return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes;
}

// This function can be used when a DIE is found that is a forward declaration
// DIE and we want to try and find a type that has the complete definition.
TypeSP
SymbolFileDWARF::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugInfoEntry *die, 
                                                       const ConstString &type_name,
                                                       bool must_be_implementation)
{
    
    TypeSP type_sp;
    
    if (!type_name || (must_be_implementation && !GetObjCClassSymbol (type_name)))
        return type_sp;
    
    DIEArray die_offsets;
    
    if (m_using_apple_tables)
    {
        if (m_apple_types_ap.get())
        {
            const char *name_cstr = type_name.GetCString();
            m_apple_types_ap->FindCompleteObjCClassByName (name_cstr, die_offsets, must_be_implementation);
        }
    }
    else
    {
        if (!m_indexed)
            Index ();
        
        m_type_index.Find (type_name, die_offsets);
    }
    
    const size_t num_matches = die_offsets.size();
    
    DWARFCompileUnit* type_cu = NULL;
    const DWARFDebugInfoEntry* type_die = NULL;
    if (num_matches)
    {
        DWARFDebugInfo* debug_info = DebugInfo();
        for (size_t i=0; i<num_matches; ++i)
        {
            const dw_offset_t die_offset = die_offsets[i];
            type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
            
            if (type_die)
            {
                bool try_resolving_type = false;
                
                // Don't try and resolve the DIE we are looking for with the DIE itself!
                if (type_die != die)
                {
                    switch (type_die->Tag())
                    {
                        case DW_TAG_class_type:
                        case DW_TAG_structure_type:
                            try_resolving_type = true;
                            break;
                        default:
                            break;
                    }
                }
                
                if (try_resolving_type)
                {
                    if (must_be_implementation && type_cu->Supports_DW_AT_APPLE_objc_complete_type())
                        try_resolving_type = type_die->GetAttributeValueAsUnsigned (this, type_cu, DW_AT_APPLE_objc_complete_type, 0);
                    
                    if (try_resolving_type)
                    {
                        Type *resolved_type = ResolveType (type_cu, type_die, false);
                        if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
                        {
                            DEBUG_PRINTF ("resolved 0x%8.8" PRIx64 " from %s to 0x%8.8" PRIx64 " (cu 0x%8.8" PRIx64 ")\n",
                                          MakeUserID(die->GetOffset()), 
                                          m_obj_file->GetFileSpec().GetFilename().AsCString("<Unknown>"),
                                          MakeUserID(type_die->GetOffset()), 
                                          MakeUserID(type_cu->GetOffset()));
                            
                            if (die)
                                m_die_to_type[die] = resolved_type;
                            type_sp = resolved_type->shared_from_this();
                            break;
                        }
                    }
                }
            }
            else
            {
                if (m_using_apple_tables)
                {
                    GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
                                                               die_offset, type_name.GetCString());
                }
            }            
            
        }
    }
    return type_sp;
}


//----------------------------------------------------------------------
// This function helps to ensure that the declaration contexts match for
// two different DIEs. Often times debug information will refer to a 
// forward declaration of a type (the equivalent of "struct my_struct;".
// There will often be a declaration of that type elsewhere that has the
// full definition. When we go looking for the full type "my_struct", we
// will find one or more matches in the accelerator tables and we will
// then need to make sure the type was in the same declaration context 
// as the original DIE. This function can efficiently compare two DIEs
// and will return true when the declaration context matches, and false
// when they don't. 
//----------------------------------------------------------------------
bool
SymbolFileDWARF::DIEDeclContextsMatch (DWARFCompileUnit* cu1, const DWARFDebugInfoEntry *die1,
                                       DWARFCompileUnit* cu2, const DWARFDebugInfoEntry *die2)
{
    if (die1 == die2)
        return true;

#if defined (LLDB_CONFIGURATION_DEBUG)
    // You can't and shouldn't call this function with a compile unit from
    // two different SymbolFileDWARF instances.
    assert (DebugInfo()->ContainsCompileUnit (cu1));
    assert (DebugInfo()->ContainsCompileUnit (cu2));
#endif

    DWARFDIECollection decl_ctx_1;
    DWARFDIECollection decl_ctx_2;
    //The declaration DIE stack is a stack of the declaration context 
    // DIEs all the way back to the compile unit. If a type "T" is
    // declared inside a class "B", and class "B" is declared inside
    // a class "A" and class "A" is in a namespace "lldb", and the
    // namespace is in a compile unit, there will be a stack of DIEs:
    //
    //   [0] DW_TAG_class_type for "B"
    //   [1] DW_TAG_class_type for "A"
    //   [2] DW_TAG_namespace  for "lldb"
    //   [3] DW_TAG_compile_unit for the source file.
    // 
    // We grab both contexts and make sure that everything matches 
    // all the way back to the compiler unit.
    
    // First lets grab the decl contexts for both DIEs
    die1->GetDeclContextDIEs (this, cu1, decl_ctx_1);
    die2->GetDeclContextDIEs (this, cu2, decl_ctx_2);
    // Make sure the context arrays have the same size, otherwise
    // we are done
    const size_t count1 = decl_ctx_1.Size();
    const size_t count2 = decl_ctx_2.Size();
    if (count1 != count2)
        return false;
    
    // Make sure the DW_TAG values match all the way back up the
    // compile unit. If they don't, then we are done.
    const DWARFDebugInfoEntry *decl_ctx_die1;
    const DWARFDebugInfoEntry *decl_ctx_die2;
    size_t i;
    for (i=0; i<count1; i++)
    {
        decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
        decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
        if (decl_ctx_die1->Tag() != decl_ctx_die2->Tag())
            return false;
    }
#if defined LLDB_CONFIGURATION_DEBUG

    // Make sure the top item in the decl context die array is always 
    // DW_TAG_compile_unit. If it isn't then something went wrong in
    // the DWARFDebugInfoEntry::GetDeclContextDIEs() function...
    assert (decl_ctx_1.GetDIEPtrAtIndex (count1 - 1)->Tag() == DW_TAG_compile_unit);

#endif
    // Always skip the compile unit when comparing by only iterating up to
    // "count - 1". Here we compare the names as we go. 
    for (i=0; i<count1 - 1; i++)
    {
        decl_ctx_die1 = decl_ctx_1.GetDIEPtrAtIndex (i);
        decl_ctx_die2 = decl_ctx_2.GetDIEPtrAtIndex (i);
        const char *name1 = decl_ctx_die1->GetName(this, cu1);
        const char *name2 = decl_ctx_die2->GetName(this, cu2);
        // If the string was from a DW_FORM_strp, then the pointer will often
        // be the same!
        if (name1 == name2)
            continue;

        // Name pointers are not equal, so only compare the strings
        // if both are not NULL.
        if (name1 && name2)
        {
            // If the strings don't compare, we are done...
            if (strcmp(name1, name2) != 0)
                return false;
        }
        else
        {
            // One name was NULL while the other wasn't
            return false;
        }
    }
    // We made it through all of the checks and the declaration contexts
    // are equal.
    return true;
}
                                          

TypeSP
SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &dwarf_decl_ctx)
{
    TypeSP type_sp;

    const uint32_t dwarf_decl_ctx_count = dwarf_decl_ctx.GetSize();
    if (dwarf_decl_ctx_count > 0)
    {
        const ConstString type_name(dwarf_decl_ctx[0].name);
        const dw_tag_t tag = dwarf_decl_ctx[0].tag;

        if (type_name)
        {
            Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION|DWARF_LOG_LOOKUPS));
            if (log)
            {
                GetObjectFile()->GetModule()->LogMessage (log,
                                                          "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s')",
                                                          DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
                                                          dwarf_decl_ctx.GetQualifiedName());
            }
            
            DIEArray die_offsets;
            
            if (m_using_apple_tables)
            {
                if (m_apple_types_ap.get())
                {
                    const bool has_tag = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeTag);
                    const bool has_qualified_name_hash = m_apple_types_ap->GetHeader().header_data.ContainsAtom (DWARFMappedHash::eAtomTypeQualNameHash);
                    if (has_tag && has_qualified_name_hash)
                    {
                        const char *qualified_name = dwarf_decl_ctx.GetQualifiedName();
                        const uint32_t qualified_name_hash = MappedHash::HashStringUsingDJB (qualified_name);
                        if (log)
                            GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTagAndQualifiedNameHash()");
                        m_apple_types_ap->FindByNameAndTagAndQualifiedNameHash (type_name.GetCString(), tag, qualified_name_hash, die_offsets);
                    }
                    else if (has_tag)
                    {
                        if (log)
                            GetObjectFile()->GetModule()->LogMessage (log,"FindByNameAndTag()");
                        m_apple_types_ap->FindByNameAndTag (type_name.GetCString(), tag, die_offsets);
                    }
                    else
                    {
                        m_apple_types_ap->FindByName (type_name.GetCString(), die_offsets);
                    }
                }
            }
            else
            {
                if (!m_indexed)
                    Index ();
                
                m_type_index.Find (type_name, die_offsets);
            }
            
            const size_t num_matches = die_offsets.size();
            
            
            DWARFCompileUnit* type_cu = NULL;
            const DWARFDebugInfoEntry* type_die = NULL;
            if (num_matches)
            {
                DWARFDebugInfo* debug_info = DebugInfo();
                for (size_t i=0; i<num_matches; ++i)
                {
                    const dw_offset_t die_offset = die_offsets[i];
                    type_die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &type_cu);
                    
                    if (type_die)
                    {
                        bool try_resolving_type = false;
                        
                        // Don't try and resolve the DIE we are looking for with the DIE itself!
                        const dw_tag_t type_tag = type_die->Tag();
                        // Make sure the tags match
                        if (type_tag == tag)
                        {
                            // The tags match, lets try resolving this type
                            try_resolving_type = true;
                        }
                        else
                        {
                            // The tags don't match, but we need to watch our for a
                            // forward declaration for a struct and ("struct foo")
                            // ends up being a class ("class foo { ... };") or
                            // vice versa.
                            switch (type_tag)
                            {
                                case DW_TAG_class_type:
                                    // We had a "class foo", see if we ended up with a "struct foo { ... };"
                                    try_resolving_type = (tag == DW_TAG_structure_type);
                                    break;
                                case DW_TAG_structure_type:
                                    // We had a "struct foo", see if we ended up with a "class foo { ... };"
                                    try_resolving_type = (tag == DW_TAG_class_type);
                                    break;
                                default:
                                    // Tags don't match, don't event try to resolve
                                    // using this type whose name matches....
                                    break;
                            }
                        }
                        
                        if (try_resolving_type)
                        {
                            DWARFDeclContext type_dwarf_decl_ctx;
                            type_die->GetDWARFDeclContext (this, type_cu, type_dwarf_decl_ctx);

                            if (log)
                            {
                                GetObjectFile()->GetModule()->LogMessage (log,
                                                                          "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') trying die=0x%8.8x (%s)",
                                                                          DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
                                                                          dwarf_decl_ctx.GetQualifiedName(),
                                                                          type_die->GetOffset(),
                                                                          type_dwarf_decl_ctx.GetQualifiedName());
                            }
                            
                            // Make sure the decl contexts match all the way up
                            if (dwarf_decl_ctx == type_dwarf_decl_ctx)
                            {
                                Type *resolved_type = ResolveType (type_cu, type_die, false);
                                if (resolved_type && resolved_type != DIE_IS_BEING_PARSED)
                                {
                                    type_sp = resolved_type->shared_from_this();
                                    break;
                                }
                            }
                        }
                        else
                        {
                            if (log)
                            {
                                std::string qualified_name;
                                type_die->GetQualifiedName(this, type_cu, qualified_name);
                                GetObjectFile()->GetModule()->LogMessage (log,
                                                                          "SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(tag=%s, qualified-name='%s') ignoring die=0x%8.8x (%s)",
                                                                          DW_TAG_value_to_name(dwarf_decl_ctx[0].tag),
                                                                          dwarf_decl_ctx.GetQualifiedName(),
                                                                          type_die->GetOffset(),
                                                                          qualified_name.c_str());
                            }
                        }
                    }
                    else
                    {
                        if (m_using_apple_tables)
                        {
                            GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_types accelerator table had bad die 0x%8.8x for '%s')\n",
                                                                                       die_offset, type_name.GetCString());
                        }
                    }            
                    
                }
            }
        }
    }
    return type_sp;
}

bool
SymbolFileDWARF::CopyUniqueClassMethodTypes (SymbolFileDWARF *src_symfile,
                                             Type *class_type,
                                             DWARFCompileUnit* src_cu,
                                             const DWARFDebugInfoEntry *src_class_die,
                                             DWARFCompileUnit* dst_cu,
                                             const DWARFDebugInfoEntry *dst_class_die,
                                             DWARFDIECollection &failures)
{
    if (!class_type || !src_cu || !src_class_die || !dst_cu || !dst_class_die)
        return false;
    if (src_class_die->Tag() != dst_class_die->Tag())
        return false;
    
    // We need to complete the class type so we can get all of the method types
    // parsed so we can then unique those types to their equivalent counterparts
    // in "dst_cu" and "dst_class_die"
    class_type->GetClangFullType();

    const DWARFDebugInfoEntry *src_die;
    const DWARFDebugInfoEntry *dst_die;
    UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die;
    UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die;
    UniqueCStringMap<const DWARFDebugInfoEntry *> src_name_to_die_artificial;
    UniqueCStringMap<const DWARFDebugInfoEntry *> dst_name_to_die_artificial;
    for (src_die = src_class_die->GetFirstChild(); src_die != NULL; src_die = src_die->GetSibling())
    {
        if (src_die->Tag() == DW_TAG_subprogram)
        {
            // Make sure this is a declaration and not a concrete instance by looking
            // for DW_AT_declaration set to 1. Sometimes concrete function instances
            // are placed inside the class definitions and shouldn't be included in
            // the list of things are are tracking here.
            if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_declaration, 0) == 1)
            {
                const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
                if (src_name)
                {
                    ConstString src_const_name(src_name);
                    if (src_die->GetAttributeValueAsUnsigned(src_symfile, src_cu, DW_AT_artificial, 0))
                        src_name_to_die_artificial.Append(src_const_name.GetCString(), src_die);
                    else
                        src_name_to_die.Append(src_const_name.GetCString(), src_die);
                }
            }
        }
    }
    for (dst_die = dst_class_die->GetFirstChild(); dst_die != NULL; dst_die = dst_die->GetSibling())
    {
        if (dst_die->Tag() == DW_TAG_subprogram)
        {
            // Make sure this is a declaration and not a concrete instance by looking
            // for DW_AT_declaration set to 1. Sometimes concrete function instances
            // are placed inside the class definitions and shouldn't be included in
            // the list of things are are tracking here.
            if (dst_die->GetAttributeValueAsUnsigned(this, dst_cu, DW_AT_declaration, 0) == 1)
            {
                const char *dst_name = dst_die->GetMangledName (this, dst_cu);
                if (dst_name)
                {
                    ConstString dst_const_name(dst_name);
                    if (dst_die->GetAttributeValueAsUnsigned(this, dst_cu, DW_AT_artificial, 0))
                        dst_name_to_die_artificial.Append(dst_const_name.GetCString(), dst_die);
                    else
                        dst_name_to_die.Append(dst_const_name.GetCString(), dst_die);
                }
            }
        }
    }
    const uint32_t src_size = src_name_to_die.GetSize ();
    const uint32_t dst_size = dst_name_to_die.GetSize ();
    Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO | DWARF_LOG_TYPE_COMPLETION));

    // Is everything kosher so we can go through the members at top speed?
    bool fast_path = true;

    if (src_size != dst_size)
    {
        if (src_size != 0 && dst_size != 0)
        {
            if (log)
                log->Printf("warning: trying to unique class DIE 0x%8.8x to 0x%8.8x, but they didn't have the same size (src=%d, dst=%d)",
                            src_class_die->GetOffset(),
                            dst_class_die->GetOffset(),
                            src_size,
                            dst_size);
        }

        fast_path = false;
    }

    uint32_t idx;

    if (fast_path)
    {
        for (idx = 0; idx < src_size; ++idx)
        {
            src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
            dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);

            if (src_die->Tag() != dst_die->Tag())
            {
                if (log)
                    log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) tags didn't match 0x%8.8x (%s)",
                                src_class_die->GetOffset(),
                                dst_class_die->GetOffset(),
                                src_die->GetOffset(),
                                DW_TAG_value_to_name(src_die->Tag()),
                                dst_die->GetOffset(),
                                DW_TAG_value_to_name(src_die->Tag()));
                fast_path = false;
            }

            const char *src_name = src_die->GetMangledName (src_symfile, src_cu);
            const char *dst_name = dst_die->GetMangledName (this, dst_cu);

            // Make sure the names match
            if (src_name == dst_name || (strcmp (src_name, dst_name) == 0))
                continue;

            if (log)
                log->Printf("warning: tried to unique class DIE 0x%8.8x to 0x%8.8x, but 0x%8.8x (%s) names didn't match 0x%8.8x (%s)",
                            src_class_die->GetOffset(),
                            dst_class_die->GetOffset(),
                            src_die->GetOffset(),
                            src_name,
                            dst_die->GetOffset(),
                            dst_name);

            fast_path = false;
        }
    }

    // Now do the work of linking the DeclContexts and Types.
    if (fast_path)
    {
        // We can do this quickly.  Just run across the tables index-for-index since
        // we know each node has matching names and tags.
        for (idx = 0; idx < src_size; ++idx)
        {
            src_die = src_name_to_die.GetValueAtIndexUnchecked (idx);
            dst_die = dst_name_to_die.GetValueAtIndexUnchecked (idx);

            clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
            if (src_decl_ctx)
            {
                if (log)
                    log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
                                 static_cast<void*>(src_decl_ctx),
                                 src_die->GetOffset(), dst_die->GetOffset());
                LinkDeclContextToDIE (src_decl_ctx, dst_die);
            }
            else
            {
                if (log)
                    log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found",
                                 src_die->GetOffset(), dst_die->GetOffset());
            }

            Type *src_child_type = m_die_to_type[src_die];
            if (src_child_type)
            {
                if (log)
                    log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
                                 static_cast<void*>(src_child_type),
                                 src_child_type->GetID(),
                                 src_die->GetOffset(), dst_die->GetOffset());
                m_die_to_type[dst_die] = src_child_type;
            }
            else
            {
                if (log)
                    log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
            }
        }
    }
    else
    {
        // We must do this slowly.  For each member of the destination, look
        // up a member in the source with the same name, check its tag, and
        // unique them if everything matches up.  Report failures.

        if (!src_name_to_die.IsEmpty() && !dst_name_to_die.IsEmpty())
        {
            src_name_to_die.Sort();

            for (idx = 0; idx < dst_size; ++idx)
            {
                const char *dst_name = dst_name_to_die.GetCStringAtIndex(idx);
                dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx);
                src_die = src_name_to_die.Find(dst_name, NULL);

                if (src_die && (src_die->Tag() == dst_die->Tag()))
                {
                    clang::DeclContext *src_decl_ctx = src_symfile->m_die_to_decl_ctx[src_die];
                    if (src_decl_ctx)
                    {
                        if (log)
                            log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
                                         static_cast<void*>(src_decl_ctx),
                                         src_die->GetOffset(),
                                         dst_die->GetOffset());
                        LinkDeclContextToDIE (src_decl_ctx, dst_die);
                    }
                    else
                    {
                        if (log)
                            log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
                    }

                    Type *src_child_type = m_die_to_type[src_die];
                    if (src_child_type)
                    {
                        if (log)
                            log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
                                         static_cast<void*>(src_child_type),
                                         src_child_type->GetID(),
                                         src_die->GetOffset(),
                                         dst_die->GetOffset());
                        m_die_to_type[dst_die] = src_child_type;
                    }
                    else
                    {
                        if (log)
                            log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
                    }
                }
                else
                {
                    if (log)
                        log->Printf ("warning: couldn't find a match for 0x%8.8x", dst_die->GetOffset());

                    failures.Append(dst_die);
                }
            }
        }
    }
    
    const uint32_t src_size_artificial = src_name_to_die_artificial.GetSize ();
    const uint32_t dst_size_artificial = dst_name_to_die_artificial.GetSize ();
    
    UniqueCStringMap<const DWARFDebugInfoEntry *> name_to_die_artificial_not_in_src;

    if (src_size_artificial && dst_size_artificial)
    {
        dst_name_to_die_artificial.Sort();

        for (idx = 0; idx < src_size_artificial; ++idx)
        {
            const char *src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx);
            src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
            dst_die = dst_name_to_die_artificial.Find(src_name_artificial, NULL);

            if (dst_die)
            {
                // Both classes have the artificial types, link them
                clang::DeclContext *src_decl_ctx = m_die_to_decl_ctx[src_die];
                if (src_decl_ctx)
                {
                    if (log)
                        log->Printf ("uniquing decl context %p from 0x%8.8x for 0x%8.8x",
                                     static_cast<void*>(src_decl_ctx),
                                     src_die->GetOffset(), dst_die->GetOffset());
                    LinkDeclContextToDIE (src_decl_ctx, dst_die);
                }
                else
                {
                    if (log)
                        log->Printf ("warning: tried to unique decl context from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
                }

                Type *src_child_type = m_die_to_type[src_die];
                if (src_child_type)
                {
                    if (log)
                        log->Printf ("uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
                                     static_cast<void*>(src_child_type),
                                     src_child_type->GetID(),
                                     src_die->GetOffset(), dst_die->GetOffset());
                    m_die_to_type[dst_die] = src_child_type;
                }
                else
                {
                    if (log)
                        log->Printf ("warning: tried to unique lldb_private::Type from 0x%8.8x for 0x%8.8x, but none was found", src_die->GetOffset(), dst_die->GetOffset());
                }
            }
        }
    }

    if (dst_size_artificial)
    {
        for (idx = 0; idx < dst_size_artificial; ++idx)
        {
            const char *dst_name_artificial = dst_name_to_die_artificial.GetCStringAtIndex(idx);
            dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked (idx);
            if (log)
                log->Printf ("warning: need to create artificial method for 0x%8.8x for method '%s'", dst_die->GetOffset(), dst_name_artificial);
            
            failures.Append(dst_die);
        }
    }

    return (failures.Size() != 0);
}

TypeSP
SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEntry *die, bool *type_is_new_ptr)
{
    TypeSP type_sp;

    if (type_is_new_ptr)
        *type_is_new_ptr = false;

#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
    static DIEStack g_die_stack;
    DIEStack::ScopedPopper scoped_die_logger(g_die_stack);
#endif

    AccessType accessibility = eAccessNone;
    if (die != NULL)
    {
        Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
        if (log)
        {
            const DWARFDebugInfoEntry *context_die;
            clang::DeclContext *context = GetClangDeclContextContainingDIE (dwarf_cu, die, &context_die);

            GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x, decl_ctx = %p (die 0x%8.8x)) %s name = '%s')",
                                                      die->GetOffset(),
                                                      static_cast<void*>(context),
                                                      context_die->GetOffset(),
                                                      DW_TAG_value_to_name(die->Tag()),
                                                      die->GetName(this, dwarf_cu));

#if defined(LLDB_CONFIGURATION_DEBUG) || defined(LLDB_CONFIGURATION_RELEASE)
            scoped_die_logger.Push (dwarf_cu, die);
            g_die_stack.LogDIEs(log, this);
#endif
        }
//
//        Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
//        if (log && dwarf_cu)
//        {
//            StreamString s;
//            die->DumpLocation (this, dwarf_cu, s);
//            GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDwarf::%s %s", __FUNCTION__, s.GetData());
//            
//        }

        Type *type_ptr = m_die_to_type.lookup (die);
        TypeList* type_list = GetTypeList();
        if (type_ptr == NULL)
        {
            ClangASTContext &ast = GetClangASTContext();
            if (type_is_new_ptr)
                *type_is_new_ptr = true;

            const dw_tag_t tag = die->Tag();

            bool is_forward_declaration = false;
            DWARFDebugInfoEntry::Attributes attributes;
            const char *type_name_cstr = NULL;
            ConstString type_name_const_str;
            Type::ResolveState resolve_state = Type::eResolveStateUnresolved;
            uint64_t byte_size = 0;
            Declaration decl;

            Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
            ClangASTType clang_type;
            DWARFFormValue form_value;
            
            dw_attr_t attr;

            switch (tag)
            {
            case DW_TAG_base_type:
            case DW_TAG_pointer_type:
            case DW_TAG_reference_type:
            case DW_TAG_rvalue_reference_type:
            case DW_TAG_typedef:
            case DW_TAG_const_type:
            case DW_TAG_restrict_type:
            case DW_TAG_volatile_type:
            case DW_TAG_unspecified_type:
                {
                    // Set a bit that lets us know that we are currently parsing this
                    m_die_to_type[die] = DIE_IS_BEING_PARSED;

                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
                    uint32_t encoding = 0;
                    lldb::user_id_t encoding_uid = LLDB_INVALID_UID;

                    if (num_attributes > 0)
                    {
                        uint32_t i;
                        for (i=0; i<num_attributes; ++i)
                        {
                            attr = attributes.AttributeAtIndex(i);
                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                            {
                                switch (attr)
                                {
                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
                                case DW_AT_name:

                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
                                    // Work around a bug in llvm-gcc where they give a name to a reference type which doesn't
                                    // include the "&"...
                                    if (tag == DW_TAG_reference_type)
                                    {
                                        if (strchr (type_name_cstr, '&') == NULL)
                                            type_name_cstr = NULL;
                                    }
                                    if (type_name_cstr)
                                        type_name_const_str.SetCString(type_name_cstr);
                                    break;
                                case DW_AT_byte_size:   byte_size = form_value.Unsigned(); break;
                                case DW_AT_encoding:    encoding = form_value.Unsigned(); break;
                                case DW_AT_type:        encoding_uid = form_value.Reference(); break;
                                default:
                                case DW_AT_sibling:
                                    break;
                                }
                            }
                        }
                    }

                    DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr, encoding_uid);

                    switch (tag)
                    {
                    default:
                        break;

                    case DW_TAG_unspecified_type:
                        if (strcmp(type_name_cstr, "nullptr_t") == 0 ||
                            strcmp(type_name_cstr, "decltype(nullptr)") == 0 )
                        {
                            resolve_state = Type::eResolveStateFull;
                            clang_type = ast.GetBasicType(eBasicTypeNullPtr);
                            break;
                        }
                        // Fall through to base type below in case we can handle the type there...

                    case DW_TAG_base_type:
                        resolve_state = Type::eResolveStateFull;
                        clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (type_name_cstr, 
                                                                                   encoding, 
                                                                                   byte_size * 8);
                        break;

                    case DW_TAG_pointer_type:           encoding_data_type = Type::eEncodingIsPointerUID;           break;
                    case DW_TAG_reference_type:         encoding_data_type = Type::eEncodingIsLValueReferenceUID;   break;
                    case DW_TAG_rvalue_reference_type:  encoding_data_type = Type::eEncodingIsRValueReferenceUID;   break;
                    case DW_TAG_typedef:                encoding_data_type = Type::eEncodingIsTypedefUID;           break;
                    case DW_TAG_const_type:             encoding_data_type = Type::eEncodingIsConstUID;             break;
                    case DW_TAG_restrict_type:          encoding_data_type = Type::eEncodingIsRestrictUID;          break;
                    case DW_TAG_volatile_type:          encoding_data_type = Type::eEncodingIsVolatileUID;          break;
                    }

                    if (!clang_type && (encoding_data_type == Type::eEncodingIsPointerUID || encoding_data_type == Type::eEncodingIsTypedefUID) && sc.comp_unit != NULL)
                    {
                        bool translation_unit_is_objc = (sc.comp_unit->GetLanguage() == eLanguageTypeObjC || sc.comp_unit->GetLanguage() == eLanguageTypeObjC_plus_plus);

                        if (translation_unit_is_objc)
                        {
                            if (type_name_cstr != NULL)
                            {
                                static ConstString g_objc_type_name_id("id");
                                static ConstString g_objc_type_name_Class("Class");
                                static ConstString g_objc_type_name_selector("SEL");

                                if (type_name_const_str == g_objc_type_name_id)
                                {
                                    if (log)
                                        GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'id' built-in type.",
                                                                                  die->GetOffset(), 
                                                                                  DW_TAG_value_to_name(die->Tag()), 
                                                                                  die->GetName(this, dwarf_cu));
                                    clang_type = ast.GetBasicType(eBasicTypeObjCID);
                                    encoding_data_type = Type::eEncodingIsUID;
                                    encoding_uid = LLDB_INVALID_UID;
                                    resolve_state = Type::eResolveStateFull;

                                }
                                else if (type_name_const_str == g_objc_type_name_Class)
                                {
                                    if (log)
                                        GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'Class' built-in type.",
                                                                                  die->GetOffset(), 
                                                                                  DW_TAG_value_to_name(die->Tag()), 
                                                                                  die->GetName(this, dwarf_cu));
                                    clang_type = ast.GetBasicType(eBasicTypeObjCClass);
                                    encoding_data_type = Type::eEncodingIsUID;
                                    encoding_uid = LLDB_INVALID_UID;
                                    resolve_state = Type::eResolveStateFull;
                                }
                                else if (type_name_const_str == g_objc_type_name_selector)
                                {
                                    if (log)
                                        GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is Objective C 'selector' built-in type.",
                                                                                  die->GetOffset(), 
                                                                                  DW_TAG_value_to_name(die->Tag()), 
                                                                                  die->GetName(this, dwarf_cu));
                                    clang_type = ast.GetBasicType(eBasicTypeObjCSel);
                                    encoding_data_type = Type::eEncodingIsUID;
                                    encoding_uid = LLDB_INVALID_UID;
                                    resolve_state = Type::eResolveStateFull;
                                }
                            }
                            else if (encoding_data_type == Type::eEncodingIsPointerUID && encoding_uid != LLDB_INVALID_UID)
                            {
                                // Clang sometimes erroneously emits id as objc_object*.  In that case we fix up the type to "id".

                                DWARFDebugInfoEntry* encoding_die = dwarf_cu->GetDIEPtr(encoding_uid);

                                if (encoding_die && encoding_die->Tag() == DW_TAG_structure_type)
                                {
                                    if (const char *struct_name = encoding_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_name, NULL))
                                    {
                                        if (!strcmp(struct_name, "objc_object"))
                                        {
                                            if (log)
                                                GetObjectFile()->GetModule()->LogMessage (log, "SymbolFileDWARF::ParseType (die = 0x%8.8x) %s '%s' is 'objc_object*', which we overrode to 'id'.",
                                                                                          die->GetOffset(),
                                                                                          DW_TAG_value_to_name(die->Tag()),
                                                                                          die->GetName(this, dwarf_cu));
                                            clang_type = ast.GetBasicType(eBasicTypeObjCID);
                                            encoding_data_type = Type::eEncodingIsUID;
                                            encoding_uid = LLDB_INVALID_UID;
                                            resolve_state = Type::eResolveStateFull;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    type_sp.reset( new Type (MakeUserID(die->GetOffset()),
                                             this, 
                                             type_name_const_str, 
                                             byte_size, 
                                             NULL, 
                                             encoding_uid, 
                                             encoding_data_type, 
                                             &decl, 
                                             clang_type, 
                                             resolve_state));

                    m_die_to_type[die] = type_sp.get();

//                  Type* encoding_type = GetUniquedTypeForDIEOffset(encoding_uid, type_sp, NULL, 0, 0, false);
//                  if (encoding_type != NULL)
//                  {
//                      if (encoding_type != DIE_IS_BEING_PARSED)
//                          type_sp->SetEncodingType(encoding_type);
//                      else
//                          m_indirect_fixups.push_back(type_sp.get());
//                  }
                }
                break;

            case DW_TAG_structure_type:
            case DW_TAG_union_type:
            case DW_TAG_class_type:
                {
                    // Set a bit that lets us know that we are currently parsing this
                    m_die_to_type[die] = DIE_IS_BEING_PARSED;
                    bool byte_size_valid = false;

                    LanguageType class_language = eLanguageTypeUnknown;
                    bool is_complete_objc_class = false;
                    //bool struct_is_class = false;
                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
                    if (num_attributes > 0)
                    {
                        uint32_t i;
                        for (i=0; i<num_attributes; ++i)
                        {
                            attr = attributes.AttributeAtIndex(i);
                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                            {
                                switch (attr)
                                {
                                case DW_AT_decl_file:
                                    if (dwarf_cu->DW_AT_decl_file_attributes_are_invalid())
                                    {
                                        // llvm-gcc outputs invalid DW_AT_decl_file attributes that always
                                        // point to the compile unit file, so we clear this invalid value
                                        // so that we can still unique types efficiently.
                                        decl.SetFile(FileSpec ("<invalid>", false));
                                    }
                                    else
                                        decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); 
                                    break;

                                case DW_AT_decl_line:
                                    decl.SetLine(form_value.Unsigned()); 
                                    break;

                                case DW_AT_decl_column: 
                                    decl.SetColumn(form_value.Unsigned()); 
                                    break;

                                case DW_AT_name:
                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
                                    type_name_const_str.SetCString(type_name_cstr);
                                    break;

                                case DW_AT_byte_size:   
                                    byte_size = form_value.Unsigned(); 
                                    byte_size_valid = true;
                                    break;

                                case DW_AT_accessibility: 
                                    accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); 
                                    break;

                                case DW_AT_declaration: 
                                    is_forward_declaration = form_value.Boolean();
                                    break;

                                case DW_AT_APPLE_runtime_class: 
                                    class_language = (LanguageType)form_value.Signed(); 
                                    break;

                                case DW_AT_APPLE_objc_complete_type:
                                    is_complete_objc_class = form_value.Signed(); 
                                    break;

                                case DW_AT_allocated:
                                case DW_AT_associated:
                                case DW_AT_data_location:
                                case DW_AT_description:
                                case DW_AT_start_scope:
                                case DW_AT_visibility:
                                default:
                                case DW_AT_sibling:
                                    break;
                                }
                            }
                        }
                    }
                    
                    // UniqueDWARFASTType is large, so don't create a local variables on the
                    // stack, put it on the heap. This function is often called recursively
                    // and clang isn't good and sharing the stack space for variables in different blocks.
                    std::unique_ptr<UniqueDWARFASTType> unique_ast_entry_ap(new UniqueDWARFASTType());

                    // Only try and unique the type if it has a name. 
                    if (type_name_const_str &&
                        GetUniqueDWARFASTTypeMap().Find (type_name_const_str,
                                                         this,
                                                         dwarf_cu,
                                                         die,
                                                         decl,
                                                         byte_size_valid ? byte_size : -1,
                                                         *unique_ast_entry_ap))
                    {
                        // We have already parsed this type or from another 
                        // compile unit. GCC loves to use the "one definition
                        // rule" which can result in multiple definitions
                        // of the same class over and over in each compile
                        // unit.
                        type_sp = unique_ast_entry_ap->m_type_sp;
                        if (type_sp)
                        {
                            m_die_to_type[die] = type_sp.get();
                            return type_sp;
                        }
                    }

                    DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);

                    int tag_decl_kind = -1;
                    AccessType default_accessibility = eAccessNone;
                    if (tag == DW_TAG_structure_type)
                    {
                        tag_decl_kind = clang::TTK_Struct;
                        default_accessibility = eAccessPublic;
                    }
                    else if (tag == DW_TAG_union_type)
                    {
                        tag_decl_kind = clang::TTK_Union;
                        default_accessibility = eAccessPublic;
                    }
                    else if (tag == DW_TAG_class_type)
                    {
                        tag_decl_kind = clang::TTK_Class;
                        default_accessibility = eAccessPrivate;
                    }

                    if (byte_size_valid && byte_size == 0 && type_name_cstr &&
                        die->HasChildren() == false && 
                        sc.comp_unit->GetLanguage() == eLanguageTypeObjC)
                    {
                        // Work around an issue with clang at the moment where
                        // forward declarations for objective C classes are emitted
                        // as:
                        //  DW_TAG_structure_type [2]  
                        //  DW_AT_name( "ForwardObjcClass" )
                        //  DW_AT_byte_size( 0x00 )
                        //  DW_AT_decl_file( "..." )
                        //  DW_AT_decl_line( 1 )
                        //
                        // Note that there is no DW_AT_declaration and there are
                        // no children, and the byte size is zero.
                        is_forward_declaration = true;
                    }

                    if (class_language == eLanguageTypeObjC ||
                        class_language == eLanguageTypeObjC_plus_plus)
                    {
                        if (!is_complete_objc_class && Supports_DW_AT_APPLE_objc_complete_type(dwarf_cu))
                        {
                            // We have a valid eSymbolTypeObjCClass class symbol whose
                            // name matches the current objective C class that we
                            // are trying to find and this DIE isn't the complete
                            // definition (we checked is_complete_objc_class above and
                            // know it is false), so the real definition is in here somewhere
                            type_sp = FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);

                            if (!type_sp && GetDebugMapSymfile ())
                            {
                                // We weren't able to find a full declaration in
                                // this DWARF, see if we have a declaration anywhere    
                                // else...
                                type_sp = m_debug_map_symfile->FindCompleteObjCDefinitionTypeForDIE (die, type_name_const_str, true);
                            }

                            if (type_sp)
                            {
                                if (log)
                                {
                                    GetObjectFile()->GetModule()->LogMessage (log,
                                                                              "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is an incomplete objc type, complete type is 0x%8.8" PRIx64,
                                                                              static_cast<void*>(this),
                                                                              die->GetOffset(), 
                                                                              DW_TAG_value_to_name(tag),
                                                                              type_name_cstr,
                                                                              type_sp->GetID());
                                }

                                // We found a real definition for this type elsewhere
                                // so lets use it and cache the fact that we found
                                // a complete type for this die
                                m_die_to_type[die] = type_sp.get();
                                return type_sp;
                            }
                        }
                    }


                    if (is_forward_declaration)
                    {
                        // We have a forward declaration to a type and we need
                        // to try and find a full declaration. We look in the
                        // current type index just in case we have a forward
                        // declaration followed by an actual declarations in the
                        // DWARF. If this fails, we need to look elsewhere...
                        if (log)
                        {
                            GetObjectFile()->GetModule()->LogMessage (log,
                                                                      "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, trying to find complete type", 
                                                                      static_cast<void*>(this),
                                                                      die->GetOffset(), 
                                                                      DW_TAG_value_to_name(tag),
                                                                      type_name_cstr);
                        }

                        DWARFDeclContext die_decl_ctx;
                        die->GetDWARFDeclContext(this, dwarf_cu, die_decl_ctx);

                        //type_sp = FindDefinitionTypeForDIE (dwarf_cu, die, type_name_const_str);
                        type_sp = FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);

                        if (!type_sp && GetDebugMapSymfile ())
                        {
                            // We weren't able to find a full declaration in
                            // this DWARF, see if we have a declaration anywhere    
                            // else...
                            type_sp = m_debug_map_symfile->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx);
                        }

                        if (type_sp)
                        {
                            if (log)
                            {
                                GetObjectFile()->GetModule()->LogMessage (log,
                                                                          "SymbolFileDWARF(%p) - 0x%8.8x: %s type \"%s\" is a forward declaration, complete type is 0x%8.8" PRIx64,
                                                                          static_cast<void*>(this),
                                                                          die->GetOffset(), 
                                                                          DW_TAG_value_to_name(tag),
                                                                          type_name_cstr,
                                                                          type_sp->GetID());
                            }

                            // We found a real definition for this type elsewhere
                            // so lets use it and cache the fact that we found
                            // a complete type for this die
                            m_die_to_type[die] = type_sp.get();
                            return type_sp;
                        }
                    }
                    assert (tag_decl_kind != -1);
                    bool clang_type_was_created = false;
                    clang_type.SetClangType(ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
                    if (!clang_type)
                    {
                        const DWARFDebugInfoEntry *decl_ctx_die;

                        clang::DeclContext *decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
                        if (accessibility == eAccessNone && decl_ctx)
                        {
                            // Check the decl context that contains this class/struct/union.
                            // If it is a class we must give it an accessibility.
                            const clang::Decl::Kind containing_decl_kind = decl_ctx->getDeclKind();
                            if (DeclKindIsCXXClass (containing_decl_kind))
                                accessibility = default_accessibility;
                        }

                        ClangASTMetadata metadata;
                        metadata.SetUserID(MakeUserID(die->GetOffset()));
                        metadata.SetIsDynamicCXXType(ClassOrStructIsVirtual (dwarf_cu, die));

                        if (type_name_cstr && strchr (type_name_cstr, '<'))
                        {
                            ClangASTContext::TemplateParameterInfos template_param_infos;
                            if (ParseTemplateParameterInfos (dwarf_cu, die, template_param_infos))
                            {
                                clang::ClassTemplateDecl *class_template_decl = ParseClassTemplateDecl (decl_ctx,
                                                                                                        accessibility,
                                                                                                        type_name_cstr,
                                                                                                        tag_decl_kind,
                                                                                                        template_param_infos);

                                clang::ClassTemplateSpecializationDecl *class_specialization_decl = ast.CreateClassTemplateSpecializationDecl (decl_ctx,
                                                                                                                                               class_template_decl,
                                                                                                                                               tag_decl_kind,
                                                                                                                                               template_param_infos);
                                clang_type = ast.CreateClassTemplateSpecializationType (class_specialization_decl);
                                clang_type_was_created = true;

                                GetClangASTContext().SetMetadata (class_template_decl, metadata);
                                GetClangASTContext().SetMetadata (class_specialization_decl, metadata);
                            }
                        }

                        if (!clang_type_was_created)
                        {
                            clang_type_was_created = true;
                            clang_type = ast.CreateRecordType (decl_ctx, 
                                                               accessibility, 
                                                               type_name_cstr, 
                                                               tag_decl_kind, 
                                                               class_language,
                                                               &metadata);
                        }
                    }

                    // Store a forward declaration to this class type in case any 
                    // parameters in any class methods need it for the clang 
                    // types for function prototypes.
                    LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);
                    type_sp.reset (new Type (MakeUserID(die->GetOffset()), 
                                             this, 
                                             type_name_const_str, 
                                             byte_size, 
                                             NULL, 
                                             LLDB_INVALID_UID, 
                                             Type::eEncodingIsUID, 
                                             &decl, 
                                             clang_type, 
                                             Type::eResolveStateForward));

                    type_sp->SetIsCompleteObjCClass(is_complete_objc_class);


                    // Add our type to the unique type map so we don't
                    // end up creating many copies of the same type over
                    // and over in the ASTContext for our module
                    unique_ast_entry_ap->m_type_sp = type_sp;
                    unique_ast_entry_ap->m_symfile = this;
                    unique_ast_entry_ap->m_cu = dwarf_cu;
                    unique_ast_entry_ap->m_die = die;
                    unique_ast_entry_ap->m_declaration = decl;
                    unique_ast_entry_ap->m_byte_size = byte_size;
                    GetUniqueDWARFASTTypeMap().Insert (type_name_const_str, 
                                                       *unique_ast_entry_ap);

                    if (is_forward_declaration && die->HasChildren())
                    {
                        // Check to see if the DIE actually has a definition, some version of GCC will
                        // emit DIEs with DW_AT_declaration set to true, but yet still have subprogram,
                        // members, or inheritance, so we can't trust it
                        const DWARFDebugInfoEntry *child_die = die->GetFirstChild();
                        while (child_die)
                        {
                            switch (child_die->Tag())
                            {
                                case DW_TAG_inheritance:
                                case DW_TAG_subprogram:
                                case DW_TAG_member:
                                case DW_TAG_APPLE_property:
                                case DW_TAG_class_type:
                                case DW_TAG_structure_type:
                                case DW_TAG_enumeration_type:
                                case DW_TAG_typedef:
                                case DW_TAG_union_type:
                                    child_die = NULL;
                                    is_forward_declaration = false;
                                    break;
                                default:
                                    child_die = child_die->GetSibling();
                                    break;
                            }
                        }
                    }

                    if (!is_forward_declaration)
                    {
                        // Always start the definition for a class type so that
                        // if the class has child classes or types that require
                        // the class to be created for use as their decl contexts
                        // the class will be ready to accept these child definitions.
                        if (die->HasChildren() == false)
                        {
                            // No children for this struct/union/class, lets finish it
                            clang_type.StartTagDeclarationDefinition ();
                            clang_type.CompleteTagDeclarationDefinition ();

                            if (tag == DW_TAG_structure_type) // this only applies in C
                            {
                                clang::RecordDecl *record_decl = clang_type.GetAsRecordDecl();

                                if (record_decl)
                                    m_record_decl_to_layout_map.insert(std::make_pair(record_decl, LayoutInfo()));
                            }
                        }
                        else if (clang_type_was_created)
                        {
                            // Start the definition if the class is not objective C since
                            // the underlying decls respond to isCompleteDefinition(). Objective
                            // C decls don't respond to isCompleteDefinition() so we can't
                            // start the declaration definition right away. For C++ class/union/structs
                            // we want to start the definition in case the class is needed as the
                            // declaration context for a contained class or type without the need
                            // to complete that type..

                            if (class_language != eLanguageTypeObjC &&
                                class_language != eLanguageTypeObjC_plus_plus)
                                clang_type.StartTagDeclarationDefinition ();

                            // Leave this as a forward declaration until we need
                            // to know the details of the type. lldb_private::Type
                            // will automatically call the SymbolFile virtual function
                            // "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition(Type *)"
                            // When the definition needs to be defined.
                            m_forward_decl_die_to_clang_type[die] = clang_type.GetOpaqueQualType();
                            m_forward_decl_clang_type_to_die[clang_type.RemoveFastQualifiers().GetOpaqueQualType()] = die;
                            clang_type.SetHasExternalStorage (true);
                        }
                    }

                }
                break;

            case DW_TAG_enumeration_type:
                {
                    // Set a bit that lets us know that we are currently parsing this
                    m_die_to_type[die] = DIE_IS_BEING_PARSED;

                    lldb::user_id_t encoding_uid = DW_INVALID_OFFSET;

                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
                    if (num_attributes > 0)
                    {
                        uint32_t i;

                        for (i=0; i<num_attributes; ++i)
                        {
                            attr = attributes.AttributeAtIndex(i);
                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                            {
                                switch (attr)
                                {
                                case DW_AT_decl_file:       decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
                                case DW_AT_decl_line:       decl.SetLine(form_value.Unsigned()); break;
                                case DW_AT_decl_column:     decl.SetColumn(form_value.Unsigned()); break;
                                case DW_AT_name:
                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
                                    type_name_const_str.SetCString(type_name_cstr);
                                    break;
                                case DW_AT_type:            encoding_uid = form_value.Reference(); break;
                                case DW_AT_byte_size:       byte_size = form_value.Unsigned(); break;
                                case DW_AT_accessibility:   break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
                                case DW_AT_declaration:     break; //is_forward_declaration = form_value.Boolean(); break;
                                case DW_AT_allocated:
                                case DW_AT_associated:
                                case DW_AT_bit_stride:
                                case DW_AT_byte_stride:
                                case DW_AT_data_location:
                                case DW_AT_description:
                                case DW_AT_start_scope:
                                case DW_AT_visibility:
                                case DW_AT_specification:
                                case DW_AT_abstract_origin:
                                case DW_AT_sibling:
                                    break;
                                }
                            }
                        }

                        DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);

                        ClangASTType enumerator_clang_type;
                        clang_type.SetClangType (ast.getASTContext(), m_forward_decl_die_to_clang_type.lookup (die));
                        if (!clang_type)
                        {
                            if (encoding_uid != DW_INVALID_OFFSET)
                            {
                                Type *enumerator_type = ResolveTypeUID(encoding_uid);
                                if (enumerator_type)
                                    enumerator_clang_type = enumerator_type->GetClangFullType();
                            }

                            if (!enumerator_clang_type)
                                enumerator_clang_type = ast.GetBuiltinTypeForDWARFEncodingAndBitSize (NULL,
                                                                                                      DW_ATE_signed,
                                                                                                      byte_size * 8);

                            clang_type = ast.CreateEnumerationType (type_name_cstr, 
                                                                    GetClangDeclContextContainingDIE (dwarf_cu, die, NULL), 
                                                                    decl,
                                                                    enumerator_clang_type);
                        }
                        else
                        {
                            enumerator_clang_type = clang_type.GetEnumerationIntegerType ();
                        }

                        LinkDeclContextToDIE(clang_type.GetDeclContextForType(), die);

                        type_sp.reset( new Type (MakeUserID(die->GetOffset()), 
                                                 this, 
                                                 type_name_const_str, 
                                                 byte_size, 
                                                 NULL, 
                                                 encoding_uid, 
                                                 Type::eEncodingIsUID,
                                                 &decl, 
                                                 clang_type, 
                                                 Type::eResolveStateForward));

                        clang_type.StartTagDeclarationDefinition ();
                        if (die->HasChildren())
                        {
                            SymbolContext cu_sc(GetCompUnitForDWARFCompUnit(dwarf_cu));
                            bool is_signed = false;
                            enumerator_clang_type.IsIntegerType(is_signed);
                            ParseChildEnumerators(cu_sc, clang_type, is_signed, type_sp->GetByteSize(), dwarf_cu, die);
                        }
                        clang_type.CompleteTagDeclarationDefinition ();
                    }
                }
                break;

            case DW_TAG_inlined_subroutine:
            case DW_TAG_subprogram:
            case DW_TAG_subroutine_type:
                {
                    // Set a bit that lets us know that we are currently parsing this
                    m_die_to_type[die] = DIE_IS_BEING_PARSED;

                    //const char *mangled = NULL;
                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
                    bool is_variadic = false;
                    bool is_inline = false;
                    bool is_static = false;
                    bool is_virtual = false;
                    bool is_explicit = false;
                    bool is_artificial = false;
                    dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
                    dw_offset_t abstract_origin_die_offset = DW_INVALID_OFFSET;
                    dw_offset_t object_pointer_die_offset = DW_INVALID_OFFSET;

                    unsigned type_quals = 0;
                    clang::StorageClass storage = clang::SC_None;//, Extern, Static, PrivateExtern


                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
                    if (num_attributes > 0)
                    {
                        uint32_t i;
                        for (i=0; i<num_attributes; ++i)
                        {
                            attr = attributes.AttributeAtIndex(i);
                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                            {
                                switch (attr)
                                {
                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
                                case DW_AT_name:
                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
                                    type_name_const_str.SetCString(type_name_cstr);
                                    break;

                                case DW_AT_linkage_name:
                                case DW_AT_MIPS_linkage_name:   break; // mangled = form_value.AsCString(&get_debug_str_data()); break;
                                case DW_AT_type:                type_die_offset = form_value.Reference(); break;
                                case DW_AT_accessibility:       accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
                                case DW_AT_declaration:         break; // is_forward_declaration = form_value.Boolean(); break;
                                case DW_AT_inline:              is_inline = form_value.Boolean(); break;
                                case DW_AT_virtuality:          is_virtual = form_value.Boolean();  break;
                                case DW_AT_explicit:            is_explicit = form_value.Boolean();  break;
                                case DW_AT_artificial:          is_artificial = form_value.Boolean();  break;


                                case DW_AT_external:
                                    if (form_value.Unsigned())
                                    {
                                        if (storage == clang::SC_None)
                                            storage = clang::SC_Extern;
                                        else
                                            storage = clang::SC_PrivateExtern;
                                    }
                                    break;

                                case DW_AT_specification:
                                    specification_die_offset = form_value.Reference();
                                    break;

                                case DW_AT_abstract_origin:
                                    abstract_origin_die_offset = form_value.Reference();
                                    break;

                                case DW_AT_object_pointer:
                                    object_pointer_die_offset = form_value.Reference();
                                    break;

                                case DW_AT_allocated:
                                case DW_AT_associated:
                                case DW_AT_address_class:
                                case DW_AT_calling_convention:
                                case DW_AT_data_location:
                                case DW_AT_elemental:
                                case DW_AT_entry_pc:
                                case DW_AT_frame_base:
                                case DW_AT_high_pc:
                                case DW_AT_low_pc:
                                case DW_AT_prototyped:
                                case DW_AT_pure:
                                case DW_AT_ranges:
                                case DW_AT_recursive:
                                case DW_AT_return_addr:
                                case DW_AT_segment:
                                case DW_AT_start_scope:
                                case DW_AT_static_link:
                                case DW_AT_trampoline:
                                case DW_AT_visibility:
                                case DW_AT_vtable_elem_location:
                                case DW_AT_description:
                                case DW_AT_sibling:
                                    break;
                                }
                            }
                        }
                    }

                    std::string object_pointer_name;
                    if (object_pointer_die_offset != DW_INVALID_OFFSET)
                    {
                        // Get the name from the object pointer die
                        StreamString s;
                        if (DWARFDebugInfoEntry::GetName (this, dwarf_cu, object_pointer_die_offset, s))
                        {
                            object_pointer_name.assign(s.GetData());
                        }
                    }

                    DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);

                    ClangASTType return_clang_type;
                    Type *func_type = NULL;

                    if (type_die_offset != DW_INVALID_OFFSET)
                        func_type = ResolveTypeUID(type_die_offset);

                    if (func_type)
                        return_clang_type = func_type->GetClangForwardType();
                    else
                        return_clang_type = ast.GetBasicType(eBasicTypeVoid);


                    std::vector<ClangASTType> function_param_types;
                    std::vector<clang::ParmVarDecl*> function_param_decls;

                    // Parse the function children for the parameters

                    const DWARFDebugInfoEntry *decl_ctx_die = NULL;
                    clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE (dwarf_cu, die, &decl_ctx_die);
                    const clang::Decl::Kind containing_decl_kind = containing_decl_ctx->getDeclKind();

                    const bool is_cxx_method = DeclKindIsCXXClass (containing_decl_kind);
                    // Start off static. This will be set to false in ParseChildParameters(...)
                    // if we find a "this" parameters as the first parameter
                    if (is_cxx_method)
                        is_static = true;
                    
                    if (die->HasChildren())
                    {
                        bool skip_artificial = true;
                        ParseChildParameters (sc,
                                              containing_decl_ctx,
                                              dwarf_cu,
                                              die,
                                              skip_artificial,
                                              is_static,
                                              is_variadic,
                                              function_param_types,
                                              function_param_decls,
                                              type_quals);
                    }

                    // clang_type will get the function prototype clang type after this call
                    clang_type = ast.CreateFunctionType (return_clang_type, 
                                                         function_param_types.data(),
                                                         function_param_types.size(), 
                                                         is_variadic, 
                                                         type_quals);

                    bool ignore_containing_context = false;

                    if (type_name_cstr)
                    {
                        bool type_handled = false;
                        if (tag == DW_TAG_subprogram)
                        {
                            ObjCLanguageRuntime::MethodName objc_method (type_name_cstr, true);
                            if (objc_method.IsValid(true))
                            {
                                ClangASTType class_opaque_type;
                                ConstString class_name(objc_method.GetClassName());
                                if (class_name)
                                {
                                    TypeSP complete_objc_class_type_sp (FindCompleteObjCDefinitionTypeForDIE (NULL, class_name, false));

                                    if (complete_objc_class_type_sp)
                                    {
                                        ClangASTType type_clang_forward_type = complete_objc_class_type_sp->GetClangForwardType();
                                        if (type_clang_forward_type.IsObjCObjectOrInterfaceType ())
                                            class_opaque_type = type_clang_forward_type;
                                    }
                                }

                                if (class_opaque_type)
                                {
                                    // If accessibility isn't set to anything valid, assume public for 
                                    // now...
                                    if (accessibility == eAccessNone)
                                        accessibility = eAccessPublic;

                                    clang::ObjCMethodDecl *objc_method_decl = class_opaque_type.AddMethodToObjCObjectType (type_name_cstr,
                                                                                                                           clang_type,
                                                                                                                           accessibility,
                                                                                                                           is_artificial);
                                    type_handled = objc_method_decl != NULL;
                                    if (type_handled)
                                    {
                                        LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(objc_method_decl), die);
                                        GetClangASTContext().SetMetadataAsUserID (objc_method_decl, MakeUserID(die->GetOffset()));
                                    }
                                    else
                                    {
                                        GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: invalid Objective-C method 0x%4.4x (%s), please file a bug and attach the file at the start of this error message",
                                                                                   die->GetOffset(),
                                                                                   tag,
                                                                                   DW_TAG_value_to_name(tag));
                                    }
                                }
                            }
                            else if (is_cxx_method)
                            {
                                // Look at the parent of this DIE and see if is is
                                // a class or struct and see if this is actually a
                                // C++ method
                                Type *class_type = ResolveType (dwarf_cu, decl_ctx_die);
                                if (class_type)
                                {
                                    if (class_type->GetID() != MakeUserID(decl_ctx_die->GetOffset()))
                                    {
                                        // We uniqued the parent class of this function to another class
                                        // so we now need to associate all dies under "decl_ctx_die" to
                                        // DIEs in the DIE for "class_type"...
                                        SymbolFileDWARF *class_symfile = NULL;
                                        DWARFCompileUnitSP class_type_cu_sp;
                                        const DWARFDebugInfoEntry *class_type_die = NULL;

                                        SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile();
                                        if (debug_map_symfile)
                                        {
                                            class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
                                            class_type_die = class_symfile->DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
                                        }
                                        else
                                        {
                                            class_symfile = this;
                                            class_type_die = DebugInfo()->GetDIEPtr(class_type->GetID(), &class_type_cu_sp);
                                        }
                                        if (class_type_die)
                                        {
                                            DWARFDIECollection failures;

                                            CopyUniqueClassMethodTypes (class_symfile,
                                                                        class_type,
                                                                        class_type_cu_sp.get(),
                                                                        class_type_die,
                                                                        dwarf_cu,
                                                                        decl_ctx_die,
                                                                        failures);

                                            // FIXME do something with these failures that's smarter than
                                            // just dropping them on the ground.  Unfortunately classes don't
                                            // like having stuff added to them after their definitions are
                                            // complete...

                                            type_ptr = m_die_to_type[die];
                                            if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
                                            {
                                                type_sp = type_ptr->shared_from_this();
                                                break;
                                            }
                                        }
                                    }

                                    if (specification_die_offset != DW_INVALID_OFFSET)
                                    {
                                        // We have a specification which we are going to base our function
                                        // prototype off of, so we need this type to be completed so that the
                                        // m_die_to_decl_ctx for the method in the specification has a valid
                                        // clang decl context.
                                        class_type->GetClangForwardType();
                                        // If we have a specification, then the function type should have been
                                        // made with the specification and not with this die.
                                        DWARFCompileUnitSP spec_cu_sp;
                                        const DWARFDebugInfoEntry* spec_die = DebugInfo()->GetDIEPtr(specification_die_offset, &spec_cu_sp);
                                        clang::DeclContext *spec_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, spec_die);
                                        if (spec_clang_decl_ctx)
                                        {
                                            LinkDeclContextToDIE(spec_clang_decl_ctx, die);
                                        }
                                        else
                                        {
                                            GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_specification(0x%8.8x) has no decl\n",
                                                                                         MakeUserID(die->GetOffset()), 
                                                                                         specification_die_offset);
                                        }
                                        type_handled = true;
                                    }
                                    else if (abstract_origin_die_offset != DW_INVALID_OFFSET)
                                    {
                                        // We have a specification which we are going to base our function
                                        // prototype off of, so we need this type to be completed so that the
                                        // m_die_to_decl_ctx for the method in the abstract origin has a valid
                                        // clang decl context.
                                        class_type->GetClangForwardType();

                                        DWARFCompileUnitSP abs_cu_sp;
                                        const DWARFDebugInfoEntry* abs_die = DebugInfo()->GetDIEPtr(abstract_origin_die_offset, &abs_cu_sp);
                                        clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE (sc, dwarf_cu, abs_die);
                                        if (abs_clang_decl_ctx)
                                        {
                                            LinkDeclContextToDIE (abs_clang_decl_ctx, die);
                                        }
                                        else
                                        {
                                            GetObjectFile()->GetModule()->ReportWarning ("0x%8.8" PRIx64 ": DW_AT_abstract_origin(0x%8.8x) has no decl\n",
                                                                                         MakeUserID(die->GetOffset()), 
                                                                                         abstract_origin_die_offset);
                                        }
                                        type_handled = true;
                                    }
                                    else
                                    {
                                        ClangASTType class_opaque_type = class_type->GetClangForwardType();
                                        if (class_opaque_type.IsCXXClassType ())
                                        {
                                            if (class_opaque_type.IsBeingDefined ())
                                            {
                                                // Neither GCC 4.2 nor clang++ currently set a valid accessibility
                                                // in the DWARF for C++ methods... Default to public for now...
                                                if (accessibility == eAccessNone)
                                                    accessibility = eAccessPublic;

                                                if (!is_static && !die->HasChildren())
                                                {
                                                    // We have a C++ member function with no children (this pointer!)
                                                    // and clang will get mad if we try and make a function that isn't
                                                    // well formed in the DWARF, so we will just skip it...
                                                    type_handled = true;
                                                }
                                                else
                                                {
                                                    clang::CXXMethodDecl *cxx_method_decl;
                                                    // REMOVE THE CRASH DESCRIPTION BELOW
                                                    Host::SetCrashDescriptionWithFormat ("SymbolFileDWARF::ParseType() is adding a method %s to class %s in DIE 0x%8.8" PRIx64 " from %s",
                                                                                         type_name_cstr, 
                                                                                         class_type->GetName().GetCString(),
                                                                                         MakeUserID(die->GetOffset()),
                                                                                         m_obj_file->GetFileSpec().GetPath().c_str());

                                                    const bool is_attr_used = false;

                                                    cxx_method_decl = class_opaque_type.AddMethodToCXXRecordType (type_name_cstr,
                                                                                                                  clang_type,
                                                                                                                  accessibility,
                                                                                                                  is_virtual,
                                                                                                                  is_static,
                                                                                                                  is_inline,
                                                                                                                  is_explicit,
                                                                                                                  is_attr_used,
                                                                                                                  is_artificial);

                                                    type_handled = cxx_method_decl != NULL;

                                                    if (type_handled)
                                                    {
                                                        LinkDeclContextToDIE(ClangASTContext::GetAsDeclContext(cxx_method_decl), die);

                                                        Host::SetCrashDescription (NULL);


                                                        ClangASTMetadata metadata;
                                                        metadata.SetUserID(MakeUserID(die->GetOffset()));

                                                        if (!object_pointer_name.empty())
                                                        {
                                                            metadata.SetObjectPtrName(object_pointer_name.c_str());
                                                            if (log)
                                                                log->Printf ("Setting object pointer name: %s on method object %p.\n",
                                                                             object_pointer_name.c_str(),
                                                                             static_cast<void*>(cxx_method_decl));
                                                        }
                                                        GetClangASTContext().SetMetadata (cxx_method_decl, metadata);
                                                    }
                                                    else
                                                    {
                                                        ignore_containing_context = true;
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                // We were asked to parse the type for a method in a class, yet the
                                                // class hasn't been asked to complete itself through the 
                                                // clang::ExternalASTSource protocol, so we need to just have the
                                                // class complete itself and do things the right way, then our 
                                                // DIE should then have an entry in the m_die_to_type map. First 
                                                // we need to modify the m_die_to_type so it doesn't think we are 
                                                // trying to parse this DIE anymore...
                                                m_die_to_type[die] = NULL;

                                                // Now we get the full type to force our class type to complete itself 
                                                // using the clang::ExternalASTSource protocol which will parse all 
                                                // base classes and all methods (including the method for this DIE).
                                                class_type->GetClangFullType();

                                                // The type for this DIE should have been filled in the function call above
                                                type_ptr = m_die_to_type[die];
                                                if (type_ptr && type_ptr != DIE_IS_BEING_PARSED)
                                                {
                                                    type_sp = type_ptr->shared_from_this();
                                                    break;
                                                }

                                                // FIXME This is fixing some even uglier behavior but we really need to
                                                // uniq the methods of each class as well as the class itself.
                                                // <rdar://problem/11240464>
                                                type_handled = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (!type_handled)
                        {
                            // We just have a function that isn't part of a class
                            clang::FunctionDecl *function_decl = ast.CreateFunctionDeclaration (ignore_containing_context ? GetClangASTContext().GetTranslationUnitDecl() : containing_decl_ctx,
                                                                                                type_name_cstr, 
                                                                                                clang_type, 
                                                                                                storage, 
                                                                                                is_inline);

//                            if (template_param_infos.GetSize() > 0)
//                            {
//                                clang::FunctionTemplateDecl *func_template_decl = ast.CreateFunctionTemplateDecl (containing_decl_ctx,
//                                                                                                                  function_decl,
//                                                                                                                  type_name_cstr, 
//                                                                                                                  template_param_infos);
//                                
//                                ast.CreateFunctionTemplateSpecializationInfo (function_decl,
//                                                                              func_template_decl,
//                                                                              template_param_infos);
//                            }
                            // Add the decl to our DIE to decl context map
                            assert (function_decl);
                            LinkDeclContextToDIE(function_decl, die);
                            if (!function_param_decls.empty())
                                ast.SetFunctionParameters (function_decl, 
                                                           &function_param_decls.front(), 
                                                           function_param_decls.size());

                            ClangASTMetadata metadata;
                            metadata.SetUserID(MakeUserID(die->GetOffset()));

                            if (!object_pointer_name.empty())
                            {
                                metadata.SetObjectPtrName(object_pointer_name.c_str());
                                if (log)
                                    log->Printf ("Setting object pointer name: %s on function object %p.",
                                                 object_pointer_name.c_str(),
                                                 static_cast<void*>(function_decl));
                            }
                            GetClangASTContext().SetMetadata (function_decl, metadata);
                        }
                    }
                    type_sp.reset( new Type (MakeUserID(die->GetOffset()), 
                                             this, 
                                             type_name_const_str, 
                                             0, 
                                             NULL, 
                                             LLDB_INVALID_UID, 
                                             Type::eEncodingIsUID, 
                                             &decl, 
                                             clang_type, 
                                             Type::eResolveStateFull));                    
                    assert(type_sp.get());
                }
                break;

            case DW_TAG_array_type:
                {
                    // Set a bit that lets us know that we are currently parsing this
                    m_die_to_type[die] = DIE_IS_BEING_PARSED;

                    lldb::user_id_t type_die_offset = DW_INVALID_OFFSET;
                    int64_t first_index = 0;
                    uint32_t byte_stride = 0;
                    uint32_t bit_stride = 0;
                    bool is_vector = false;
                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);

                    if (num_attributes > 0)
                    {
                        uint32_t i;
                        for (i=0; i<num_attributes; ++i)
                        {
                            attr = attributes.AttributeAtIndex(i);
                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                            {
                                switch (attr)
                                {
                                case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
                                case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
                                case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
                                case DW_AT_name:
                                    type_name_cstr = form_value.AsCString(&get_debug_str_data());
                                    type_name_const_str.SetCString(type_name_cstr);
                                    break;

                                case DW_AT_type:            type_die_offset = form_value.Reference(); break;
                                case DW_AT_byte_size:       break; // byte_size = form_value.Unsigned(); break;
                                case DW_AT_byte_stride:     byte_stride = form_value.Unsigned(); break;
                                case DW_AT_bit_stride:      bit_stride = form_value.Unsigned(); break;
                                case DW_AT_GNU_vector:      is_vector = form_value.Boolean(); break;
                                case DW_AT_accessibility:   break; // accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
                                case DW_AT_declaration:     break; // is_forward_declaration = form_value.Boolean(); break;
                                case DW_AT_allocated:
                                case DW_AT_associated:
                                case DW_AT_data_location:
                                case DW_AT_description:
                                case DW_AT_ordering:
                                case DW_AT_start_scope:
                                case DW_AT_visibility:
                                case DW_AT_specification:
                                case DW_AT_abstract_origin:
                                case DW_AT_sibling:
                                    break;
                                }
                            }
                        }

                        DEBUG_PRINTF ("0x%8.8" PRIx64 ": %s (\"%s\")\n", MakeUserID(die->GetOffset()), DW_TAG_value_to_name(tag), type_name_cstr);

                        Type *element_type = ResolveTypeUID(type_die_offset);

                        if (element_type)
                        {
                            std::vector<uint64_t> element_orders;
                            ParseChildArrayInfo(sc, dwarf_cu, die, first_index, element_orders, byte_stride, bit_stride);
                            if (byte_stride == 0 && bit_stride == 0)
                                byte_stride = element_type->GetByteSize();
                            ClangASTType array_element_type = element_type->GetClangForwardType();
                            uint64_t array_element_bit_stride = byte_stride * 8 + bit_stride;
                            if (element_orders.size() > 0)
                            {
                                uint64_t num_elements = 0;
                                std::vector<uint64_t>::const_reverse_iterator pos;
                                std::vector<uint64_t>::const_reverse_iterator end = element_orders.rend();
                                for (pos = element_orders.rbegin(); pos != end; ++pos)
                                {
                                    num_elements = *pos;
                                    clang_type = ast.CreateArrayType (array_element_type,
                                                                      num_elements,
                                                                      is_vector);
                                    array_element_type = clang_type;
                                    array_element_bit_stride = num_elements ?
                                                               array_element_bit_stride * num_elements :
                                                               array_element_bit_stride;
                                }
                            }
                            else
                            {
                                clang_type = ast.CreateArrayType (array_element_type, 0, is_vector);
                            }
                            ConstString empty_name;
                            type_sp.reset( new Type (MakeUserID(die->GetOffset()), 
                                                     this, 
                                                     empty_name, 
                                                     array_element_bit_stride / 8, 
                                                     NULL, 
                                                     type_die_offset, 
                                                     Type::eEncodingIsUID, 
                                                     &decl, 
                                                     clang_type, 
                                                     Type::eResolveStateFull));
                            type_sp->SetEncodingType (element_type);
                        }
                    }
                }
                break;

            case DW_TAG_ptr_to_member_type:
                {
                    dw_offset_t type_die_offset = DW_INVALID_OFFSET;
                    dw_offset_t containing_type_die_offset = DW_INVALID_OFFSET;

                    const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);

                    if (num_attributes > 0) {
                        uint32_t i;
                        for (i=0; i<num_attributes; ++i)
                        {
                            attr = attributes.AttributeAtIndex(i);
                            if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                            {
                                switch (attr)
                                {
                                    case DW_AT_type:
                                        type_die_offset = form_value.Reference(); break;
                                    case DW_AT_containing_type:
                                        containing_type_die_offset = form_value.Reference(); break;
                                }
                            }
                        }

                        Type *pointee_type = ResolveTypeUID(type_die_offset);
                        Type *class_type = ResolveTypeUID(containing_type_die_offset);

                        ClangASTType pointee_clang_type = pointee_type->GetClangForwardType();
                        ClangASTType class_clang_type = class_type->GetClangLayoutType();

                        clang_type = pointee_clang_type.CreateMemberPointerType(class_clang_type);

                        byte_size = clang_type.GetByteSize(nullptr);

                        type_sp.reset( new Type (MakeUserID(die->GetOffset()), 
                                                 this, 
                                                 type_name_const_str, 
                                                 byte_size, 
                                                 NULL, 
                                                 LLDB_INVALID_UID, 
                                                 Type::eEncodingIsUID, 
                                                 NULL, 
                                                 clang_type, 
                                                 Type::eResolveStateForward));
                    }

                    break;
                }
            default:
                GetObjectFile()->GetModule()->ReportError ("{0x%8.8x}: unhandled type tag 0x%4.4x (%s), please file a bug and attach the file at the start of this error message",
                                                           die->GetOffset(),
                                                           tag,
                                                           DW_TAG_value_to_name(tag));
                break;
            }

            if (type_sp.get())
            {
                const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
                dw_tag_t sc_parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;

                SymbolContextScope * symbol_context_scope = NULL;
                if (sc_parent_tag == DW_TAG_compile_unit)
                {
                    symbol_context_scope = sc.comp_unit;
                }
                else if (sc.function != NULL && sc_parent_die)
                {
                    symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
                    if (symbol_context_scope == NULL)
                        symbol_context_scope = sc.function;
                }

                if (symbol_context_scope != NULL)
                {
                    type_sp->SetSymbolContextScope(symbol_context_scope);
                }

                // We are ready to put this type into the uniqued list up at the module level
                type_list->Insert (type_sp);

                m_die_to_type[die] = type_sp.get();
            }
        }
        else if (type_ptr != DIE_IS_BEING_PARSED)
        {
            type_sp = type_ptr->shared_from_this();
        }
    }
    return type_sp;
}

size_t
SymbolFileDWARF::ParseTypes
(
    const SymbolContext& sc, 
    DWARFCompileUnit* dwarf_cu, 
    const DWARFDebugInfoEntry *die, 
    bool parse_siblings, 
    bool parse_children
)
{
    size_t types_added = 0;
    while (die != NULL)
    {
        bool type_is_new = false;
        if (ParseType(sc, dwarf_cu, die, &type_is_new).get())
        {
            if (type_is_new)
                ++types_added;
        }

        if (parse_children && die->HasChildren())
        {
            if (die->Tag() == DW_TAG_subprogram)
            {
                SymbolContext child_sc(sc);
                child_sc.function = sc.comp_unit->FindFunctionByUID(MakeUserID(die->GetOffset())).get();
                types_added += ParseTypes(child_sc, dwarf_cu, die->GetFirstChild(), true, true);
            }
            else
                types_added += ParseTypes(sc, dwarf_cu, die->GetFirstChild(), true, true);
        }

        if (parse_siblings)
            die = die->GetSibling();
        else
            die = NULL;
    }
    return types_added;
}


size_t
SymbolFileDWARF::ParseFunctionBlocks (const SymbolContext &sc)
{
    assert(sc.comp_unit && sc.function);
    size_t functions_added = 0;
    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
    if (dwarf_cu)
    {
        dw_offset_t function_die_offset = sc.function->GetID();
        const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(function_die_offset);
        if (function_die)
        {
            ParseFunctionBlocks(sc, &sc.function->GetBlock (false), dwarf_cu, function_die, LLDB_INVALID_ADDRESS, 0);
        }
    }

    return functions_added;
}


size_t
SymbolFileDWARF::ParseTypes (const SymbolContext &sc)
{
    // At least a compile unit must be valid
    assert(sc.comp_unit);
    size_t types_added = 0;
    DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
    if (dwarf_cu)
    {
        if (sc.function)
        {
            dw_offset_t function_die_offset = sc.function->GetID();
            const DWARFDebugInfoEntry *func_die = dwarf_cu->GetDIEPtr(function_die_offset);
            if (func_die && func_die->HasChildren())
            {
                types_added = ParseTypes(sc, dwarf_cu, func_die->GetFirstChild(), true, true);
            }
        }
        else
        {
            const DWARFDebugInfoEntry *dwarf_cu_die = dwarf_cu->DIE();
            if (dwarf_cu_die && dwarf_cu_die->HasChildren())
            {
                types_added = ParseTypes(sc, dwarf_cu, dwarf_cu_die->GetFirstChild(), true, true);
            }
        }
    }

    return types_added;
}

size_t
SymbolFileDWARF::ParseVariablesForContext (const SymbolContext& sc)
{
    if (sc.comp_unit != NULL)
    {
        DWARFDebugInfo* info = DebugInfo();
        if (info == NULL)
            return 0;
        
        if (sc.function)
        {
            DWARFCompileUnit* dwarf_cu = info->GetCompileUnitContainingDIE(sc.function->GetID()).get();
            
            if (dwarf_cu == NULL)
                return 0;
            
            const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
            
            dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
            if (func_lo_pc != LLDB_INVALID_ADDRESS)
            {
                const size_t num_variables = ParseVariables(sc, dwarf_cu, func_lo_pc, function_die->GetFirstChild(), true, true);
            
                // Let all blocks know they have parse all their variables
                sc.function->GetBlock (false).SetDidParseVariables (true, true);
                return num_variables;
            }
        }
        else if (sc.comp_unit)
        {
            DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()).get();

            if (dwarf_cu == NULL)
                return 0;

            uint32_t vars_added = 0;
            VariableListSP variables (sc.comp_unit->GetVariableList(false));
            
            if (variables.get() == NULL)
            {
                variables.reset(new VariableList());
                sc.comp_unit->SetVariableList(variables);

                DWARFCompileUnit* match_dwarf_cu = NULL;
                const DWARFDebugInfoEntry* die = NULL;
                DIEArray die_offsets;
                if (m_using_apple_tables)
                {
                    if (m_apple_names_ap.get())
                    {
                        DWARFMappedHash::DIEInfoArray hash_data_array;
                        if (m_apple_names_ap->AppendAllDIEsInRange (dwarf_cu->GetOffset(), 
                                                                    dwarf_cu->GetNextCompileUnitOffset(), 
                                                                    hash_data_array))
                        {
                            DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets);
                        }
                    }
                }
                else
                {
                    // Index if we already haven't to make sure the compile units
                    // get indexed and make their global DIE index list
                    if (!m_indexed)
                        Index ();

                    m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(), 
                                                                 dwarf_cu->GetNextCompileUnitOffset(), 
                                                                 die_offsets);
                }

                const size_t num_matches = die_offsets.size();
                if (num_matches)
                {
                    DWARFDebugInfo* debug_info = DebugInfo();
                    for (size_t i=0; i<num_matches; ++i)
                    {
                        const dw_offset_t die_offset = die_offsets[i];
                        die = debug_info->GetDIEPtrWithCompileUnitHint (die_offset, &match_dwarf_cu);
                        if (die)
                        {
                            VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, LLDB_INVALID_ADDRESS));
                            if (var_sp)
                            {
                                variables->AddVariableIfUnique (var_sp);
                                ++vars_added;
                            }
                        }
                        else
                        {
                            if (m_using_apple_tables)
                            {
                                GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_offset);
                            }
                        }            

                    }
                }
            }
            return vars_added;
        }
    }
    return 0;
}


VariableSP
SymbolFileDWARF::ParseVariableDIE
(
    const SymbolContext& sc,
    DWARFCompileUnit* dwarf_cu,
    const DWARFDebugInfoEntry *die,
    const lldb::addr_t func_low_pc
)
{
    VariableSP var_sp (m_die_to_variable_sp[die]);
    if (var_sp)
        return var_sp;  // Already been parsed!
    
    const dw_tag_t tag = die->Tag();
    ModuleSP module = GetObjectFile()->GetModule();
    
    if ((tag == DW_TAG_variable) ||
        (tag == DW_TAG_constant) ||
        (tag == DW_TAG_formal_parameter && sc.function))
    {
        DWARFDebugInfoEntry::Attributes attributes;
        const size_t num_attributes = die->GetAttributes(this, dwarf_cu, NULL, attributes);
        if (num_attributes > 0)
        {
            const char *name = NULL;
            const char *mangled = NULL;
            Declaration decl;
            uint32_t i;
            lldb::user_id_t type_uid = LLDB_INVALID_UID;
            DWARFExpression location;
            bool is_external = false;
            bool is_artificial = false;
            bool location_is_const_value_data = false;
            bool has_explicit_location = false;
            DWARFFormValue const_value;
            //AccessType accessibility = eAccessNone;

            for (i=0; i<num_attributes; ++i)
            {
                dw_attr_t attr = attributes.AttributeAtIndex(i);
                DWARFFormValue form_value;
                
                if (attributes.ExtractFormValueAtIndex(this, i, form_value))
                {
                    switch (attr)
                    {
                    case DW_AT_decl_file:   decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(form_value.Unsigned())); break;
                    case DW_AT_decl_line:   decl.SetLine(form_value.Unsigned()); break;
                    case DW_AT_decl_column: decl.SetColumn(form_value.Unsigned()); break;
                    case DW_AT_name:        name = form_value.AsCString(&get_debug_str_data()); break;
                    case DW_AT_linkage_name:
                    case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(&get_debug_str_data()); break;
                    case DW_AT_type:        type_uid = form_value.Reference(); break;
                    case DW_AT_external:    is_external = form_value.Boolean(); break;
                    case DW_AT_const_value:
                        // If we have already found a DW_AT_location attribute, ignore this attribute.
                        if (!has_explicit_location)
                        {
                            location_is_const_value_data = true;
                            // The constant value will be either a block, a data value or a string.
                            const DWARFDataExtractor& debug_info_data = get_debug_info_data();
                            if (DWARFFormValue::IsBlockForm(form_value.Form()))
                            {
                                // Retrieve the value as a block expression.
                                uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
                                uint32_t block_length = form_value.Unsigned();
                                location.CopyOpcodeData(module, debug_info_data, block_offset, block_length);
                            }
                            else if (DWARFFormValue::IsDataForm(form_value.Form()))
                            {
                                // Retrieve the value as a data expression.
                                const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
                                uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
                                uint32_t data_length = fixed_form_sizes[form_value.Form()];
                                if (data_length == 0)
                                {
                                    const uint8_t *data_pointer = form_value.BlockData();
                                    if (data_pointer)
                                    {
                                        form_value.Unsigned();
                                    }
                                    else if (DWARFFormValue::IsDataForm(form_value.Form()))
                                    {
                                        // we need to get the byte size of the type later after we create the variable
                                        const_value = form_value;
                                    }
                                }
                                else
                                    location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
                            }
                            else
                            {
                                // Retrieve the value as a string expression.
                                if (form_value.Form() == DW_FORM_strp)
                                {
                                    const uint8_t *fixed_form_sizes = DWARFFormValue::GetFixedFormSizesForAddressSize (attributes.CompileUnitAtIndex(i)->GetAddressByteSize(), attributes.CompileUnitAtIndex(i)->IsDWARF64());
                                    uint32_t data_offset = attributes.DIEOffsetAtIndex(i);
                                    uint32_t data_length = fixed_form_sizes[form_value.Form()];
                                    location.CopyOpcodeData(module, debug_info_data, data_offset, data_length);
                                }
                                else
                                {
                                    const char *str = form_value.AsCString(&debug_info_data);
                                    uint32_t string_offset = str - (const char *)debug_info_data.GetDataStart();
                                    uint32_t string_length = strlen(str) + 1;
                                    location.CopyOpcodeData(module, debug_info_data, string_offset, string_length);
                                }
                            }
                        }
                        break;
                    case DW_AT_location:
                        {
                            location_is_const_value_data = false;
                            has_explicit_location = true;
                            if (form_value.BlockData())
                            {
                                const DWARFDataExtractor& debug_info_data = get_debug_info_data();

                                uint32_t block_offset = form_value.BlockData() - debug_info_data.GetDataStart();
                                uint32_t block_length = form_value.Unsigned();
                                location.CopyOpcodeData(module, get_debug_info_data(), block_offset, block_length);
                            }
                            else
                            {
                                const DWARFDataExtractor&    debug_loc_data = get_debug_loc_data();
                                const dw_offset_t debug_loc_offset = form_value.Unsigned();

                                size_t loc_list_length = DWARFLocationList::Size(debug_loc_data, debug_loc_offset);
                                if (loc_list_length > 0)
                                {
                                    location.CopyOpcodeData(module, debug_loc_data, debug_loc_offset, loc_list_length);
                                    assert (func_low_pc != LLDB_INVALID_ADDRESS);
                                    location.SetLocationListSlide (func_low_pc - attributes.CompileUnitAtIndex(i)->GetBaseAddress());
                                }
                            }
                        }
                        break;

                    case DW_AT_artificial:      is_artificial = form_value.Boolean(); break;
                    case DW_AT_accessibility:   break; //accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); break;
                    case DW_AT_declaration:
                    case DW_AT_description:
                    case DW_AT_endianity:
                    case DW_AT_segment:
                    case DW_AT_start_scope:
                    case DW_AT_visibility:
                    default:
                    case DW_AT_abstract_origin:
                    case DW_AT_sibling:
                    case DW_AT_specification:
                        break;
                    }
                }
            }

            ValueType scope = eValueTypeInvalid;

            const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(die);
            dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
            SymbolContextScope * symbol_context_scope = NULL;

            if (!mangled)
            {
                // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to
                // generate fully qualified names of global variables with commands like "frame var j".
                // For example, if j were an int variable holding a value 4 and declared in a namespace
                // B which in turn is contained in a namespace A, the command "frame var j" returns
                // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able
                // to generate a fully qualified name from the declaration context.
                if (die->GetParent()->Tag() == DW_TAG_compile_unit &&
                    LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType()))
                {
                    DWARFDeclContext decl_ctx;

                    die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx);
                    mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString();
                }
            }

            // DWARF doesn't specify if a DW_TAG_variable is a local, global
            // or static variable, so we have to do a little digging by
            // looking at the location of a variable to see if it contains
            // a DW_OP_addr opcode _somewhere_ in the definition. I say
            // somewhere because clang likes to combine small global variables
            // into the same symbol and have locations like:
            // DW_OP_addr(0x1000), DW_OP_constu(2), DW_OP_plus
            // So if we don't have a DW_TAG_formal_parameter, we can look at
            // the location to see if it contains a DW_OP_addr opcode, and
            // then we can correctly classify  our variables.
            if (tag == DW_TAG_formal_parameter)
                scope = eValueTypeVariableArgument;
            else
            {
                bool op_error = false;
                // Check if the location has a DW_OP_addr with any address value...
                lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
                if (!location_is_const_value_data)
                {
                    location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
                    if (op_error)
                    {
                        StreamString strm;
                        location.DumpLocationForAddress (&strm, eDescriptionLevelFull, 0, 0, NULL);
                        GetObjectFile()->GetModule()->ReportError ("0x%8.8x: %s has an invalid location: %s", die->GetOffset(), DW_TAG_value_to_name(die->Tag()), strm.GetString().c_str());
                    }
                }

                if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
                {
                    if (is_external)
                        scope = eValueTypeVariableGlobal;
                    else
                        scope = eValueTypeVariableStatic;
                    
                    
                    SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
                    
                    if (debug_map_symfile)
                    {
                        // When leaving the DWARF in the .o files on darwin,
                        // when we have a global variable that wasn't initialized,
                        // the .o file might not have allocated a virtual
                        // address for the global variable. In this case it will
                        // have created a symbol for the global variable
                        // that is undefined/data and external and the value will
                        // be the byte size of the variable. When we do the
                        // address map in SymbolFileDWARFDebugMap we rely on
                        // having an address, we need to do some magic here
                        // so we can get the correct address for our global
                        // variable. The address for all of these entries
                        // will be zero, and there will be an undefined symbol
                        // in this object file, and the executable will have
                        // a matching symbol with a good address. So here we
                        // dig up the correct address and replace it in the
                        // location for the variable, and set the variable's
                        // symbol context scope to be that of the main executable
                        // so the file address will resolve correctly.
                        bool linked_oso_file_addr = false;
                        if (is_external && location_DW_OP_addr == 0)
                        {
                            // we have a possible uninitialized extern global
                            ConstString const_name(mangled ? mangled : name);
                            ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
                            if (debug_map_objfile)
                            {
                                Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
                                if (debug_map_symtab)
                                {
                                    Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
                                                                                                           eSymbolTypeData,
                                                                                                           Symtab::eDebugYes,
                                                                                                           Symtab::eVisibilityExtern);
                                    if (exe_symbol)
                                    {
                                        if (exe_symbol->ValueIsAddress())
                                        {
                                            const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
                                            if (exe_file_addr != LLDB_INVALID_ADDRESS)
                                            {
                                                if (location.Update_DW_OP_addr (exe_file_addr))
                                                {
                                                    linked_oso_file_addr = true;
                                                    symbol_context_scope = exe_symbol;
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (!linked_oso_file_addr)
                        {
                            // The DW_OP_addr is not zero, but it contains a .o file address which
                            // needs to be linked up correctly.
                            const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
                            if (exe_file_addr != LLDB_INVALID_ADDRESS)
                            {
                                // Update the file address for this variable
                                location.Update_DW_OP_addr (exe_file_addr);
                            }
                            else
                            {
                                // Variable didn't make it into the final executable
                                return var_sp;
                            }
                        }
                    }
                }
                else
                {
                    scope = eValueTypeVariableLocal;
                }
            }

            if (symbol_context_scope == NULL)
            {
                switch (parent_tag)
                {
                case DW_TAG_subprogram:
                case DW_TAG_inlined_subroutine:
                case DW_TAG_lexical_block:
                    if (sc.function)
                    {
                        symbol_context_scope = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
                        if (symbol_context_scope == NULL)
                            symbol_context_scope = sc.function;
                    }
                    break;
                
                default:
                    symbol_context_scope = sc.comp_unit;
                    break;
                }
            }

            if (symbol_context_scope)
            {
                SymbolFileTypeSP type_sp(new SymbolFileType(*this, type_uid));
                
                if (const_value.Form() && type_sp && type_sp->GetType())
                    location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), dwarf_cu->GetAddressByteSize());
                
                var_sp.reset (new Variable (MakeUserID(die->GetOffset()), 
                                            name, 
                                            mangled,
                                            type_sp,
                                            scope, 
                                            symbol_context_scope, 
                                            &decl, 
                                            location, 
                                            is_external, 
                                            is_artificial));
                
                var_sp->SetLocationIsConstantValueData (location_is_const_value_data);
            }
            else
            {
                // Not ready to parse this variable yet. It might be a global
                // or static variable that is in a function scope and the function
                // in the symbol context wasn't filled in yet
                return var_sp;
            }
        }
        // Cache var_sp even if NULL (the variable was just a specification or
        // was missing vital information to be able to be displayed in the debugger
        // (missing location due to optimization, etc)) so we don't re-parse
        // this DIE over and over later...
        m_die_to_variable_sp[die] = var_sp;
    }
    return var_sp;
}


const DWARFDebugInfoEntry *
SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset, 
                                                   dw_offset_t spec_block_die_offset,
                                                   DWARFCompileUnit **result_die_cu_handle)
{
    // Give the concrete function die specified by "func_die_offset", find the 
    // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
    // to "spec_block_die_offset"
    DWARFDebugInfo* info = DebugInfo();

    const DWARFDebugInfoEntry *die = info->GetDIEPtrWithCompileUnitHint(func_die_offset, result_die_cu_handle);
    if (die)
    {
        assert (*result_die_cu_handle);
        return FindBlockContainingSpecification (*result_die_cu_handle, die, spec_block_die_offset, result_die_cu_handle);
    }
    return NULL;
}


const DWARFDebugInfoEntry *
SymbolFileDWARF::FindBlockContainingSpecification(DWARFCompileUnit* dwarf_cu,
                                                  const DWARFDebugInfoEntry *die,
                                                  dw_offset_t spec_block_die_offset,
                                                  DWARFCompileUnit **result_die_cu_handle)
{
    if (die)
    {
        switch (die->Tag())
        {
        case DW_TAG_subprogram:
        case DW_TAG_inlined_subroutine:
        case DW_TAG_lexical_block:
            {
                if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_specification, DW_INVALID_OFFSET) == spec_block_die_offset)
                {
                    *result_die_cu_handle = dwarf_cu;
                    return die;
                }

                if (die->GetAttributeValueAsReference (this, dwarf_cu, DW_AT_abstract_origin, DW_INVALID_OFFSET) == spec_block_die_offset)
                {
                    *result_die_cu_handle = dwarf_cu;
                    return die;
                }
            }
            break;
        }

        // Give the concrete function die specified by "func_die_offset", find the 
        // concrete block whose DW_AT_specification or DW_AT_abstract_origin points
        // to "spec_block_die_offset"
        for (const DWARFDebugInfoEntry *child_die = die->GetFirstChild(); child_die != NULL; child_die = child_die->GetSibling())
        {
            const DWARFDebugInfoEntry *result_die = FindBlockContainingSpecification (dwarf_cu,
                                                                                      child_die,
                                                                                      spec_block_die_offset,
                                                                                      result_die_cu_handle);
            if (result_die)
                return result_die;
        }
    }
    
    *result_die_cu_handle = NULL;
    return NULL;
}

size_t
SymbolFileDWARF::ParseVariables
(
    const SymbolContext& sc,
    DWARFCompileUnit* dwarf_cu,
    const lldb::addr_t func_low_pc,
    const DWARFDebugInfoEntry *orig_die,
    bool parse_siblings,
    bool parse_children,
    VariableList* cc_variable_list
)
{
    if (orig_die == NULL)
        return 0;

    VariableListSP variable_list_sp;

    size_t vars_added = 0;
    const DWARFDebugInfoEntry *die = orig_die;
    while (die != NULL)
    {
        dw_tag_t tag = die->Tag();

        // Check to see if we have already parsed this variable or constant?
        if (m_die_to_variable_sp[die])
        {
            if (cc_variable_list)
                cc_variable_list->AddVariableIfUnique (m_die_to_variable_sp[die]);
        }
        else
        {
            // We haven't already parsed it, lets do that now.
            if ((tag == DW_TAG_variable) ||
                (tag == DW_TAG_constant) ||
                (tag == DW_TAG_formal_parameter && sc.function))
            {
                if (variable_list_sp.get() == NULL)
                {
                    const DWARFDebugInfoEntry *sc_parent_die = GetParentSymbolContextDIE(orig_die);
                    dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0;
                    switch (parent_tag)
                    {
                        case DW_TAG_compile_unit:
                            if (sc.comp_unit != NULL)
                            {
                                variable_list_sp = sc.comp_unit->GetVariableList(false);
                                if (variable_list_sp.get() == NULL)
                                {
                                    variable_list_sp.reset(new VariableList());
                                    sc.comp_unit->SetVariableList(variable_list_sp);
                                }
                            }
                            else
                            {
                                GetObjectFile()->GetModule()->ReportError ("parent 0x%8.8" PRIx64 " %s with no valid compile unit in symbol context for 0x%8.8" PRIx64 " %s.\n",
                                                                           MakeUserID(sc_parent_die->GetOffset()),
                                                                           DW_TAG_value_to_name (parent_tag),
                                                                           MakeUserID(orig_die->GetOffset()),
                                                                           DW_TAG_value_to_name (orig_die->Tag()));
                            }
                            break;
                            
                        case DW_TAG_subprogram:
                        case DW_TAG_inlined_subroutine:
                        case DW_TAG_lexical_block:
                            if (sc.function != NULL)
                            {
                                // Check to see if we already have parsed the variables for the given scope
                                
                                Block *block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(sc_parent_die->GetOffset()));
                                if (block == NULL)
                                {
                                    // This must be a specification or abstract origin with 
                                    // a concrete block counterpart in the current function. We need
                                    // to find the concrete block so we can correctly add the 
                                    // variable to it
                                    DWARFCompileUnit *concrete_block_die_cu = dwarf_cu;
                                    const DWARFDebugInfoEntry *concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(), 
                                                                                                                      sc_parent_die->GetOffset(), 
                                                                                                                      &concrete_block_die_cu);
                                    if (concrete_block_die)
                                        block = sc.function->GetBlock(true).FindBlockByID(MakeUserID(concrete_block_die->GetOffset()));
                                }
                                
                                if (block != NULL)
                                {
                                    const bool can_create = false;
                                    variable_list_sp = block->GetBlockVariableList (can_create);
                                    if (variable_list_sp.get() == NULL)
                                    {
                                        variable_list_sp.reset(new VariableList());
                                        block->SetVariableList(variable_list_sp);
                                    }
                                }
                            }
                            break;
                            
                        default:
                             GetObjectFile()->GetModule()->ReportError ("didn't find appropriate parent DIE for variable list for 0x%8.8" PRIx64 " %s.\n",
                                                                        MakeUserID(orig_die->GetOffset()),
                                                                        DW_TAG_value_to_name (orig_die->Tag()));
                            break;
                    }
                }
                
                if (variable_list_sp)
                {
                    VariableSP var_sp (ParseVariableDIE(sc, dwarf_cu, die, func_low_pc));
                    if (var_sp)
                    {
                        variable_list_sp->AddVariableIfUnique (var_sp);
                        if (cc_variable_list)
                            cc_variable_list->AddVariableIfUnique (var_sp);
                        ++vars_added;
                    }
                }
            }
        }

        bool skip_children = (sc.function == NULL && tag == DW_TAG_subprogram);

        if (!skip_children && parse_children && die->HasChildren())
        {
            vars_added += ParseVariables(sc, dwarf_cu, func_low_pc, die->GetFirstChild(), true, true, cc_variable_list);
        }

        if (parse_siblings)
            die = die->GetSibling();
        else
            die = NULL;
    }
    return vars_added;
}

//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
ConstString
SymbolFileDWARF::GetPluginName()
{
    return GetPluginNameStatic();
}

uint32_t
SymbolFileDWARF::GetPluginVersion()
{
    return 1;
}

void
SymbolFileDWARF::CompleteTagDecl (void *baton, clang::TagDecl *decl)
{
    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
    ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
    if (clang_type)
        symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
}

void
SymbolFileDWARF::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *decl)
{
    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
    ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl);
    if (clang_type)
        symbol_file_dwarf->ResolveClangOpaqueTypeDefinition (clang_type);
}

void
SymbolFileDWARF::DumpIndexes ()
{
    StreamFile s(stdout, false);
    
    s.Printf ("DWARF index for (%s) '%s':",
              GetObjectFile()->GetModule()->GetArchitecture().GetArchitectureName(),
              GetObjectFile()->GetFileSpec().GetPath().c_str());
    s.Printf("\nFunction basenames:\n");    m_function_basename_index.Dump (&s);
    s.Printf("\nFunction fullnames:\n");    m_function_fullname_index.Dump (&s);
    s.Printf("\nFunction methods:\n");      m_function_method_index.Dump (&s);
    s.Printf("\nFunction selectors:\n");    m_function_selector_index.Dump (&s);
    s.Printf("\nObjective C class selectors:\n");    m_objc_class_selectors_index.Dump (&s);
    s.Printf("\nGlobals and statics:\n");   m_global_index.Dump (&s); 
    s.Printf("\nTypes:\n");                 m_type_index.Dump (&s);
    s.Printf("\nNamepaces:\n");             m_namespace_index.Dump (&s);
}

void
SymbolFileDWARF::SearchDeclContext (const clang::DeclContext *decl_context, 
                                    const char *name, 
                                    llvm::SmallVectorImpl <clang::NamedDecl *> *results)
{    
    DeclContextToDIEMap::iterator iter = m_decl_ctx_to_die.find(decl_context);
    
    if (iter == m_decl_ctx_to_die.end())
        return;
    
    for (DIEPointerSet::iterator pos = iter->second.begin(), end = iter->second.end(); pos != end; ++pos)
    {
        const DWARFDebugInfoEntry *context_die = *pos;
    
        if (!results)
            return;
        
        DWARFDebugInfo* info = DebugInfo();
        
        DIEArray die_offsets;
        
        DWARFCompileUnit* dwarf_cu = NULL;
        const DWARFDebugInfoEntry* die = NULL;
        
        if (m_using_apple_tables)
        {
            if (m_apple_types_ap.get())
                m_apple_types_ap->FindByName (name, die_offsets);
        }
        else
        {
            if (!m_indexed)
                Index ();
            
            m_type_index.Find (ConstString(name), die_offsets);
        }
        
        const size_t num_matches = die_offsets.size();
        
        if (num_matches)
        {
            for (size_t i = 0; i < num_matches; ++i)
            {
                const dw_offset_t die_offset = die_offsets[i];
                die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu);

                if (die->GetParent() != context_die)
                    continue;
                
                Type *matching_type = ResolveType (dwarf_cu, die);
                
                clang::QualType qual_type = matching_type->GetClangForwardType().GetQualType();
                
                if (const clang::TagType *tag_type = llvm::dyn_cast<clang::TagType>(qual_type.getTypePtr()))
                {
                    clang::TagDecl *tag_decl = tag_type->getDecl();
                    results->push_back(tag_decl);
                }
                else if (const clang::TypedefType *typedef_type = llvm::dyn_cast<clang::TypedefType>(qual_type.getTypePtr()))
                {
                    clang::TypedefNameDecl *typedef_decl = typedef_type->getDecl();
                    results->push_back(typedef_decl); 
                }
            }
        }
    }
}

void
SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton,
                                                 const clang::DeclContext *decl_context,
                                                 clang::DeclarationName decl_name,
                                                 llvm::SmallVectorImpl <clang::NamedDecl *> *results)
{
    
    switch (decl_context->getDeclKind())
    {
    case clang::Decl::Namespace:
    case clang::Decl::TranslationUnit:
        {
            SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
            symbol_file_dwarf->SearchDeclContext (decl_context, decl_name.getAsString().c_str(), results);
        }
        break;
    default:
        break;
    }
}

bool
SymbolFileDWARF::LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size,
                                  uint64_t &alignment,
                                  llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
                                  llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
                                  llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
{
    SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton;
    return symbol_file_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets);
}

bool
SymbolFileDWARF::LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment,
                                  llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets,
                                  llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets,
                                  llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets)
{
    Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
    RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl);
    bool success = false;
    base_offsets.clear();
    vbase_offsets.clear();
    if (pos != m_record_decl_to_layout_map.end())
    {
        bit_size = pos->second.bit_size;
        alignment = pos->second.alignment;
        field_offsets.swap(pos->second.field_offsets);
        base_offsets.swap (pos->second.base_offsets);
        vbase_offsets.swap (pos->second.vbase_offsets);
        m_record_decl_to_layout_map.erase(pos);
        success = true;
    }
    else
    {
        bit_size = 0;
        alignment = 0;
        field_offsets.clear();
    }
    
    if (log)
        GetObjectFile()->GetModule()->LogMessage (log, 
                                                  "SymbolFileDWARF::LayoutRecordType (record_decl = %p, bit_size = %" PRIu64 ", alignment = %" PRIu64 ", field_offsets[%u],base_offsets[%u], vbase_offsets[%u]) success = %i",
                                                  static_cast<const void*>(record_decl),
                                                  bit_size, alignment,
                                                  static_cast<uint32_t>(field_offsets.size()),
                                                  static_cast<uint32_t>(base_offsets.size()),
                                                  static_cast<uint32_t>(vbase_offsets.size()),
                                                  success);
    return success;
}


SymbolFileDWARFDebugMap *
SymbolFileDWARF::GetDebugMapSymfile ()
{
    if (m_debug_map_symfile == NULL && !m_debug_map_module_wp.expired())
    {
        lldb::ModuleSP module_sp (m_debug_map_module_wp.lock());
        if (module_sp)
        {
            SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
            if (sym_vendor)
                m_debug_map_symfile = (SymbolFileDWARFDebugMap *)sym_vendor->GetSymbolFile();
        }
    }
    return m_debug_map_symfile;
}


