tberghammer updated the summary for this revision.
tberghammer updated this revision to Diff 33676.
tberghammer added a comment.

[RFC] DO NOT COMMIT!

Update the design based on the discussion for the previous diff.

The current version have ~35 failures with split dwarf (most of them hit an 
assertion in clang) and causes a minor regression in non-split dwarf handling. 
I am working on these issues, but would like to get a feedback about the 
current design because a major change there can shuffle up everything.


http://reviews.llvm.org/D12291

Files:
  include/lldb/Symbol/ObjectFile.h
  source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
  source/Plugins/SymbolFile/DWARF/CMakeLists.txt
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
  source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDIE.h
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
  source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
  source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
  source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
  source/Plugins/SymbolFile/DWARF/NameToDIE.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
  source/Symbol/ObjectFile.cpp

Index: source/Symbol/ObjectFile.cpp
===================================================================
--- source/Symbol/ObjectFile.cpp
+++ source/Symbol/ObjectFile.cpp
@@ -602,15 +602,23 @@
 }
 
 SectionList *
-ObjectFile::GetSectionList()
+ObjectFile::GetSectionList(bool update_module_section_list)
 {
     if (m_sections_ap.get() == nullptr)
     {
-        ModuleSP module_sp(GetModule());
-        if (module_sp)
+        if (update_module_section_list)
         {
-            lldb_private::Mutex::Locker locker(module_sp->GetMutex());
-            CreateSections(*module_sp->GetUnifiedSectionList());
+            ModuleSP module_sp(GetModule());
+            if (module_sp)
+            {
+                lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+                CreateSections(*module_sp->GetUnifiedSectionList());
+            }
+        }
+        else
+        {
+            SectionList unified_section_list;
+            CreateSections(unified_section_list);
         }
     }
     return m_sections_ap.get();
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
===================================================================
--- /dev/null
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -0,0 +1,49 @@
+//===-- SymbolFileDWARFDwo.h ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
+#define SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "SymbolFileDWARF.h"
+
+class SymbolFileDWARFDwo : public SymbolFileDWARF
+{
+public:
+    SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit* dwarf_cu);
+
+    virtual
+    ~SymbolFileDWARFDwo() = default;
+    
+    const lldb_private::DWARFDataExtractor&
+    GetCachedSectionData(uint32_t got_flag,
+                         lldb::SectionType sect_type,
+                         lldb_private::DWARFDataExtractor &data) override;
+    
+    lldb::CompUnitSP
+    ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) override;
+
+    DWARFCompileUnit*
+    GetCompileUnit();
+
+    DWARFCompileUnit*
+    GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit) override;
+
+    void
+    AddTypeForwardDeclaration(const lldb_private::CompilerType& clang_type, const DWARFDIE& die) override;
+
+protected:
+    lldb::ObjectFileSP m_obj_file_sp;
+    DWARFCompileUnit* m_base_dwarf_cu;
+};
+
+#endif  // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
===================================================================
--- /dev/null
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -0,0 +1,87 @@
+//===-- SymbolFileDWARFDwo.cpp ----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "SymbolFileDWARFDwo.h"
+
+#include "lldb/Core/Section.h"
+#include "lldb/Symbol/ObjectFile.h"
+
+#include "DWARFCompileUnit.h"
+#include "DWARFDebugInfo.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile, DWARFCompileUnit* dwarf_cu) :
+    SymbolFileDWARF(objfile.get()),
+    m_obj_file_sp(objfile),
+    m_base_dwarf_cu(dwarf_cu)
+{
+}
+
+const lldb_private::DWARFDataExtractor&
+SymbolFileDWARFDwo::GetCachedSectionData(uint32_t got_flag,
+                                         lldb::SectionType sect_type,
+                                         lldb_private::DWARFDataExtractor &data)
+{
+    if (!m_flags.IsClear (got_flag))
+        return data;
+
+    const SectionList* section_list = m_obj_file->GetSectionList(false /* update_module_section_list */);
+    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());
+                m_flags.Set (got_flag);
+                return data;
+            }
+
+            if (m_obj_file->ReadSectionData(section_sp.get(), data) != 0)
+            {
+                m_flags.Set (got_flag);
+                return data;
+            }
+
+            data.Clear();
+        }
+    }
+    return SymbolFileDWARF::GetCachedSectionData(got_flag, sect_type, data);
+}
+
+lldb::CompUnitSP
+SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit* dwarf_cu, uint32_t cu_idx)
+{
+    assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit called with incompatible compile unit");
+    return m_base_dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(m_base_dwarf_cu, UINT32_MAX);
+}
+
+DWARFCompileUnit*
+SymbolFileDWARFDwo::GetCompileUnit()
+{
+    assert(GetNumCompileUnits() == 1 && "Only dwo files with 1 compile unit is supported");
+    return DebugInfo()->GetCompileUnitAtIndex(0);
+}
+
+DWARFCompileUnit*
+SymbolFileDWARFDwo::GetDWARFCompileUnit(lldb_private::CompileUnit *comp_unit)
+{
+    return GetCompileUnit();
+}
+
+void
+SymbolFileDWARFDwo::AddTypeForwardDeclaration(const lldb_private::CompilerType& clang_type,
+                                              const DWARFDIE& die)
+{
+    m_base_dwarf_cu->GetSymbolFileDWARF()->AddTypeForwardDeclaration(clang_type, die);
+}
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -265,7 +265,7 @@
     const DWARFDebugRanges*
     DebugRanges() const;
 
-    const lldb_private::DWARFDataExtractor&
+    virtual const lldb_private::DWARFDataExtractor&
     GetCachedSectionData (uint32_t got_flag, 
                           lldb::SectionType sect_type, 
                           lldb_private::DWARFDataExtractor &data);
@@ -311,6 +311,12 @@
     static DWARFDIE
     GetParentSymbolContextDIE(const DWARFDIE &die);
 
+    virtual lldb::CompUnitSP
+    ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx);
+    
+    virtual void
+    AddTypeForwardDeclaration(const lldb_private::CompilerType& clang_type, const DWARFDIE& die);
+
 protected:
 
     enum
@@ -343,11 +349,7 @@
 
     DISALLOW_COPY_AND_ASSIGN (SymbolFileDWARF);
 
-    lldb::CompUnitSP
-    ParseCompileUnit (DWARFCompileUnit* dwarf_cu,
-                      uint32_t cu_idx);
-
-    DWARFCompileUnit*
+    virtual DWARFCompileUnit*
     GetDWARFCompileUnit (lldb_private::CompileUnit *comp_unit);
 
     DWARFCompileUnit*
@@ -401,7 +403,7 @@
 
     // Given a die_offset, figure out the symbol context representing that die.
     bool
-    ResolveFunction (dw_offset_t offset,
+    ResolveFunction (const DIERef& die_ref,
                      bool include_inlines,
                      lldb_private::SymbolContextList& sc_list);
 
@@ -451,11 +453,6 @@
     lldb::TypeSP
     GetTypeForDIE (const DWARFDIE &die);
 
-    uint32_t
-    FindTypes (std::vector<dw_offset_t> die_offsets,
-               uint32_t max_matches,
-               lldb_private::TypeList& types);
-
     void
     Index();
     
@@ -472,21 +469,19 @@
     GetDebugMapSymfile ();
 
     DWARFDIE
-    FindBlockContainingSpecification (dw_offset_t func_die_offset,
-                                      dw_offset_t spec_block_die_offset);
+    FindBlockContainingSpecification (const DIERef& func_die_ref, dw_offset_t spec_block_die_offset);
 
     DWARFDIE
-    FindBlockContainingSpecification (const DWARFDIE &die,
-                                      dw_offset_t spec_block_die_offset);
+    FindBlockContainingSpecification (const DWARFDIE &die, dw_offset_t spec_block_die_offset);
     
     UniqueDWARFASTTypeMap &
     GetUniqueDWARFASTTypeMap ();
     
     bool
     UserIDMatches (lldb::user_id_t uid) const
     {
         const lldb::user_id_t high_uid = uid & 0xffffffff00000000ull;
-        if (high_uid)
+        if (high_uid != 0 && GetID() != 0)
             return high_uid == GetID();
         return true;
     }
@@ -574,7 +569,7 @@
     typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr;
     typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::VariableSP> DIEToVariableSP;
     typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb::clang_type_t> DIEToClangType;
-    typedef llvm::DenseMap<lldb::clang_type_t, const DWARFDebugInfoEntry *> ClangTypeToDIE;
+    typedef llvm::DenseMap<lldb::clang_type_t, DIERef> ClangTypeToDIE;
     DIEToTypePtr m_die_to_type;
     DIEToVariableSP m_die_to_variable_sp;
     DIEToClangType m_forward_decl_die_to_clang_type;
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -70,6 +70,7 @@
 #include "DWARFFormValue.h"
 #include "DWARFLocationList.h"
 #include "LogChannelDWARF.h"
+#include "SymbolFileDWARFDwo.h"
 #include "SymbolFileDWARFDebugMap.h"
 
 #include <map>
@@ -1381,7 +1382,7 @@
         DWARFDebugInfo* debug_info = DebugInfo();
         if (debug_info)
         {
-            DWARFDIE die = debug_info->GetDIE(type_uid);
+            DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
             if (die)
             {
                 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
@@ -1401,7 +1402,7 @@
         DWARFDebugInfo* debug_info = DebugInfo();
         if (debug_info)
         {
-            DWARFDIE die = debug_info->GetDIE(type_uid);
+            DWARFDIE die = debug_info->GetDIE(DIERef(type_uid));
             if (die)
             {
                 DWARFASTParser *dwarf_ast = die.GetDWARFParser();
@@ -1422,7 +1423,7 @@
         DWARFDebugInfo* debug_info = DebugInfo();
         if (debug_info)
         {
-            DWARFDIE type_die = debug_info->GetDIE (type_uid);
+            DWARFDIE type_die = debug_info->GetDIE (DIERef(type_uid));
             if (type_die)
             {
                 const bool assert_not_being_parsed = true;
@@ -1488,17 +1489,17 @@
 SymbolFileDWARF::HasForwardDeclForClangType (const CompilerType &clang_type)
 {
     CompilerType clang_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(clang_type);
-    return m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType()) != nullptr;
+    return m_forward_decl_clang_type_to_die.count (clang_type_no_qualifiers.GetOpaqueQualType());
 }
 
 
 bool
 SymbolFileDWARF::CompleteType (CompilerType &clang_type)
 {
     // We have a struct/union/class/enum that needs to be fully resolved.
     CompilerType clang_type_no_qualifiers = ClangASTContext::RemoveFastQualifiers(clang_type);
-    const DWARFDebugInfoEntry* die = m_forward_decl_clang_type_to_die.lookup (clang_type_no_qualifiers.GetOpaqueQualType());
-    if (die == NULL)
+    auto die_it = m_forward_decl_clang_type_to_die.find (clang_type_no_qualifiers.GetOpaqueQualType());
+    if (die_it == m_forward_decl_clang_type_to_die.end())
     {
         // We have already resolved this type...
         return true;
@@ -1510,8 +1511,9 @@
     m_forward_decl_clang_type_to_die.erase (clang_type_no_qualifiers.GetOpaqueQualType());
 
     DWARFDebugInfo* debug_info = DebugInfo();
-    DWARFDIE dwarf_die (debug_info->GetCompileUnitContainingDIE (die->GetOffset()), die);
-    Type *type = m_die_to_type.lookup (die);
+    
+    DWARFDIE dwarf_die = debug_info->GetDIE(die_it->getSecond());
+    Type *type = m_die_to_type.lookup (dwarf_die.GetDIE());
 
     Log *log (LogChannelDWARF::GetLogIfAny(DWARF_LOG_DEBUG_INFO|DWARF_LOG_TYPE_COMPLETION));
     if (log)
@@ -1618,8 +1620,7 @@
     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)
     {
@@ -1995,8 +1996,7 @@
 
             bool clear_dies = dwarf_cu->ExtractDIEsIfNeeded (false) > 1;
 
-            dwarf_cu->Index (cu_idx,
-                             m_function_basename_index,
+            dwarf_cu->Index (m_function_basename_index,
                              m_function_fullname_index,
                              m_function_method_index,
                              m_function_selector_index,
@@ -2122,8 +2122,8 @@
         bool done = false;
         for (size_t i=0; i<num_die_matches && !done; ++i)
         {
-            const dw_offset_t die_offset = die_offsets[i];
-            DWARFDIE die = debug_info->GetDIE (die_offset);
+            const DIERef& die_ref = die_offsets[i];
+            DWARFDIE die = debug_info->GetDIE (die_ref);
 
             if (die)
             {
@@ -2164,7 +2164,7 @@
                 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());
+                                                                               die_ref.die_offset, name.GetCString());
                 }
             }
         }
@@ -2210,7 +2210,7 @@
     const uint32_t original_size = variables.GetSize();
 
     DIEArray die_offsets;
-    
+
     if (m_using_apple_tables)
     {
         if (m_apple_names_ap.get())
@@ -2239,8 +2239,8 @@
         DWARFDebugInfo* debug_info = DebugInfo();
         for (size_t i=0; i<num_matches; ++i)
         {
-            const dw_offset_t die_offset = die_offsets[i];
-            DWARFDIE die = debug_info->GetDIE (die_offset);
+            const DIERef& die_ref = die_offsets[i];
+            DWARFDIE die = debug_info->GetDIE (die_ref);
             
             if (die)
             {
@@ -2256,7 +2256,7 @@
                 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());
+                                                                               die_ref.die_offset, regex.GetText());
                 }
             }            
         }
@@ -2268,11 +2268,11 @@
 
 
 bool
-SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset,
+SymbolFileDWARF::ResolveFunction (const DIERef& die_ref,
                                   bool include_inlines,
                                   SymbolContextList& sc_list)
 {
-    DWARFDIE die = DebugInfo()->GetDIE (die_offset);
+    DWARFDIE die = DebugInfo()->GetDIE (die_ref);
     return ResolveFunction (die, include_inlines, sc_list);
 }
     
@@ -2392,10 +2392,7 @@
     if (num_matches)
     {
         for (size_t i=0; i<num_matches; ++i)
-        {
-            const dw_offset_t die_offset = die_offsets[i];
-            ResolveFunction (die_offset, include_inlines, sc_list);
-        }
+            ResolveFunction (die_offsets[i], include_inlines, sc_list);
     }
 }
 
@@ -2488,8 +2485,8 @@
                 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];
-                    DWARFDIE die = info->GetDIE (die_offset);
+                    const DIERef& die_ref = die_offsets[i];
+                    DWARFDIE die = info->GetDIE (die_ref);
                     if (die)
                     {
                         if (!DIEInDeclContext(parent_decl_ctx, die))
@@ -2504,7 +2501,7 @@
                     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_ref.die_offset, name_cstr);
                     }                                    
                 }
             }
@@ -2520,8 +2517,8 @@
                 
                 for (uint32_t i = 0; i < num_matches; i++)
                 {
-                    const dw_offset_t die_offset = die_offsets[i];
-                    DWARFDIE die = info->GetDIE (die_offset);
+                    const DIERef& die_ref = die_offsets[i];
+                    DWARFDIE die = info->GetDIE (die_ref);
                     if (die)
                     {
                         const char *die_name = die.GetName();
@@ -2537,7 +2534,7 @@
                     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_ref.die_offset, name_cstr);
                     }                                    
                 }
                 die_offsets.clear();
@@ -2554,8 +2551,8 @@
                 
                 for (uint32_t i = 0; i < num_matches; i++)
                 {
-                    const dw_offset_t die_offset = die_offsets[i];
-                    DWARFDIE die = info->GetDIE (die_offset);
+                    const DIERef& die_ref = die_offsets[i];
+                    DWARFDIE die = info->GetDIE (die_ref);
                     if (die)
                     {
                         if (!DIEInDeclContext(parent_decl_ctx, die))
@@ -2604,7 +2601,7 @@
                                         else
                                         {
                                             GetObjectFile()->GetModule()->ReportWarning ("function at die offset 0x%8.8x had no function type",
-                                                                                         die_offset);
+                                                                                         die_ref.die_offset);
                                         }
                                     }
                                 }
@@ -2616,7 +2613,7 @@
                     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_ref.die_offset, name_cstr);
                     }                                    
                 }
                 die_offsets.clear();
@@ -2851,8 +2848,8 @@
         DWARFDebugInfo* debug_info = DebugInfo();
         for (size_t i=0; i<num_die_matches; ++i)
         {
-            const dw_offset_t die_offset = die_offsets[i];
-            DWARFDIE die = debug_info->GetDIE (die_offset);
+            const DIERef& die_ref = die_offsets[i];
+            DWARFDIE die = debug_info->GetDIE (die_ref);
 
             if (die)
             {
@@ -2873,7 +2870,7 @@
                 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());
+                                                                               die_ref.die_offset, name.GetCString());
                 }
             }            
 
@@ -2955,8 +2952,8 @@
             DWARFDebugInfo* debug_info = DebugInfo();
             for (size_t i=0; i<num_matches; ++i)
             {
-                const dw_offset_t die_offset = die_offsets[i];
-                DWARFDIE die = debug_info->GetDIE (die_offset);
+                const DIERef& die_ref = die_offsets[i];
+                DWARFDIE die = debug_info->GetDIE (die_ref);
 
                 if (die)
                 {
@@ -2976,7 +2973,7 @@
                     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());
+                                                                   die_ref.die_offset, name.GetCString());
                     }
                 }            
 
@@ -2996,35 +2993,6 @@
     return namespace_decl_ctx;
 }
 
-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;
-}
-
-
 TypeSP
 SymbolFileDWARF::GetTypeForDIE (const DWARFDIE &die)
 {
@@ -3190,8 +3158,8 @@
         DWARFDebugInfo* debug_info = DebugInfo();
         for (size_t i=0; i<num_matches; ++i)
         {
-            const dw_offset_t die_offset = die_offsets[i];
-            DWARFDIE type_die = debug_info->GetDIE (die_offset);
+            const DIERef& die_ref = die_offsets[i];
+            DWARFDIE type_die = debug_info->GetDIE (die_ref);
             
             if (type_die)
             {
@@ -3240,7 +3208,7 @@
                 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());
+                                                               die_ref.die_offset, type_name.GetCString());
                 }
             }            
             
@@ -3414,8 +3382,8 @@
                 DWARFDebugInfo* debug_info = DebugInfo();
                 for (size_t i=0; i<num_matches; ++i)
                 {
-                    const dw_offset_t die_offset = die_offsets[i];
-                    DWARFDIE type_die = debug_info->GetDIE (die_offset);
+                    const DIERef& die_ref = die_offsets[i];
+                    DWARFDIE type_die = debug_info->GetDIE (die_ref);
                     
                     if (type_die)
                     {
@@ -3498,7 +3466,7 @@
                         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());
+                                                                                       die_ref.die_offset, type_name.GetCString());
                         }
                     }            
                     
@@ -3641,9 +3609,9 @@
         
         if (sc.function)
         {
-            DWARFDIE function_die = info->GetDIE(sc.function->GetID());
+            DWARFDIE function_die = info->GetDIE(DIERef(sc.function->GetID()));
             
-            const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsUnsigned (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+            const dw_addr_t func_lo_pc = function_die.GetAttributeValueAsAddress (DW_AT_low_pc, LLDB_INVALID_ADDRESS);
             if (func_lo_pc != LLDB_INVALID_ADDRESS)
             {
                 const size_t num_variables = ParseVariables(sc, function_die.GetFirstChild(), func_lo_pc, true, true);
@@ -3690,7 +3658,6 @@
                         Index ();
 
                     m_global_index.FindAllEntriesForCompileUnit (dwarf_cu->GetOffset(), 
-                                                                 dwarf_cu->GetNextCompileUnitOffset(), 
                                                                  die_offsets);
                 }
 
@@ -3700,8 +3667,8 @@
                     DWARFDebugInfo* debug_info = DebugInfo();
                     for (size_t i=0; i<num_matches; ++i)
                     {
-                        const dw_offset_t die_offset = die_offsets[i];
-                        DWARFDIE die = debug_info->GetDIE (die_offset);
+                        const DIERef& die_ref = die_offsets[i];
+                        DWARFDIE die = debug_info->GetDIE (die_ref);
                         if (die)
                         {
                             VariableSP var_sp (ParseVariableDIE(sc, die, LLDB_INVALID_ADDRESS));
@@ -3715,7 +3682,7 @@
                         {
                             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);
+                                GetObjectFile()->GetModule()->ReportErrorIfModifyDetected ("the DWARF debug information has been modified (.apple_names accelerator table had bad die 0x%8.8x)\n", die_ref.die_offset);
                             }
                         }            
 
@@ -3736,6 +3703,9 @@
     const lldb::addr_t func_low_pc
 )
 {
+    if (die.GetDWARF() != this)
+        return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
+
     VariableSP var_sp;
     if (!die)
         return var_sp;
@@ -3759,7 +3729,7 @@
             const char *mangled = NULL;
             Declaration decl;
             uint32_t i;
-            lldb::user_id_t type_uid = LLDB_INVALID_UID;
+            DIERef type_die_ref;
             DWARFExpression location(die.GetCU());
             bool is_external = false;
             bool is_artificial = false;
@@ -3783,7 +3753,7 @@
                     case DW_AT_name:        name = form_value.AsCString(); break;
                     case DW_AT_linkage_name:
                     case DW_AT_MIPS_linkage_name: mangled = form_value.AsCString(); break;
-                    case DW_AT_type:        type_uid = form_value.Reference(); break;
+                    case DW_AT_type:        type_die_ref = DIERef(die.GetCU()->GetOffset(), 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.
@@ -4058,7 +4028,7 @@
 
             if (symbol_context_scope)
             {
-                SymbolFileTypeSP type_sp(new SymbolFileType(*this, type_uid));
+                SymbolFileTypeSP type_sp(new SymbolFileType(*this, type_die_ref.GetUID()));
                 
                 if (const_value.Form() && type_sp && type_sp->GetType())
                     location.CopyOpcodeData(const_value.Unsigned(), type_sp->GetType()->GetByteSize(), die.GetCU()->GetAddressByteSize());
@@ -4096,13 +4066,13 @@
 
 
 DWARFDIE
-SymbolFileDWARF::FindBlockContainingSpecification (dw_offset_t func_die_offset, 
+SymbolFileDWARF::FindBlockContainingSpecification (const DIERef& func_die_ref,
                                                    dw_offset_t spec_block_die_offset)
 {
     // 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"
-    return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_offset), spec_block_die_offset);
+    return FindBlockContainingSpecification (DebugInfo()->GetDIE (func_die_ref), spec_block_die_offset);
 }
 
 
@@ -4214,7 +4184,7 @@
                                     // a concrete block counterpart in the current function. We need
                                     // to find the concrete block so we can correctly add the 
                                     // variable to it
-                                    const DWARFDIE concrete_block_die = FindBlockContainingSpecification (sc.function->GetID(),
+                                    const DWARFDIE concrete_block_die = FindBlockContainingSpecification (DIERef(sc.function->GetID()),
                                                                                                           sc_parent_die.GetOffset());
                                     if (concrete_block_die)
                                         block = sc.function->GetBlock(true).FindBlockByID(concrete_block_die.GetID());
@@ -4320,4 +4290,9 @@
     return m_debug_map_symfile;
 }
 
-
+void
+SymbolFileDWARF::AddTypeForwardDeclaration(const CompilerType& clang_type, const DWARFDIE& die)
+{
+    m_forward_decl_die_to_clang_type[die.GetDIE()] = clang_type.GetOpaqueQualType();
+    m_forward_decl_clang_type_to_die[ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] = die.GetDIERef();
+}
Index: source/Plugins/SymbolFile/DWARF/NameToDIE.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/NameToDIE.h
+++ source/Plugins/SymbolFile/DWARF/NameToDIE.h
@@ -10,56 +10,83 @@
 #ifndef SymbolFileDWARF_NameToDIE_h_
 #define SymbolFileDWARF_NameToDIE_h_
 
-#include "lldb/Core/UniqueCStringMap.h"
-
 #include <functional>
 
+#include "lldb/Core/dwarf.h"
+#include "lldb/Core/UniqueCStringMap.h"
 #include "lldb/lldb-defines.h"
 
 class SymbolFileDWARF;
 
-typedef std::vector<uint32_t> DIEArray;
+struct DIERef
+{
+    DIERef() :
+        cu_offset(DW_INVALID_OFFSET),
+        die_offset(DW_INVALID_OFFSET)
+    {}
+
+    explicit DIERef(dw_offset_t d) :
+        cu_offset(DW_INVALID_OFFSET),
+        die_offset(d)
+    {}
+
+    DIERef(dw_offset_t c, dw_offset_t d) :
+        cu_offset(c),
+        die_offset(d)
+    {}
+
+    explicit DIERef(lldb::user_id_t uid) :
+        cu_offset(uid>>32),
+        die_offset(uid&0xffffffff)
+    {}
+
+    lldb::user_id_t
+    GetUID() const
+    {
+        return ((lldb::user_id_t)cu_offset) << 32 | die_offset;
+    }
+
+    dw_offset_t cu_offset;
+    dw_offset_t die_offset;
+};
+
+typedef std::vector<DIERef> DIEArray;
 
 class NameToDIE
 {
 public:
-    NameToDIE () :   
+    NameToDIE () :
         m_map()
     {
     }
-    
+
     ~NameToDIE ()
     {
     }
-    
+
     void
     Dump (lldb_private::Stream *s);
 
     void
-    Insert (const lldb_private::ConstString& name, uint32_t die_offset);
+    Insert (const lldb_private::ConstString& name, const DIERef& die_ref);
 
     void
     Finalize();
 
     size_t
-    Find (const lldb_private::ConstString &name, 
-          DIEArray &info_array) const;
+    Find (const lldb_private::ConstString &name, DIEArray &info_array) const;
     
     size_t
-    Find (const lldb_private::RegularExpression& regex, 
-          DIEArray &info_array) const;
+    Find (const lldb_private::RegularExpression& regex, DIEArray &info_array) const;
 
     size_t
-    FindAllEntriesForCompileUnit (uint32_t cu_offset, 
-                                  uint32_t cu_end_offset, 
-                                  DIEArray &info_array) const;
+    FindAllEntriesForCompileUnit (dw_offset_t cu_offset, DIEArray &info_array) const;
 
     void
-    ForEach (std::function <bool(const char *name, uint32_t die_offset)> const &callback) const;
+    ForEach (std::function <bool(const char *name, const DIERef& die_ref)> const &callback) const;
 
 protected:
-    lldb_private::UniqueCStringMap<uint32_t> m_map;
-
+    lldb_private::UniqueCStringMap<DIERef> m_map;
 };
 
 #endif  // SymbolFileDWARF_NameToDIE_h_
Index: source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
+++ source/Plugins/SymbolFile/DWARF/NameToDIE.cpp
@@ -18,6 +18,7 @@
 #include "DWARFDebugInfo.h"
 #include "DWARFDebugInfoEntry.h"
 #include "SymbolFileDWARF.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -29,9 +30,9 @@
 }
 
 void
-NameToDIE::Insert (const ConstString& name, uint32_t die_offset)
+NameToDIE::Insert (const ConstString& name, const DIERef& die_ref)
 {
-    m_map.Append(name.GetCString(), die_offset);
+    m_map.Append(name.GetCString(), die_ref);
 }
 
 size_t
@@ -47,17 +48,15 @@
 }
 
 size_t
-NameToDIE::FindAllEntriesForCompileUnit (uint32_t cu_offset, 
-                                         uint32_t cu_end_offset, 
-                                         DIEArray &info_array) const
+NameToDIE::FindAllEntriesForCompileUnit (dw_offset_t cu_offset, DIEArray &info_array) const
 {
     const size_t initial_size = info_array.size();
     const uint32_t size = m_map.GetSize();
     for (uint32_t i=0; i<size; ++i)
     {
-        const uint32_t die_offset = m_map.GetValueAtIndexUnchecked(i);
-        if (cu_offset < die_offset && die_offset < cu_end_offset)
-            info_array.push_back (die_offset);
+        const DIERef& die_ref = m_map.GetValueAtIndexUnchecked(i);
+        if (cu_offset == die_ref.cu_offset)
+            info_array.push_back (die_ref);
     }
     return info_array.size() - initial_size;
 }
@@ -69,18 +68,18 @@
     for (uint32_t i=0; i<size; ++i)
     {
         const char *cstr = m_map.GetCStringAtIndex(i);
-        s->Printf("%p: {0x%8.8x} \"%s\"\n", (const void *)cstr, m_map.GetValueAtIndexUnchecked(i), cstr);
+        const DIERef& die_ref = m_map.GetValueAtIndexUnchecked(i);
+        s->Printf("%p: {0x%8.8x/0x%8.8x} \"%s\"\n", cstr, die_ref.cu_offset, die_ref.die_offset, cstr);
     }
 }
 
 void
-NameToDIE::ForEach (std::function <bool(const char *name, uint32_t die_offset)> const &callback) const
+NameToDIE::ForEach (std::function <bool(const char *name, const DIERef& die_ref)> const &callback) const
 {
     const uint32_t size = m_map.GetSize();
     for (uint32_t i=0; i<size; ++i)
     {
-        if (!callback(m_map.GetCStringAtIndexUnchecked(i),
-                      m_map.GetValueAtIndexUnchecked (i)))
+        if (!callback(m_map.GetCStringAtIndexUnchecked(i), m_map.GetValueAtIndexUnchecked (i)))
             break;
     }
 }
Index: source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
+++ source/Plugins/SymbolFile/DWARF/HashedNameToDIE.h
@@ -52,13 +52,14 @@
 
     struct DIEInfo
     {
+        dw_offset_t cu_offset;
         dw_offset_t offset;  // The DIE offset
         dw_tag_t tag;
         uint32_t type_flags; // Any flags for this DIEInfo
         uint32_t qualified_name_hash; // A 32 bit hash of the fully qualified name
 
         DIEInfo ();
-        DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
+        DIEInfo (dw_offset_t c, dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h);
     };
 
     struct Atom
@@ -178,7 +179,7 @@
         Result
         GetHashDataForName (const char *name,
                             lldb::offset_t* hash_data_offset_ptr,
-                            Pair &pair) const;
+                            Pair &pair) const override;
 
         const lldb_private::DWARFDataExtractor &m_data;
         const lldb_private::DWARFDataExtractor &m_string_table;
@@ -200,8 +201,6 @@
                      const uint32_t qualified_name_hash,
                      DIEArray &die_offsets);
 
-    
-
     static void
     ExtractClassOrStructDIEArray (const DIEInfoArray &die_info_array,
                                   bool return_implementation_only_if_available,
@@ -217,5 +216,4 @@
     GetAtomTypeName (uint16_t atom);
 };
 
-
 #endif  // SymbolFileDWARF_HashedNameToDIE_h_
Index: source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -14,7 +14,7 @@
 {
     const size_t count = die_info_array.size();
     for (size_t i=0; i<count; ++i)
-        die_offsets.push_back (die_info_array[i].offset);
+        die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
 }
 
 void
@@ -39,7 +39,7 @@
                     tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
             }
             if (tag_matches)
-                die_offsets.push_back (die_info_array[i].offset);
+                die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
         }
     }
 }
@@ -69,7 +69,7 @@
                     tag_matches = tag == DW_TAG_structure_type || tag == DW_TAG_class_type;
             }
             if (tag_matches)
-                die_offsets.push_back (die_info_array[i].offset);
+                die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
         }
     }
 }
@@ -92,19 +92,19 @@
                     // We found the one true definition for this class, so
                     // only return that
                     die_offsets.clear();                        
-                    die_offsets.push_back (die_info_array[i].offset);
+                    die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
                     return;
                 }
                 else
                 {
                     // Put the one true definition as the first entry so it
                     // matches first
-                    die_offsets.insert (die_offsets.begin(), die_info_array[i].offset);
+                    die_offsets.emplace(die_offsets.begin(), die_info_array[i].cu_offset, die_info_array[i].offset);
                 }
             }
             else
             {
-                die_offsets.push_back (die_info_array[i].offset);
+                die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
             }
         }
     }
@@ -120,7 +120,7 @@
     for (size_t i=0; i<count; ++i)
     {
         if ((die_info_array[i].type_flags & type_flag_mask) == type_flag_value)
-            die_offsets.push_back (die_info_array[i].offset);
+            die_offsets.emplace_back(die_info_array[i].cu_offset, die_info_array[i].offset);
     }
 }
 
@@ -148,7 +148,12 @@
 {
 }
 
-DWARFMappedHash::DIEInfo::DIEInfo (dw_offset_t o, dw_tag_t t, uint32_t f, uint32_t h) :
+DWARFMappedHash::DIEInfo::DIEInfo (dw_offset_t c,
+                                   dw_offset_t o,
+                                   dw_tag_t t,
+                                   uint32_t f,
+                                   uint32_t h) :
+    cu_offset (c),
     offset (o),
     tag (t),
     type_flags (f),
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -115,13 +115,6 @@
                     DWARFAttributes& attrs,
                     uint32_t curr_depth = 0) const; // "curr_depth" for internal use only, don't set this yourself!!!
 
-    dw_offset_t GetAttributeValue(
-                    SymbolFileDWARF* dwarf2Data,
-                    const DWARFCompileUnit* cu,
-                    const dw_attr_t attr,
-                    DWARFFormValue& formValue,
-                    dw_offset_t* end_attr_offset_ptr = NULL) const;
-
     const char* GetAttributeValueAsString(
                     SymbolFileDWARF* dwarf2Data,
                     const DWARFCompileUnit* cu,
@@ -146,6 +139,12 @@
                     const dw_attr_t attr,
                     int64_t fail_value) const;
 
+    uint64_t    GetAttributeValueAsAddress(
+                    SymbolFileDWARF* dwarf2Data,
+                    const DWARFCompileUnit* cu,
+                    const dw_attr_t attr,
+                    uint64_t fail_value) const;
+
     dw_addr_t   GetAttributeHighPC(
                     SymbolFileDWARF* dwarf2Data,
                     const DWARFCompileUnit* cu,
@@ -382,14 +381,19 @@
                        DWARFDebugInfoEntry::collection &die_collection);
 
 protected:
+    dw_offset_t GetAttributeValue(SymbolFileDWARF* dwarf2Data,
+                                  const DWARFCompileUnit* cu,
+                                  const dw_attr_t attr,
+                                  DWARFFormValue& formValue,
+                                  dw_offset_t* end_attr_offset_ptr = nullptr) const;
+
     dw_offset_t m_offset;           // Offset within the .debug_info of the start of this entry
     uint32_t    m_parent_idx;       // How many to subtract from "this" to get the parent. If zero this die has no parent
     uint32_t    m_sibling_idx:31,   // How many to add to "this" to get the sibling.
                 m_empty_children:1; // If a DIE says it had children, yet it just contained a NULL tag, this will be set.
     uint32_t    m_abbr_idx:DIE_ABBR_IDX_BITSIZE,
                 m_has_children:1,   // Set to 1 if this DIE has children
                 m_tag:16;           // A copy of the DW_TAG value so we don't have to go through the compile unit abbrev table
-                
 };
 
 #endif  // SymbolFileDWARF_DWARFDebugInfoEntry_h_
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -19,7 +19,6 @@
 #include "lldb/Symbol/ObjectFile.h"
 
 #include "DWARFCompileUnit.h"
-#include "SymbolFileDWARF.h"
 #include "DWARFDebugAbbrev.h"
 #include "DWARFDebugAranges.h"
 #include "DWARFDebugInfo.h"
@@ -29,6 +28,8 @@
 #include "DWARFLocationDescription.h"
 #include "DWARFLocationList.h"
 #include "DWARFDebugRanges.h"
+#include "SymbolFileDWARF.h"
+#include "SymbolFileDWARFDwo.h"
 
 using namespace lldb_private;
 using namespace std;
@@ -245,7 +246,7 @@
                         if (form_value.ExtractValue(debug_info_data, &offset))
                         {
                             if (attr == DW_AT_low_pc || attr == DW_AT_entry_pc)
-                                ((DWARFCompileUnit*)cu)->SetBaseAddress(form_value.Unsigned());
+                                const_cast<DWARFCompileUnit*>(cu)->SetBaseAddress(form_value.Address());
                         }
                     }
                     else
@@ -403,9 +404,24 @@
     DWARFExpression *frame_base
 ) const
 {
-    if (dwarf2Data == NULL)
+    if (dwarf2Data == nullptr)
         return false;
 
+    SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile();
+    if (dwo_symbol_file)
+        return GetDIENamesAndRanges(dwo_symbol_file,
+                                    dwo_symbol_file->GetCompileUnit(),
+                                    name,
+                                    mangled,
+                                    ranges,
+                                    decl_file,
+                                    decl_line,
+                                    decl_column,
+                                    call_file,
+                                    call_line,
+                                    call_column,
+                                    frame_base);
+
     dw_addr_t lo_pc = LLDB_INVALID_ADDRESS;
     dw_addr_t hi_pc = LLDB_INVALID_ADDRESS;
     std::vector<dw_offset_t> die_offsets;
@@ -438,21 +454,26 @@
                 switch (attr)
                 {
                 case DW_AT_low_pc:
-                    lo_pc = form_value.Unsigned();
+                    lo_pc = form_value.Address();
 
                     if (do_offset)
                         hi_pc += lo_pc;
                     do_offset = false;
                     break;
 
                 case DW_AT_entry_pc:
-                    lo_pc = form_value.Unsigned();
+                    lo_pc = form_value.Address();
                     break;
 
                 case DW_AT_high_pc:
-                    hi_pc = form_value.Unsigned();
-                    if (form_value.Form() != DW_FORM_addr)
+                    if (form_value.Form() == DW_FORM_addr ||
+                        form_value.Form() == DW_FORM_GNU_addr_index)
+                    {
+                        hi_pc = form_value.Address();
+                    }
+                    else
                     {
+                        hi_pc = form_value.Unsigned();
                         if (lo_pc == LLDB_INVALID_ADDRESS)
                             do_offset = hi_pc != LLDB_INVALID_ADDRESS;
                         else
@@ -586,7 +607,7 @@
             dw_offset_t die_offset = *pos;
             if (die_offset != DW_INVALID_OFFSET)
             {
-                DWARFDIE die = dwarf2Data->DebugInfo()->GetDIE(die_offset);
+                DWARFDIE die = dwarf2Data->DebugInfo()->GetDIE(DIERef(cu->GetOffset(), die_offset));
                 if (die)
                     die.GetDIE()->GetDIENamesAndRanges(die.GetDWARF(), die.GetCU(), name, mangled, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column);
             }
@@ -867,6 +888,16 @@
     lldb::offset_t offset = 0;
     if (cu)
     {
+        if (m_tag != DW_TAG_compile_unit)
+        {
+            SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile();
+            if (dwo_symbol_file)
+                return GetAttributes(dwo_symbol_file->GetCompileUnit(),
+                                     fixed_form_sizes,
+                                     attributes,
+                                     curr_depth);
+        }
+
         dwarf2Data = cu->GetSymbolFileDWARF();
         abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
     }
@@ -954,6 +985,14 @@
     dw_offset_t* end_attr_offset_ptr
 ) const
 {
+    SymbolFileDWARFDwo* dwo_symbol_file = cu->GetDwoSymbolFile();
+    if (dwo_symbol_file && m_tag != DW_TAG_compile_unit)
+        return GetAttributeValue(dwo_symbol_file,
+                                 dwo_symbol_file->GetCompileUnit(),
+                                 attr,
+                                 form_value,
+                                 end_attr_offset_ptr);
+
     lldb::offset_t offset;
     const DWARFAbbreviationDeclaration* abbrevDecl = GetAbbreviationDeclarationPtr(dwarf2Data, cu, offset);
 
@@ -981,7 +1020,22 @@
         }
     }
 
-    return 0;
+    if (!dwo_symbol_file)
+        return 0;
+
+    DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit();
+    if (!dwo_cu)
+        return 0;
+
+    DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly();
+    if (!dwo_cu_die.IsValid())
+        return 0;
+
+    return dwo_cu_die.GetDIE()->GetAttributeValue(dwo_symbol_file,
+                                                  dwo_cu,
+                                                  attr,
+                                                  form_value,
+                                                  end_attr_offset_ptr);
 }
 
 //----------------------------------------------------------------------
@@ -1067,6 +1121,21 @@
     return fail_value;
 }
 
+uint64_t
+DWARFDebugInfoEntry::GetAttributeValueAsAddress
+(
+    SymbolFileDWARF* dwarf2Data,
+    const DWARFCompileUnit* cu,
+    const dw_attr_t attr,
+    uint64_t fail_value
+) const
+{
+    DWARFFormValue form_value;
+    if (GetAttributeValue(dwarf2Data, cu, attr, form_value))
+        return form_value.Address();
+    return fail_value;
+}
+
 //----------------------------------------------------------------------
 // GetAttributeHighPC
 //
@@ -1115,7 +1184,7 @@
     uint64_t fail_value
 ) const
 {
-    lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, fail_value);
+    lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, fail_value);
     if (lo_pc != fail_value)
     {
         hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, fail_value);
@@ -1178,14 +1247,19 @@
     // Empty out data in case we don't find anything
     location_data.Clear();
     dw_offset_t end_addr_offset = DW_INVALID_OFFSET;
-    const dw_offset_t attr_offset = GetAttributeValue(dwarf2Data, cu, attr, form_value, &end_addr_offset);
+    SymbolFileDWARF* attribute_symbol_file = nullptr;
+    const dw_offset_t attr_offset = GetAttributeValue(dwarf2Data,
+                                                      cu,
+                                                      attr,
+                                                      form_value,
+                                                      &end_addr_offset);
     if (attr_offset)
     {
         const uint8_t* blockData = form_value.BlockData();
         if (blockData)
         {
             // We have an inlined location list in the .debug_info section
-            const DWARFDataExtractor& debug_info = dwarf2Data->get_debug_info_data();
+            const DWARFDataExtractor& debug_info = attribute_symbol_file->get_debug_info_data();
             dw_offset_t block_offset = blockData - debug_info.GetDataStart();
             block_size = (end_addr_offset - attr_offset) - form_value.Unsigned();
             location_data.SetData(debug_info, block_offset, block_size);
@@ -1196,10 +1270,12 @@
             // the offset into the .debug_loc section that describes
             // the value over it's lifetime
             lldb::offset_t debug_loc_offset = form_value.Unsigned();
-            if (dwarf2Data)
+            if (attribute_symbol_file)
             {
-                assert(dwarf2Data->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize());
-                return DWARFLocationList::Extract(dwarf2Data->get_debug_loc_data(), &debug_loc_offset, location_data);
+                assert(attribute_symbol_file->get_debug_loc_data().GetAddressByteSize() == cu->GetAddressByteSize());
+                return DWARFLocationList::Extract(attribute_symbol_file->get_debug_loc_data(),
+                                                  &debug_loc_offset,
+                                                  location_data);
             }
         }
     }
@@ -1219,16 +1295,19 @@
     const DWARFCompileUnit* cu
 ) const
 {
+    const char* dw_at_name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr);
+    if (dw_at_name)
+        return dw_at_name;
+
     DWARFFormValue form_value;
-    if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
-        return form_value.AsCString();
-    else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
+    if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
     {
         DWARFDIE die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(form_value.Reference());
         if (die)
             return die.GetName();
     }
-    else if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value))
+
+    if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value))
     {
         DWARFDIE die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(form_value.Reference());
         if (die)
@@ -1253,19 +1332,19 @@
 ) const
 {
     const char* name = nullptr;
-    DWARFFormValue form_value;
 
-    if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
-        name = form_value.AsCString();
+    name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr);
+    if (name)
+        return name;
 
-    if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
-        name = form_value.AsCString();
+    name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr);
+    if (name)
+        return name;
 
-    if (substitute_name_allowed && name == nullptr)
-    {
-        if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
-            name = form_value.AsCString();
-    }
+    if (!substitute_name_allowed)
+        return nullptr;
+
+    name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr);
     return name;
 }
 
@@ -1283,19 +1362,24 @@
     const DWARFCompileUnit* cu
 ) const
 {
-    const char* name = NULL;
+    const char* name = nullptr;
     if (!dwarf2Data)
         return name;
-    
-    DWARFFormValue form_value;
 
-    if (GetAttributeValue(dwarf2Data, cu, DW_AT_MIPS_linkage_name, form_value))
-        name = form_value.AsCString();
-    else if (GetAttributeValue(dwarf2Data, cu, DW_AT_linkage_name, form_value))
-        name = form_value.AsCString();
-    else if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
-        name = form_value.AsCString();
-    else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
+    name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_MIPS_linkage_name, nullptr);
+    if (name)
+        return name;
+
+    name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_linkage_name, nullptr);
+    if (name)
+        return name;
+
+    name = GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr);
+    if (name)
+        return name;
+
+    DWARFFormValue form_value;
+    if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value))
     {
         DWARFDIE die = const_cast<DWARFCompileUnit*>(cu)->GetDIE(form_value.Reference());
         if (die)
@@ -1340,15 +1424,11 @@
         }
         else
         {
-            DWARFFormValue form_value;
-            if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
+            const char* name = die.GetAttributeValueAsString(dwarf2Data, cu, DW_AT_name, nullptr);
+            if (name)
             {
-                const char* name = form_value.AsCString();
-                if (name)
-                {
-                    s.PutCString(name);
-                    return true;
-                }
+                s.PutCString(name);
+                return true;
             }
         }
     }
@@ -1390,8 +1470,6 @@
         else
         {
             const char* name = die.GetPubname(dwarf2Data, cu);
-        //  if (die.GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value))
-        //      name = form_value.AsCString(&dwarf2Data->get_debug_str_data());
             if (name)
                 s.PutCString(name);
             else
@@ -1810,7 +1888,7 @@
 
         if (match_addr_range)
         {
-            dw_addr_t lo_pc = GetAttributeValueAsUnsigned(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+            dw_addr_t lo_pc = GetAttributeValueAsAddress(dwarf2Data, cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
             if (lo_pc != LLDB_INVALID_ADDRESS)
             {
                 dw_addr_t hi_pc = GetAttributeHighPC(dwarf2Data, cu, lo_pc, LLDB_INVALID_ADDRESS);
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -36,18 +36,13 @@
     DWARFDebugInfo();
     void SetDwarfData(SymbolFileDWARF* dwarf2Data);
 
-    DWARFDIE
-    LookupAddress(const dw_addr_t address,
-                  const dw_offset_t cu_offset);    // Can be valid (find in .debug_aranges), or DW_INVALID_OFFSET if we need to search manually
-
     size_t GetNumCompileUnits();
     bool ContainsCompileUnit (const DWARFCompileUnit *cu) const;
     DWARFCompileUnit* GetCompileUnitAtIndex (uint32_t idx);
     DWARFCompileUnit* GetCompileUnit (dw_offset_t cu_offset, uint32_t* idx_ptr = NULL);
-    DWARFCompileUnit* GetCompileUnitContainingDIE (dw_offset_t die_offset);
+    DWARFCompileUnit* GetCompileUnitContainingDIE (const DIERef& die_ref);
 
-    DWARFDIE GetDIE (dw_offset_t die_offset);
-    DWARFDIE GetDIEContainingOffset (dw_offset_t die_offset);
+    DWARFDIE GetDIE (const DIERef& die_ref);
 
     void Dump(lldb_private::Stream *s, const uint32_t die_offset, const uint32_t recurse_depth);
     static void Parse(SymbolFileDWARF* parser, Callback callback, void* userData);
Index: source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -103,48 +103,6 @@
     return *m_cu_aranges_ap.get();
 }
 
-
-//----------------------------------------------------------------------
-// LookupAddress
-//----------------------------------------------------------------------
-DWARFDIE
-DWARFDebugInfo::LookupAddress (const dw_addr_t address,
-                               const dw_offset_t hint_die_offset)
-{
-    DWARFDIE die;
-    DWARFCompileUnit *cu = nullptr;
-    if (hint_die_offset != DW_INVALID_OFFSET)
-    {
-        cu = GetCompileUnit(hint_die_offset);
-    }
-    else
-    {
-        DWARFDebugAranges &cu_aranges = GetCompileUnitAranges ();
-        const dw_offset_t cu_offset = cu_aranges.FindAddress (address);
-        cu = GetCompileUnit(cu_offset);
-    }
-
-    if (cu)
-    {
-        die = cu->LookupAddress(address);
-    }
-    else
-    {
-        // The hint_die_offset may have been a pointer to the actual item that
-        // we are looking for
-        die = GetDIE(hint_die_offset);
-        if (die)
-        {
-            DWARFDebugInfoEntry* function_die = nullptr;
-
-            if (die.GetDIE()->LookupAddress (address, die.GetDWARF(), die.GetCU(), &function_die, nullptr))
-                die.Set (die.GetCU(), function_die);
-        }
-    }
-    return die;
-}
-
-
 void
 DWARFDebugInfo::ParseCompileUnitHeadersIfNeeded()
 {
@@ -251,29 +209,33 @@
 }
 
 DWARFCompileUnit *
-DWARFDebugInfo::GetCompileUnitContainingDIE (dw_offset_t die_offset)
+DWARFDebugInfo::GetCompileUnitContainingDIE (const DIERef& die_ref)
 {
+    dw_offset_t search_offset = die_ref.cu_offset;
+    if (search_offset == DW_INVALID_OFFSET)
+        search_offset = die_ref.die_offset;
+
     DWARFCompileUnitSP cu_sp;
-    if (die_offset != DW_INVALID_OFFSET)
+    if (search_offset != DW_INVALID_OFFSET)
     {
         ParseCompileUnitHeadersIfNeeded();
 
         // Watch out for single compile unit executable as they are pretty common
         const size_t num_cus = m_compile_units.size();
         if (num_cus == 1)
         {
-            if (m_compile_units[0]->ContainsDIEOffset(die_offset))
+            if (m_compile_units[0]->GetOffset() == search_offset)
                 cu_sp = m_compile_units[0];
         }
         else if (num_cus)
         {
             CompileUnitColl::const_iterator end_pos = m_compile_units.end();
             CompileUnitColl::const_iterator begin_pos = m_compile_units.begin();
-            CompileUnitColl::const_iterator pos = std::upper_bound(begin_pos, end_pos, die_offset, OffsetLessThanCompileUnitOffset);
+            CompileUnitColl::const_iterator pos = std::upper_bound(begin_pos, end_pos, search_offset, OffsetLessThanCompileUnitOffset);
             if (pos != begin_pos)
             {
                 --pos;
-                if ((*pos)->ContainsDIEOffset(die_offset))
+                if ((*pos)->GetOffset() == search_offset)
                     cu_sp = *pos;
             }
         }
@@ -287,11 +249,11 @@
 // Get the DIE (Debug Information Entry) with the specified offset.
 //----------------------------------------------------------------------
 DWARFDIE
-DWARFDebugInfo::GetDIE(dw_offset_t die_offset)
+DWARFDebugInfo::GetDIE(const DIERef& die_ref)
 {
-    DWARFCompileUnit *cu = GetCompileUnitContainingDIE(die_offset);
+    DWARFCompileUnit *cu = GetCompileUnitContainingDIE(die_ref);
     if (cu)
-        return cu->GetDIE (die_offset);
+        return cu->GetDIE (die_ref.die_offset);
     return DWARFDIE();    // Not found
 }
 
Index: source/Plugins/SymbolFile/DWARF/DWARFDIE.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -13,6 +13,7 @@
 #include "lldb/lldb-types.h"
 #include "lldb/Core/dwarf.h"
 
+struct DIERef;
 class DWARFASTParser;
 class DWARFAttributes;
 class DWARFCompileUnit;
@@ -95,6 +96,9 @@
         return m_die;
     }
 
+    DIERef
+    GetDIERef() const;
+
     lldb_private::TypeSystem *
     GetTypeSystem () const;
 
@@ -232,6 +236,9 @@
     uint64_t
     GetAttributeValueAsReference (const dw_attr_t attr, uint64_t fail_value) const;
 
+    uint64_t
+    GetAttributeValueAsAddress (const dw_attr_t attr, uint64_t fail_value) const;
+
     size_t
     GetAttributes (DWARFAttributes &attributes, uint32_t depth = 0) const;
 
Index: source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -25,6 +25,12 @@
 #include "lldb/Core/Module.h"
 #include "lldb/Symbol/ObjectFile.h"
 
+DIERef
+DWARFDIE::GetDIERef() const
+{
+    return DIERef(m_cu->GetOffset(), m_die->GetOffset());
+}
+
 dw_tag_t
 DWARFDIE::Tag() const
 {
@@ -122,6 +128,15 @@
         return fail_value;
 }
 
+uint64_t
+DWARFDIE::GetAttributeValueAsAddress (const dw_attr_t attr, uint64_t fail_value) const
+{
+    if (IsValid())
+        return m_die->GetAttributeValueAsAddress(GetDWARF(), GetCU(), attr, fail_value);
+    else
+        return fail_value;
+}
+
 
 DWARFDIE
 DWARFDIE::LookupDeepestBlock (lldb::addr_t file_addr) const
@@ -143,7 +158,7 @@
                 if (cu->ContainsDIEOffset(block_die->GetOffset()))
                     return DWARFDIE(cu, block_die);
                 else
-                    return DWARFDIE(dwarf->DebugInfo()->GetCompileUnitContainingDIE(block_die->GetOffset()), block_die);
+                    return DWARFDIE(dwarf->DebugInfo()->GetCompileUnitContainingDIE(DIERef(cu->GetOffset(), block_die->GetOffset())), block_die);
             }
         }
     }
@@ -156,11 +171,19 @@
     const dw_offset_t die_offset = GetOffset();
     if (die_offset != DW_INVALID_OFFSET)
     {
+        lldb::user_id_t id = 0;
         SymbolFileDWARF *dwarf = GetDWARF();
         if (dwarf)
-            return dwarf->MakeUserID(die_offset);
+            id = dwarf->MakeUserID(die_offset);
         else
-            return die_offset;
+            id = die_offset;
+
+        if (m_cu)
+        {
+            assert ((id&0xffffffff00000000ull) == 0 || m_cu->GetID() == 0);
+            id |= ((lldb::user_id_t)m_cu->GetID()) << 32;
+        }
+        return id;
     }
     return LLDB_INVALID_UID;
 }
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -13,9 +13,10 @@
 #include "lldb/lldb-enumerations.h"
 #include "DWARFDebugInfoEntry.h"
 #include "DWARFDIE.h"
-#include "SymbolFileDWARF.h"
 
 class NameToDIE;
+class SymbolFileDWARF;
+class SymbolFileDWARFDwo;
 
 class DWARFCompileUnit
 {
@@ -30,6 +31,7 @@
     };
 
     DWARFCompileUnit(SymbolFileDWARF* dwarf2Data);
+    ~DWARFCompileUnit();
 
     bool        Extract(const lldb_private::DWARFDataExtractor &debug_info, lldb::offset_t *offset_ptr);
     size_t      ExtractDIEsIfNeeded (bool cu_die_only);
@@ -51,11 +53,13 @@
     dw_offset_t GetAbbrevOffset() const;
     uint8_t     GetAddressByteSize() const { return m_addr_size; }
     dw_addr_t   GetBaseAddress() const { return m_base_addr; }
-    dw_addr_t   GetAddrBase() const { return 0; } // TODO: Read out DW_AT_addr_base from the parent compile unit
+    dw_addr_t   GetAddrBase() const { return m_addr_base; }
+    void        SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset);
     void        ClearDIEs(bool keep_compile_unit_die);
     void        BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data,
                                         DWARFDebugAranges* debug_aranges);
 
+
     lldb_private::TypeSystem *
                 GetTypeSystem();
 
@@ -96,6 +100,9 @@
             m_die_array.reserve(GetDebugInfoSize() / 24);
         m_die_array.push_back(die);
     }
+    
+    void
+    AddCompileUnitDIE (DWARFDebugInfoEntry& die);
 
     bool
     HasDIEsParsed () const
@@ -125,10 +132,7 @@
     }
 
     void
-    SetUserData(void *d)
-    {
-        m_user_data = d;
-    }
+    SetUserData(void *d);
 
     bool
     Supports_DW_AT_APPLE_objc_complete_type ();
@@ -140,8 +144,7 @@
     Supports_unnamed_objc_bitfields ();
 
     void
-    Index (const uint32_t cu_idx,
-           NameToDIE& func_basenames,
+    Index (NameToDIE& func_basenames,
            NameToDIE& func_fullnames,
            NameToDIE& func_methods,
            NameToDIE& func_selectors,
@@ -183,8 +186,15 @@
     bool
     GetIsOptimized ();
 
+    SymbolFileDWARFDwo*
+    GetDwoSymbolFile() const
+    {
+        return m_dwo_symbol_file.get();
+    }
+
 protected:
     SymbolFileDWARF*    m_dwarf2Data;
+    std::unique_ptr<SymbolFileDWARFDwo> m_dwo_symbol_file;
     const DWARFAbbreviationDeclarationSet *m_abbrevs;
     void *              m_user_data;
     DWARFDebugInfoEntry::collection m_die_array;    // The compile unit debug information entry item
@@ -201,9 +211,27 @@
     lldb::LanguageType  m_language_type;
     bool                m_is_dwarf64;
     lldb_private::LazyBool m_is_optimized;
-    
+    dw_addr_t           m_addr_base;       // Value of DW_AT_addr_base
+    dw_offset_t         m_base_obj_offset; // If this is a dwo compile unit this is the offset of
+                                           // the base compile unit in the main object file
+
     void
     ParseProducerInfo ();
+
+    static void
+    IndexPrivate (DWARFCompileUnit* dwarf_cu,
+                  const lldb::LanguageType cu_language,
+                  const DWARFFormValue::FixedFormSizes& fixed_form_sizes,
+                  const dw_offset_t cu_offset,
+                  NameToDIE& func_basenames,
+                  NameToDIE& func_fullnames,
+                  NameToDIE& func_methods,
+                  NameToDIE& func_selectors,
+                  NameToDIE& objc_class_selectors,
+                  NameToDIE& globals,
+                  NameToDIE& types,
+                  NameToDIE& namespaces);
+
 private:
 
     const DWARFDebugInfoEntry*
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -27,6 +27,7 @@
 #include "LogChannelDWARF.h"
 #include "NameToDIE.h"
 #include "SymbolFileDWARF.h"
+#include "SymbolFileDWARFDwo.h"
 #include "SymbolFileDWARFDebugMap.h"
 
 using namespace lldb;
@@ -53,10 +54,15 @@
     m_producer_version_update (0),
     m_language_type (eLanguageTypeUnknown),
     m_is_dwarf64    (false),
-    m_is_optimized  (eLazyBoolCalculate)
+    m_is_optimized  (eLazyBoolCalculate),
+    m_addr_base (0),
+    m_base_obj_offset (DW_INVALID_OFFSET)
 {
 }
 
+DWARFCompileUnit::~DWARFCompileUnit()
+{}
+
 void
 DWARFCompileUnit::Clear()
 {
@@ -73,6 +79,8 @@
     m_language_type = eLanguageTypeUnknown;
     m_is_dwarf64    = false;
     m_is_optimized  = eLazyBoolCalculate;
+    m_addr_base     = 0;
+    m_base_obj_offset = DW_INVALID_OFFSET;
 }
 
 bool
@@ -130,6 +138,9 @@
         if (keep_compile_unit_die)
             m_die_array.push_back(tmp_array.front());
     }
+
+    if (m_dwo_symbol_file)
+        m_dwo_symbol_file->GetCompileUnit()->ClearDIEs(keep_compile_unit_die);
 }
 
 //----------------------------------------------------------------------
@@ -191,12 +202,12 @@
         const bool null_die = die.IsNULL();
         if (depth == 0)
         {
-            uint64_t base_addr = die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
+            if (initial_die_array_size == 0)
+                AddCompileUnitDIE(die);
+            uint64_t base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
             if (base_addr == LLDB_INVALID_ADDRESS)
-                base_addr = die.GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_entry_pc, 0);
+                base_addr = die.GetAttributeValueAsAddress(m_dwarf2Data, this, DW_AT_entry_pc, 0);
             SetBaseAddress (base_addr);
-            if (initial_die_array_size == 0)
-                AddDIE (die);
             if (cu_die_only)
                 return 1;
         }
@@ -286,9 +297,78 @@
         verbose_log->PutCString (strm.GetString().c_str());
     }
 
-    return m_die_array.size();
+    if (!m_dwo_symbol_file)
+        return m_die_array.size();
+
+    DWARFCompileUnit* dwo_cu = m_dwo_symbol_file->GetCompileUnit();
+    size_t dwo_die_count = dwo_cu->ExtractDIEsIfNeeded(cu_die_only);
+    return m_die_array.size() + dwo_die_count - 1; // We have 2 CU die, but we waht to count it only as one
 }
 
+void
+DWARFCompileUnit::AddCompileUnitDIE(DWARFDebugInfoEntry& die)
+{
+    assert (m_die_array.empty() && "Compile unit DIE already added");
+    AddDIE(die);
+    
+    DWARFDebugInfoEntry& cu_die = m_die_array.front();
+
+    const char* dwo_name = cu_die.GetAttributeValueAsString(m_dwarf2Data,
+                                                            this,
+                                                            DW_AT_GNU_dwo_name,
+                                                            nullptr);
+    if (!dwo_name)
+        return;
+    
+    const char* comp_dir = cu_die.GetAttributeValueAsString(m_dwarf2Data,
+                                                            this,
+                                                            DW_AT_comp_dir,
+                                                            nullptr);
+    if (!comp_dir)
+        return;
+
+    FileSpec dwo_file(comp_dir, true);
+    dwo_file.AppendPathComponent(dwo_name);
+    if (!dwo_file.Exists())
+        return;
+
+    DataBufferSP dwo_file_data_sp;
+    lldb::offset_t dwo_file_data_offset = 0;
+    ObjectFileSP dwo_obj_file = ObjectFile::FindPlugin(m_dwarf2Data->GetObjectFile()->GetModule(),
+                                                       &dwo_file,
+                                                       0 /* file_offset */,
+                                                       dwo_file.GetByteSize(),
+                                                       dwo_file_data_sp,
+                                                       dwo_file_data_offset);
+    if (dwo_obj_file == nullptr)
+        return;
+
+    std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file(new SymbolFileDWARFDwo(dwo_obj_file, this));
+
+    DWARFCompileUnit* dwo_cu = dwo_symbol_file->GetCompileUnit();
+    if (!dwo_cu)
+        return; // Can't fetch the compile unit from the dwo file.
+
+    DWARFDIE dwo_cu_die = dwo_cu->GetCompileUnitDIEOnly();
+    if (!dwo_cu_die.IsValid())
+        return; // Can't fetch the compile unit DIE from the dwo file.
+
+    uint64_t main_dwo_id = cu_die.GetAttributeValueAsUnsigned(m_dwarf2Data,
+                                                              this,
+                                                              DW_AT_GNU_dwo_id,
+                                                              0);
+    uint64_t sub_dwo_id = dwo_cu_die.GetAttributeValueAsUnsigned(DW_AT_GNU_dwo_id, 0);
+    if (main_dwo_id != sub_dwo_id)
+        return; // The 2 dwo ID isn't match. Don't use the dwo file as it belongs to a differectn compilation.
+
+    m_dwo_symbol_file = std::move(dwo_symbol_file);
+    
+    dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned(m_dwarf2Data,
+                                                             this,
+                                                             DW_AT_GNU_addr_base,
+                                                             0);
+    dwo_cu->SetAddrBase(addr_base, m_offset);
+}
 
 dw_offset_t
 DWARFCompileUnit::GetAbbrevOffset() const
@@ -379,10 +459,11 @@
 lldb::user_id_t
 DWARFCompileUnit::GetID () const
 {
+    dw_offset_t local_id = m_base_obj_offset != DW_INVALID_OFFSET ? m_base_obj_offset : m_offset;
     if (m_dwarf2Data)
-        return m_dwarf2Data->MakeUserID(GetOffset());
+        return m_dwarf2Data->MakeUserID(local_id);
     else
-        return GetOffset();
+        return local_id;
 }
 
 void
@@ -508,6 +589,17 @@
         const DWARFDebugInfoEntry* die = DIEPtr();
         if (die)
             die->BuildFunctionAddressRangeTable (m_dwarf2Data, this, m_func_aranges_ap.get());
+
+        if (m_dwo_symbol_file)
+        {
+            DWARFCompileUnit* dwo_cu = m_dwo_symbol_file->GetCompileUnit();
+            const DWARFDebugInfoEntry* dwo_die = dwo_cu->DIEPtr();
+            if (dwo_die)
+                dwo_die->BuildFunctionAddressRangeTable (m_dwo_symbol_file.get(),
+                                                         dwo_cu,
+                                                         m_func_aranges_ap.get());
+        }
+        
         const bool minimize = false;
         m_func_aranges_ap->Sort(minimize);
     }
@@ -549,6 +641,9 @@
 {
     if (die_offset != DW_INVALID_OFFSET)
     {
+        if (m_dwo_symbol_file)
+            return m_dwo_symbol_file->GetCompileUnit()->GetDIE(die_offset);
+
         if (ContainsDIEOffset(die_offset))
         {
             ExtractDIEsIfNeeded (false);
@@ -562,7 +657,7 @@
         }
         else
         {
-            return m_dwarf2Data->DebugInfo()->GetDIE (die_offset);
+            return m_dwarf2Data->DebugInfo()->GetDIE (DIERef(die_offset));
         }
     }
     return DWARFDIE(); // Not found
@@ -608,19 +703,15 @@
 
 
 void
-DWARFCompileUnit::Index (const uint32_t cu_idx,
-                         NameToDIE& func_basenames,
+DWARFCompileUnit::Index (NameToDIE& func_basenames,
                          NameToDIE& func_fullnames,
                          NameToDIE& func_methods,
                          NameToDIE& func_selectors,
                          NameToDIE& objc_class_selectors,
                          NameToDIE& globals,
                          NameToDIE& types,
                          NameToDIE& namespaces)
 {
-    DWARFFormValue::FixedFormSizes fixed_form_sizes =
-        DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64);
-
     Log *log (LogChannelDWARF::GetLogIfAll (DWARF_LOG_LOOKUPS));
     
     if (log)
@@ -631,9 +722,57 @@
     }
 
     const LanguageType cu_language = GetLanguageType();
+    DWARFFormValue::FixedFormSizes fixed_form_sizes =
+        DWARFFormValue::GetFixedFormSizesForAddressSize (GetAddressByteSize(), m_is_dwarf64);
+    
+    IndexPrivate(this,
+                 cu_language,
+                 fixed_form_sizes,
+                 GetOffset(),
+                 func_basenames,
+                 func_fullnames,
+                 func_methods,
+                 func_selectors,
+                 objc_class_selectors,
+                 globals,
+                 types,
+                 namespaces);
+
+    SymbolFileDWARFDwo* dwo_symbol_file = GetDwoSymbolFile();
+    if (dwo_symbol_file)
+    {
+        IndexPrivate(dwo_symbol_file->GetCompileUnit(),
+                     cu_language,
+                     fixed_form_sizes,
+                     GetOffset(),
+                     func_basenames,
+                     func_fullnames,
+                     func_methods,
+                     func_selectors,
+                     objc_class_selectors,
+                     globals,
+                     types,
+                     namespaces);
+    }
+}
+
+void
+DWARFCompileUnit::IndexPrivate (DWARFCompileUnit* dwarf_cu,
+                                const LanguageType cu_language,
+                                const DWARFFormValue::FixedFormSizes& fixed_form_sizes,
+                                const dw_offset_t cu_offset,
+                                NameToDIE& func_basenames,
+                                NameToDIE& func_fullnames,
+                                NameToDIE& func_methods,
+                                NameToDIE& func_selectors,
+                                NameToDIE& objc_class_selectors,
+                                NameToDIE& globals,
+                                NameToDIE& types,
+                                NameToDIE& namespaces)
+{
     DWARFDebugInfoEntry::const_iterator pos;
-    DWARFDebugInfoEntry::const_iterator begin = m_die_array.begin();
-    DWARFDebugInfoEntry::const_iterator end = m_die_array.end();
+    DWARFDebugInfoEntry::const_iterator begin = dwarf_cu->m_die_array.begin();
+    DWARFDebugInfoEntry::const_iterator end = dwarf_cu->m_die_array.end();
     for (pos = begin; pos != end; ++pos)
     {
         const DWARFDebugInfoEntry &die = *pos;
@@ -672,7 +811,7 @@
         bool is_global_or_static_variable = false;
         
         dw_offset_t specification_die_offset = DW_INVALID_OFFSET;
-        const size_t num_attributes = die.GetAttributes(this, fixed_form_sizes, attributes);
+        const size_t num_attributes = die.GetAttributes(dwarf_cu, fixed_form_sizes, attributes);
         if (num_attributes > 0)
         {
             for (uint32_t i=0; i<num_attributes; ++i)
@@ -784,15 +923,15 @@
                         ConstString objc_selector_name (objc_method.GetSelector());
                         ConstString objc_fullname_no_category_name (objc_method.GetFullNameWithoutCategory(true));
                         ConstString objc_class_name_no_category (objc_method.GetClassName());
-                        func_fullnames.Insert (ConstString(name), die.GetOffset());
+                        func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
                         if (objc_class_name_with_category)
-                            objc_class_selectors.Insert(objc_class_name_with_category, die.GetOffset());
+                            objc_class_selectors.Insert(objc_class_name_with_category, DIERef(cu_offset, die.GetOffset()));
                         if (objc_class_name_no_category && objc_class_name_no_category != objc_class_name_with_category)
-                            objc_class_selectors.Insert(objc_class_name_no_category, die.GetOffset());
+                            objc_class_selectors.Insert(objc_class_name_no_category, DIERef(cu_offset, die.GetOffset()));
                         if (objc_selector_name)
-                            func_selectors.Insert (objc_selector_name, die.GetOffset());
+                            func_selectors.Insert (objc_selector_name, DIERef(cu_offset, die.GetOffset()));
                         if (objc_fullname_no_category_name)
-                            func_fullnames.Insert (objc_fullname_no_category_name, die.GetOffset());
+                            func_fullnames.Insert (objc_fullname_no_category_name, DIERef(cu_offset, die.GetOffset()));
                     }
                     // If we have a mangled name, then the DW_AT_name attribute
                     // is usually the method name without the class or any parameters
@@ -809,21 +948,21 @@
                         {
                             if (specification_die_offset != DW_INVALID_OFFSET)
                             {
-                                DWARFDIE specification_die = m_dwarf2Data->DebugInfo()->GetDIE (specification_die_offset);
+                                DWARFDIE specification_die = dwarf_cu->GetSymbolFileDWARF()->DebugInfo()->GetDIE (DIERef(specification_die_offset));
                                 if (specification_die.GetParent().IsStructOrClass())
                                     is_method = true;
                             }
                         }
                     }
 
 
                     if (is_method)
-                        func_methods.Insert (ConstString(name), die.GetOffset());
+                        func_methods.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
                     else
-                        func_basenames.Insert (ConstString(name), die.GetOffset());
+                        func_basenames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
 
                     if (!is_method && !mangled_cstr && !objc_method.IsValid(true))
-                        func_fullnames.Insert (ConstString(name), die.GetOffset());
+                        func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
                 }
                 if (mangled_cstr)
                 {
@@ -834,10 +973,10 @@
                     if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (name && ::strcmp(name, mangled_cstr) != 0)))
                     {
                         Mangled mangled (ConstString(mangled_cstr), true);
-                        func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset());
+                        func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset()));
                         ConstString demangled = mangled.GetDemangledName(cu_language);
                         if (demangled)
-                            func_fullnames.Insert (demangled, die.GetOffset());
+                            func_fullnames.Insert (demangled, DIERef(cu_offset, die.GetOffset()));
                     }
                 }
             }
@@ -847,7 +986,7 @@
             if (has_address)
             {
                 if (name)
-                    func_basenames.Insert (ConstString(name), die.GetOffset());
+                    func_basenames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
                 if (mangled_cstr)
                 {
                     // Make sure our mangled name isn't the same string table entry
@@ -857,14 +996,14 @@
                     if (name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0)))
                     {
                         Mangled mangled (ConstString(mangled_cstr), true);
-                        func_fullnames.Insert (mangled.GetMangledName(), die.GetOffset());
+                        func_fullnames.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset()));
                         ConstString demangled = mangled.GetDemangledName(cu_language);
                         if (demangled)
-                            func_fullnames.Insert (demangled, die.GetOffset());
+                            func_fullnames.Insert (demangled, DIERef(cu_offset, die.GetOffset()));
                     }
                 }
                 else
-                    func_fullnames.Insert (ConstString(name), die.GetOffset());
+                    func_fullnames.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
             }
             break;
         
@@ -880,19 +1019,19 @@
         case DW_TAG_unspecified_type:
             if (name && is_declaration == false)
             {
-                types.Insert (ConstString(name), die.GetOffset());
+                types.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
             }
             break;
 
         case DW_TAG_namespace:
             if (name)
-                namespaces.Insert (ConstString(name), die.GetOffset());
+                namespaces.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
             break;
 
         case DW_TAG_variable:
             if (name && has_location && is_global_or_static_variable)
             {
-                globals.Insert (ConstString(name), die.GetOffset());
+                globals.Insert (ConstString(name), DIERef(cu_offset, die.GetOffset()));
                 // Be sure to include variables by their mangled and demangled
                 // names if they have any since a variable can have a basename
                 // "i", a mangled named "_ZN12_GLOBAL__N_11iE" and a demangled 
@@ -905,10 +1044,10 @@
                 if (mangled_cstr && name != mangled_cstr && ((mangled_cstr[0] == '_') || (::strcmp(name, mangled_cstr) != 0)))
                 {
                     Mangled mangled (ConstString(mangled_cstr), true);
-                    globals.Insert (mangled.GetMangledName(), die.GetOffset());
+                    globals.Insert (mangled.GetMangledName(), DIERef(cu_offset, die.GetOffset()));
                     ConstString demangled = mangled.GetDemangledName(cu_language);
                     if (demangled)
-                        globals.Insert (demangled, die.GetOffset());
+                        globals.Insert (demangled, DIERef(cu_offset, die.GetOffset()));
                 }
             }
             break;
@@ -1098,3 +1237,18 @@
     else
         return nullptr;
 }
+
+void
+DWARFCompileUnit::SetUserData(void *d)
+{
+    m_user_data = d;
+    if (m_dwo_symbol_file)
+        m_dwo_symbol_file->GetCompileUnit()->SetUserData(d);
+}
+
+void
+DWARFCompileUnit::SetAddrBase(dw_addr_t addr_base, dw_offset_t base_obj_offset)
+{
+    m_addr_base = addr_base;
+    m_base_obj_offset = base_obj_offset;
+}
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -215,7 +215,7 @@
                                         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;
+                                    case DW_AT_type:        encoding_uid = DIERef(die.GetCU()->GetOffset(), form_value.Reference()).GetUID(); break;
                                     default:
                                     case DW_AT_sibling:
                                         break;
@@ -761,12 +761,10 @@
                             // will automatically call the SymbolFile virtual function
                             // "SymbolFileDWARF::CompleteType(Type *)"
                             // When the definition needs to be defined.
-                            dwarf->m_forward_decl_die_to_clang_type[die.GetDIE()] = clang_type.GetOpaqueQualType();
-                            dwarf->m_forward_decl_clang_type_to_die[ClangASTContext::RemoveFastQualifiers(clang_type).GetOpaqueQualType()] = die.GetDIE();
+                            dwarf->AddTypeForwardDeclaration(clang_type, die);
                             m_ast.SetHasExternalStorage (clang_type.GetOpaqueQualType(), true);
                         }
                     }
-
                 }
                     break;
 
@@ -1108,12 +1106,12 @@
                                         if (debug_map_symfile)
                                         {
                                             class_symfile = debug_map_symfile->GetSymbolFileByOSOIndex(SymbolFileDWARFDebugMap::GetOSOIndexFromUserID(class_type->GetID()));
-                                            class_type_die = class_symfile->DebugInfo()->GetDIE (class_type->GetID());
+                                            class_type_die = class_symfile->DebugInfo()->GetDIE (DIERef(class_type->GetID()));
                                         }
                                         else
                                         {
                                             class_symfile = dwarf;
-                                            class_type_die = dwarf->DebugInfo()->GetDIE (class_type->GetID());
+                                            class_type_die = dwarf->DebugInfo()->GetDIE (DIERef(class_type->GetID()));
                                         }
                                         if (class_type_die)
                                         {
@@ -1147,7 +1145,7 @@
                                         class_type->GetForwardCompilerType ();
                                         // If we have a specification, then the function type should have been
                                         // made with the specification and not with this die.
-                                        DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE(specification_die_offset);
+                                        DWARFDIE spec_die = dwarf->DebugInfo()->GetDIE(DIERef(die.GetCU()->GetOffset(), specification_die_offset));
                                         clang::DeclContext *spec_clang_decl_ctx = GetClangDeclContextForDIE (spec_die);
                                         if (spec_clang_decl_ctx)
                                         {
@@ -1169,7 +1167,7 @@
                                         // clang decl context.
                                         class_type->GetForwardCompilerType ();
 
-                                        DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE (abstract_origin_die_offset);
+                                        DWARFDIE abs_die = dwarf->DebugInfo()->GetDIE (DIERef(die.GetCU()->GetOffset(), abstract_origin_die_offset));
                                         clang::DeclContext *abs_clang_decl_ctx = GetClangDeclContextForDIE (abs_die);
                                         if (abs_clang_decl_ctx)
                                         {
@@ -1851,8 +1849,8 @@
                                 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];
-                                    DWARFDIE method_die = debug_info->GetDIE (die_offset);
+                                    const DIERef& die_ref = method_die_offsets[i];
+                                    DWARFDIE method_die = debug_info->GetDIE (die_ref);
 
                                     if (method_die)
                                         method_die.ResolveType ();
Index: source/Plugins/SymbolFile/DWARF/CMakeLists.txt
===================================================================
--- source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -28,6 +28,7 @@
   LogChannelDWARF.cpp
   NameToDIE.cpp
   SymbolFileDWARF.cpp
+  SymbolFileDWARFDwo.cpp
   SymbolFileDWARFDebugMap.cpp
   UniqueDWARFASTType.cpp
   )
Index: source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
===================================================================
--- source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -1684,6 +1684,12 @@
             static ConstString g_sect_name_dwarf_debug_ranges (".debug_ranges");
             static ConstString g_sect_name_dwarf_debug_str (".debug_str");
             static ConstString g_sect_name_dwarf_debug_str_offsets (".debug_str_offsets");
+            static ConstString g_sect_name_dwarf_debug_abbrev_dwo (".debug_abbrev.dwo");
+            static ConstString g_sect_name_dwarf_debug_info_dwo (".debug_info.dwo");
+            static ConstString g_sect_name_dwarf_debug_line_dwo (".debug_line.dwo");
+            static ConstString g_sect_name_dwarf_debug_loc_dwo (".debug_loc.dwo");
+            static ConstString g_sect_name_dwarf_debug_str_dwo (".debug_str.dwo");
+            static ConstString g_sect_name_dwarf_debug_str_offsets_dwo (".debug_str_offsets.dwo");
             static ConstString g_sect_name_eh_frame (".eh_frame");
 
             SectionType sect_type = eSectionTypeOther;
@@ -1717,20 +1723,26 @@
             // MISSING? .gnu_debugdata - "mini debuginfo / MiniDebugInfo" section, http://sourceware.org/gdb/onlinedocs/gdb/MiniDebugInfo.html
             // MISSING? .debug-index - http://src.chromium.org/viewvc/chrome/trunk/src/build/gdb-add-index?pathrev=144644
             // MISSING? .debug_types - Type descriptions from DWARF 4? See http://gcc.gnu.org/wiki/DwarfSeparateTypeInfo
-            else if (name == g_sect_name_dwarf_debug_abbrev)      sect_type = eSectionTypeDWARFDebugAbbrev;
-            else if (name == g_sect_name_dwarf_debug_addr)        sect_type = eSectionTypeDWARFDebugAddr;
-            else if (name == g_sect_name_dwarf_debug_aranges)     sect_type = eSectionTypeDWARFDebugAranges;
-            else if (name == g_sect_name_dwarf_debug_frame)       sect_type = eSectionTypeDWARFDebugFrame;
-            else if (name == g_sect_name_dwarf_debug_info)        sect_type = eSectionTypeDWARFDebugInfo;
-            else if (name == g_sect_name_dwarf_debug_line)        sect_type = eSectionTypeDWARFDebugLine;
-            else if (name == g_sect_name_dwarf_debug_loc)         sect_type = eSectionTypeDWARFDebugLoc;
-            else if (name == g_sect_name_dwarf_debug_macinfo)     sect_type = eSectionTypeDWARFDebugMacInfo;
-            else if (name == g_sect_name_dwarf_debug_pubnames)    sect_type = eSectionTypeDWARFDebugPubNames;
-            else if (name == g_sect_name_dwarf_debug_pubtypes)    sect_type = eSectionTypeDWARFDebugPubTypes;
-            else if (name == g_sect_name_dwarf_debug_ranges)      sect_type = eSectionTypeDWARFDebugRanges;
-            else if (name == g_sect_name_dwarf_debug_str)         sect_type = eSectionTypeDWARFDebugStr;
-            else if (name == g_sect_name_dwarf_debug_str_offsets) sect_type = eSectionTypeDWARFDebugStrOffsets;
-            else if (name == g_sect_name_eh_frame)                sect_type = eSectionTypeEHFrame;
+            else if (name == g_sect_name_dwarf_debug_abbrev)          sect_type = eSectionTypeDWARFDebugAbbrev;
+            else if (name == g_sect_name_dwarf_debug_addr)            sect_type = eSectionTypeDWARFDebugAddr;
+            else if (name == g_sect_name_dwarf_debug_aranges)         sect_type = eSectionTypeDWARFDebugAranges;
+            else if (name == g_sect_name_dwarf_debug_frame)           sect_type = eSectionTypeDWARFDebugFrame;
+            else if (name == g_sect_name_dwarf_debug_info)            sect_type = eSectionTypeDWARFDebugInfo;
+            else if (name == g_sect_name_dwarf_debug_line)            sect_type = eSectionTypeDWARFDebugLine;
+            else if (name == g_sect_name_dwarf_debug_loc)             sect_type = eSectionTypeDWARFDebugLoc;
+            else if (name == g_sect_name_dwarf_debug_macinfo)         sect_type = eSectionTypeDWARFDebugMacInfo;
+            else if (name == g_sect_name_dwarf_debug_pubnames)        sect_type = eSectionTypeDWARFDebugPubNames;
+            else if (name == g_sect_name_dwarf_debug_pubtypes)        sect_type = eSectionTypeDWARFDebugPubTypes;
+            else if (name == g_sect_name_dwarf_debug_ranges)          sect_type = eSectionTypeDWARFDebugRanges;
+            else if (name == g_sect_name_dwarf_debug_str)             sect_type = eSectionTypeDWARFDebugStr;
+            else if (name == g_sect_name_dwarf_debug_str_offsets)     sect_type = eSectionTypeDWARFDebugStrOffsets;
+            else if (name == g_sect_name_dwarf_debug_abbrev_dwo)      sect_type = eSectionTypeDWARFDebugAbbrev;
+            else if (name == g_sect_name_dwarf_debug_info_dwo)        sect_type = eSectionTypeDWARFDebugInfo;
+            else if (name == g_sect_name_dwarf_debug_line_dwo)        sect_type = eSectionTypeDWARFDebugLine;
+            else if (name == g_sect_name_dwarf_debug_loc_dwo)         sect_type = eSectionTypeDWARFDebugLoc;
+            else if (name == g_sect_name_dwarf_debug_str_dwo)         sect_type = eSectionTypeDWARFDebugStr;
+            else if (name == g_sect_name_dwarf_debug_str_offsets_dwo) sect_type = eSectionTypeDWARFDebugStrOffsets;
+            else if (name == g_sect_name_eh_frame)                    sect_type = eSectionTypeEHFrame;
 
             switch (header.sh_type)
             {
Index: include/lldb/Symbol/ObjectFile.h
===================================================================
--- include/lldb/Symbol/ObjectFile.h
+++ include/lldb/Symbol/ObjectFile.h
@@ -369,7 +369,7 @@
     ///     The list of sections contained in this object file.
     //------------------------------------------------------------------
     virtual SectionList *
-    GetSectionList ();
+    GetSectionList (bool update_module_section_list = true);
 
     virtual void
     CreateSections (SectionList &unified_section_list) = 0;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to