jankratochvil updated this revision to Diff 374770.
jankratochvil retitled this revision from "[lldb] DWZ 1/9: Pass main DWARFUnit 
* along DWARFDIEs" to "[lldb] DWZ 09/17: Pass main DWARFUnit * along DWARFDIEs".
Herald added a subscriber: mgorny.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D96236/new/

https://reviews.llvm.org/D96236

Files:
  lldb/include/lldb/Expression/DWARFExpression.h
  lldb/source/Expression/DWARFExpression.cpp
  lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFSimpleDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFSimpleDIE.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
  lldb/source/Plugins/SymbolFile/DWARF/DWARFUnitPair.cpp
  lldb/source/Plugins/SymbolFile/DWARF/DWARFUnitPair.h
  lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
  lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
  lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
  lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
  lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
  lldb/source/Target/RegisterContext.cpp
  lldb/source/Target/RegisterContextUnwind.cpp
  lldb/unittests/Expression/DWARFExpressionTest.cpp
  lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
  lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
  lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp

Index: lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp
===================================================================
--- lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp
+++ lldb/unittests/SymbolFile/DWARF/DWARFUnitTest.cpp
@@ -43,7 +43,7 @@
   ASSERT_TRUE((bool)t.GetDwarfUnit());
 
   DWARFUnit *unit = t.GetDwarfUnit();
-  const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE();
+  const DWARFDebugInfoEntry *die_first = unit->DIE(unit).GetDIE();
   ASSERT_NE(die_first, nullptr);
   EXPECT_TRUE(die_first->IsNULL());
 }
@@ -79,7 +79,7 @@
   ASSERT_TRUE((bool)t.GetDwarfUnit());
 
   DWARFUnit *unit = t.GetDwarfUnit();
-  const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE();
+  const DWARFDebugInfoEntry *die_first = unit->DIE(unit).GetDIE();
   ASSERT_NE(die_first, nullptr);
   EXPECT_EQ(die_first->GetFirstChild(), nullptr);
   EXPECT_EQ(die_first->GetSibling(), nullptr);
Index: lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
===================================================================
--- lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
+++ lldb/unittests/SymbolFile/DWARF/DWARFDIETest.cpp
@@ -68,7 +68,7 @@
   ASSERT_TRUE((bool)t.GetDwarfUnit());
 
   DWARFUnit *unit = t.GetDwarfUnit();
-  const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE();
+  const DWARFDebugInfoEntry *die_first = unit->DIE(unit).GetDIE();
 
   // Create a DWARFDIE that has three DW_TAG_base_type children.
   DWARFDIE top_die(unit, die_first);
Index: lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
===================================================================
--- lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -96,7 +96,7 @@
   DWARFASTParserClangStub ast_parser(ast_ctx);
 
   DWARFUnit *unit = t.GetDwarfUnit();
-  const DWARFDebugInfoEntry *die_first = unit->DIE().GetDIE();
+  const DWARFDebugInfoEntry *die_first = unit->DIE(unit).GetDIE();
   const DWARFDebugInfoEntry *die_child0 = die_first->GetFirstChild();
   const DWARFDebugInfoEntry *die_child1 = die_child0->GetSibling();
   const DWARFDebugInfoEntry *die_child2 = die_child1->GetSibling();
Index: lldb/unittests/Expression/DWARFExpressionTest.cpp
===================================================================
--- lldb/unittests/Expression/DWARFExpressionTest.cpp
+++ lldb/unittests/Expression/DWARFExpressionTest.cpp
@@ -25,7 +25,7 @@
 
 static llvm::Expected<Scalar> Evaluate(llvm::ArrayRef<uint8_t> expr,
                                        lldb::ModuleSP module_sp = {},
-                                       DWARFUnit *unit = nullptr,
+                                       DWARFUnitPair unit = {},
                                        ExecutionContext *exe_ctx = nullptr) {
   DataExtractor extractor(expr.data(), expr.size(), lldb::eByteOrderLittle,
                           /*addr_size*/ 4);
Index: lldb/source/Target/RegisterContextUnwind.cpp
===================================================================
--- lldb/source/Target/RegisterContextUnwind.cpp
+++ lldb/source/Target/RegisterContextUnwind.cpp
@@ -1632,7 +1632,7 @@
                             process->GetByteOrder(),
                             process->GetAddressByteSize());
     ModuleSP opcode_ctx;
-    DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
+    DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, {});
     dwarfexpr.SetRegisterKind(unwindplan_registerkind);
     Value cfa_val = Scalar(m_cfa);
     cfa_val.SetValueType(Value::ValueType::LoadAddress);
@@ -1995,7 +1995,7 @@
                             process->GetByteOrder(),
                             process->GetAddressByteSize());
     ModuleSP opcode_ctx;
-    DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, nullptr);
+    DWARFExpression dwarfexpr(opcode_ctx, dwarfdata, {});
     dwarfexpr.SetRegisterKind(row_register_kind);
     Value result;
     Status error;
Index: lldb/source/Target/RegisterContext.cpp
===================================================================
--- lldb/source/Target/RegisterContext.cpp
+++ lldb/source/Target/RegisterContext.cpp
@@ -94,10 +94,10 @@
   DataExtractor dwarf_data(dwarf_opcode_ptr, dwarf_opcode_len,
                            arch.GetByteOrder(), addr_size);
   ModuleSP opcode_ctx;
-  DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, nullptr);
+  DWARFExpression dwarf_expr(opcode_ctx, dwarf_data, {});
   Value result;
   Status error;
-  if (dwarf_expr.Evaluate(&exe_ctx, this, opcode_ctx, dwarf_data, nullptr,
+  if (dwarf_expr.Evaluate(&exe_ctx, this, opcode_ctx, dwarf_data, {},
                           eRegisterKindDWARF, nullptr, nullptr, result,
                           &error)) {
     expr_result = result.GetScalar().SInt(-1);
Index: lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
+++ lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp
@@ -174,7 +174,7 @@
   DataBufferSP buffer =
       std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
   DataExtractor extractor(buffer, byte_order, address_size, byte_size);
-  DWARFExpression result(module, extractor, nullptr);
+  DWARFExpression result(module, extractor, {});
   result.SetRegisterKind(register_kind);
 
   return result;
Index: lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
+++ lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp
@@ -122,7 +122,7 @@
   DataBufferSP buffer =
       std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
   DataExtractor extractor(buffer, byte_order, address_size, byte_size);
-  DWARFExpression result(module, extractor, nullptr);
+  DWARFExpression result(module, extractor, {});
   result.SetRegisterKind(register_kind);
 
   return result;
@@ -247,6 +247,6 @@
               .take_front(size);
   buffer->CopyData(bytes.data(), size);
   DataExtractor extractor(buffer, lldb::eByteOrderLittle, address_size);
-  DWARFExpression result(nullptr, extractor, nullptr);
+  DWARFExpression result(nullptr, extractor, {});
   return result;
 }
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -383,8 +383,9 @@
   const auto &get = [&](DWARFUnit *unit) {
     if (!unit)
       return;
+    DWARFUnit *main_unit = unit;
     unit = &unit->GetNonSkeletonUnit();
-    GetTypes(unit->DIE(), unit->GetOffset(), unit->GetNextUnitOffset(),
+    GetTypes(unit->DIE(main_unit), unit->GetOffset(), unit->GetNextUnitOffset(),
              type_mask, type_set);
   };
   if (comp_unit) {
@@ -827,7 +828,8 @@
   if (!die.IsValid())
     return nullptr;
 
-  auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
+  auto type_system_or_err =
+      GetTypeSystemForLanguage(GetLanguage(*die.GetMainCU()));
   if (auto err = type_system_or_err.takeError()) {
     LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
                    std::move(err), "Unable to parse function");
@@ -857,7 +859,7 @@
 }
 lldb::LanguageType SymbolFileDWARF::ParseLanguage(CompileUnit &comp_unit) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
-  DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
+  DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
   if (dwarf_cu)
     return GetLanguage(dwarf_cu->GetNonSkeletonUnit());
   else
@@ -866,7 +868,7 @@
 
 XcodeSDK SymbolFileDWARF::ParseXcodeSDK(CompileUnit &comp_unit) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
-  DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
+  DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
   if (!dwarf_cu)
     return {};
   const DWARFBaseDIE cu_die = dwarf_cu->GetNonSkeletonUnit().GetUnitDIEOnly();
@@ -895,7 +897,7 @@
 size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
   LLDB_SCOPED_TIMER();
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
-  DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
+  DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
   if (!dwarf_cu)
     return 0;
 
@@ -1037,7 +1039,7 @@
     std::vector<SourceModule> &imported_modules) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
   assert(sc.comp_unit);
-  DWARFUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
+  DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(sc.comp_unit);
   if (!dwarf_cu)
     return false;
   if (!ClangModulesDeclVendor::LanguageSupportsClangModules(
@@ -1166,7 +1168,7 @@
 bool SymbolFileDWARF::ParseDebugMacros(CompileUnit &comp_unit) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
 
-  DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
+  DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
   if (dwarf_cu == nullptr)
     return false;
 
@@ -1434,7 +1436,7 @@
   // SymbolFileDWARF::GetDIE(). See comments inside the
   // SymbolFileDWARF::GetDIE() for details.
   if (DWARFDIE type_die = GetDIE(type_uid))
-    return type_die.ResolveType();
+    return type_die.ResolveType(*this);
   else
     return nullptr;
 }
@@ -1555,7 +1557,7 @@
           dwarf_die.GetID(), dwarf_die.GetTagAsCString(),
           type->GetName().AsCString());
     assert(compiler_type);
-    if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetCU()))
+    if (DWARFASTParser *dwarf_ast = GetDWARFParser(*dwarf_die.GetMainCU()))
       return dwarf_ast->CompleteTypeFromDWARF(dwarf_die, type, compiler_type);
   }
   return false;
@@ -1607,7 +1609,7 @@
 bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) {
   sc.Clear(false);
 
-  if (die && llvm::isa<DWARFCompileUnit>(die.GetCU())) {
+  if (die && llvm::isa<DWARFCompileUnit>(die.GetCU().GetCU())) {
     // Check if the symbol vendor already knows about this compile unit?
     sc.comp_unit =
         GetCompUnitForDWARFCompUnit(llvm::cast<DWARFCompileUnit>(*die.GetCU()));
@@ -2120,13 +2122,13 @@
     if (die.Tag() != DW_TAG_variable)
       return true;
 
-    auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
+    auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetMainCU());
     if (!dwarf_cu)
       return true;
     sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
 
     if (parent_decl_ctx) {
-      if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) {
+      if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetMainCU())) {
         CompilerDeclContext actual_parent_decl_ctx =
             dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
         if (!actual_parent_decl_ctx ||
@@ -2183,7 +2185,8 @@
       sc.module_sp = m_objfile_sp->GetModule();
     assert(sc.module_sp);
 
-    DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
+    DWARFCompileUnit *dwarf_cu =
+        llvm::dyn_cast<DWARFCompileUnit>(die.GetCU().GetMainCU());
     if (!dwarf_cu)
       return true;
     sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
@@ -2259,7 +2262,7 @@
     return true;
 
   if (die) {
-    if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU())) {
+    if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetMainCU())) {
       if (CompilerDeclContext actual_decl_ctx =
               dwarf_ast->GetDeclContextContainingUIDFromDWARF(die))
         return decl_ctx.IsContainedInLookup(actual_decl_ctx);
@@ -2463,7 +2466,7 @@
     return;
 
   m_index->GetTypes(name, [&](DWARFDIE die) {
-    if (!languages[GetLanguageFamily(*die.GetCU())])
+    if (!languages[GetLanguageFamily(*die.GetMainCU())])
       return true;
 
     llvm::SmallVector<CompilerContext, 4> die_context;
@@ -2511,7 +2514,7 @@
     if (!DIEInDeclContext(parent_decl_ctx, die))
       return true; // The containing decl contexts don't match
 
-    DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU());
+    DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetMainCU());
     if (!dwarf_ast)
       return true;
 
@@ -2540,7 +2543,7 @@
     Type *type_ptr = GetDIERefToType().lookup(*die.GetDIERef());
     if (type_ptr == nullptr) {
       SymbolContextScope *scope;
-      if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()))
+      if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetMainCU()))
         scope = GetCompUnitForDWARFCompUnit(*dwarf_cu);
       else
         scope = GetObjectFile()->GetModule().get();
@@ -2849,7 +2852,7 @@
         // looking for. We don't want to find a "Foo" type from Java if we
         // are looking for a "Foo" type for C, C++, ObjC, or ObjC++.
         if (type_system &&
-            !type_system->SupportsLanguage(GetLanguage(*type_die.GetCU())))
+            !type_system->SupportsLanguage(GetLanguage(*type_die.GetMainCU())))
           return true;
         bool try_resolving_type = false;
 
@@ -2932,7 +2935,8 @@
   if (!die)
     return {};
 
-  auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU()));
+  auto type_system_or_err =
+      GetTypeSystemForLanguage(GetLanguage(*die.GetMainCU()));
   if (auto err = type_system_or_err.takeError()) {
     LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
                    std::move(err), "Unable to parse type");
@@ -3004,7 +3008,7 @@
   CompileUnit *comp_unit = func.GetCompileUnit();
   lldbassert(comp_unit);
 
-  DWARFUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit);
+  DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(comp_unit);
   if (!dwarf_cu)
     return 0;
 
@@ -3023,7 +3027,7 @@
 size_t SymbolFileDWARF::ParseTypes(CompileUnit &comp_unit) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
   size_t types_added = 0;
-  DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
+  DWARFCompileUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
   if (dwarf_cu) {
     DWARFDIE dwarf_cu_die = dwarf_cu->DIE();
     if (dwarf_cu_die && dwarf_cu_die.HasChildren()) {
@@ -3087,8 +3091,8 @@
 VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc,
                                              const DWARFDIE &die,
                                              const lldb::addr_t func_low_pc) {
-  if (die.GetDWARF() != this)
-    return die.GetDWARF()->ParseVariableDIE(sc, die, func_low_pc);
+  if (die.GetMainDWARF() != this)
+    return die.GetMainDWARF()->ParseVariableDIE(sc, die, func_low_pc);
 
   if (!die)
     return nullptr;
@@ -3154,7 +3158,7 @@
       location_form = form_value;
       break;
     case DW_AT_specification:
-      spec_die = form_value.Reference();
+      spec_die = form_value.Reference(die.GetMainCU());
       break;
     case DW_AT_start_scope:
       // TODO: Implement this.
@@ -3257,7 +3261,7 @@
     // declaration context.
     if ((parent_tag == DW_TAG_compile_unit ||
          parent_tag == DW_TAG_partial_unit) &&
-        Language::LanguageIsCPlusPlus(GetLanguage(*die.GetCU())))
+        Language::LanguageIsCPlusPlus(GetLanguage(*die.GetMainCU())))
       mangled =
           GetDWARFDeclContext(die).GetQualifiedNameAsConstString().GetCString();
   }
@@ -3406,7 +3410,7 @@
 
   if (symbol_context_scope) {
     auto type_sp = std::make_shared<SymbolFileType>(
-        *this, GetUID(type_die_form.Reference()));
+        *this, GetUID(type_die_form.Reference(die.GetMainCU())));
 
     if (use_type_size_for_value && type_sp->GetType())
       location.UpdateValue(
@@ -3693,7 +3697,7 @@
 
       // Extract DW_AT_call_origin (the call target's DIE).
       if (attr == DW_AT_call_origin || attr == DW_AT_abstract_origin) {
-        call_origin = form_value.Reference();
+        call_origin = form_value.Reference(function_die.GetMainCU());
         if (!call_origin->IsValid()) {
           LLDB_LOG(log, "CollectCallEdges: Invalid call origin in {0}",
                    function_die.GetPubname());
@@ -3877,6 +3881,8 @@
 }
 
 DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DWARFUnit &unit) {
+  // Caller should have called GetMainCU().
+  lldbassert(unit.GetUnitDIEOnly().Tag() != DW_TAG_partial_unit);
   auto type_system_or_err = GetTypeSystem(unit);
   if (auto err = type_system_or_err.takeError()) {
     LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS),
@@ -3887,20 +3893,20 @@
 }
 
 CompilerDecl SymbolFileDWARF::GetDecl(const DWARFDIE &die) {
-  if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
+  if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetMainCU()))
     return dwarf_ast->GetDeclForUIDFromDWARF(die);
   return CompilerDecl();
 }
 
 CompilerDeclContext SymbolFileDWARF::GetDeclContext(const DWARFDIE &die) {
-  if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
+  if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetMainCU()))
     return dwarf_ast->GetDeclContextForUIDFromDWARF(die);
   return CompilerDeclContext();
 }
 
 CompilerDeclContext
 SymbolFileDWARF::GetContainingDeclContext(const DWARFDIE &die) {
-  if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetCU()))
+  if (DWARFASTParser *dwarf_ast = GetDWARFParser(*die.GetMainCU()))
     return dwarf_ast->GetDeclContextContainingUIDFromDWARF(die);
   return CompilerDeclContext();
 }
@@ -3910,7 +3916,7 @@
     return {};
   DWARFDeclContext dwarf_decl_ctx =
       die.GetDIE()->GetDWARFDeclContext(die.GetCU());
-  dwarf_decl_ctx.SetLanguage(GetLanguage(*die.GetCU()));
+  dwarf_decl_ctx.SetLanguage(GetLanguage(*die.GetMainCU()));
   return dwarf_decl_ctx;
 }
 
Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
+++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.h
@@ -10,6 +10,7 @@
 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_MANUALDWARFINDEX_H
 
 #include "Plugins/SymbolFile/DWARF/DWARFIndex.h"
+#include "Plugins/SymbolFile/DWARF/DWARFUnitPair.h"
 #include "Plugins/SymbolFile/DWARF/NameToDIE.h"
 #include "llvm/ADT/DenseSet.h"
 
@@ -68,10 +69,9 @@
   };
   void Index();
   void IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp, IndexSet &set);
+  void IndexUnit(DWARFUnitPair unit, SymbolFileDWARFDwo *dwp, IndexSet &set);
 
-  static void IndexUnitImpl(DWARFUnit &unit,
-                            const lldb::LanguageType cu_language,
-                            IndexSet &set);
+  static void IndexUnitImpl(DWARFUnitPair unit, IndexSet &set);
 
   /// The DWARF file which we are indexing. Set to nullptr after the index is
   /// built.
Index: lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp
@@ -8,6 +8,7 @@
 
 #include "Plugins/SymbolFile/DWARF/ManualDWARFIndex.h"
 #include "Plugins/Language/ObjC/ObjCLanguage.h"
+#include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h"
 #include "Plugins/SymbolFile/DWARF/DWARFDebugInfo.h"
 #include "Plugins/SymbolFile/DWARF/DWARFDeclContext.h"
 #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h"
@@ -128,35 +129,60 @@
 
 void ManualDWARFIndex::IndexUnit(DWARFUnit &unit, SymbolFileDWARFDwo *dwp,
                                  IndexSet &set) {
+  // DWZ DW_TAG_partial_unit will get indexed by DW_AT_import
+  // from its DW_TAG_compile_unit (possibly transitively).
+  // Try to prevent GetUnitDIEOnly() which is expensive.
+  if (unit.GetUnitDIEOnly().Tag() == DW_TAG_partial_unit)
+    return;
+  IndexUnit(&unit, dwp, set);
+}
+
+void ManualDWARFIndex::IndexUnit(DWARFUnitPair unit, SymbolFileDWARFDwo *dwp,
+                                 IndexSet &set) {
+  // Are we called for DW_TAG_compile_unit (contrary to DW_TAG_partial_unit)?
+  if (unit.GetMainCU() == unit.GetCU()) {
+    // DWZ DW_TAG_partial_unit will get indexed by DW_AT_import
+    // from its DW_TAG_compile_unit (possibly transitively).
+    // GetUnitDIEPtrOnly() is too expensive.
+    if (unit->GetUnitDIEOnly().Tag() == DW_TAG_partial_unit)
+      return;
+  }
+
   Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_LOOKUPS);
 
   if (log) {
-    m_module.LogMessage(
-        log, "ManualDWARFIndex::IndexUnit for unit at .debug_info[0x%8.8x]",
-        unit.GetOffset());
+    m_module.LogMessage(log,
+                        "ManualDWARFIndex::IndexUnit for unit at "
+                        ".debug_info[0x%8.8x] from .debug_info[0x%8.8x]",
+                        unit->GetOffset(), unit.GetMainCU()->GetOffset());
   }
 
-  const LanguageType cu_language = SymbolFileDWARF::GetLanguage(unit);
-
-  IndexUnitImpl(unit, cu_language, set);
+  IndexUnitImpl(unit, set);
 
-  if (SymbolFileDWARFDwo *dwo_symbol_file = unit.GetDwoSymbolFile()) {
+  if (SymbolFileDWARFDwo *dwo_symbol_file = unit->GetDwoSymbolFile()) {
     // Type units in a dwp file are indexed separately, so we just need to
     // process the split unit here. However, if the split unit is in a dwo file,
     // then we need to process type units here.
     if (dwo_symbol_file == dwp) {
-      IndexUnitImpl(unit.GetNonSkeletonUnit(), cu_language, set);
+      IndexUnitImpl(&unit->GetNonSkeletonUnit(), set);
     } else {
+      assert(unit.GetCU() == unit.GetMainCU());
       DWARFDebugInfo &dwo_info = dwo_symbol_file->DebugInfo();
-      for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i)
-        IndexUnitImpl(*dwo_info.GetUnitAtIndex(i), cu_language, set);
+      for (size_t i = 0; i < dwo_info.GetNumUnits(); ++i) {
+        // Separate main CU is not used for DWO CUs.
+        DWARFUnit *dwo_cu = dwo_info.GetUnitAtIndex(i);
+        IndexUnitImpl(dwo_cu, set);
+      }
     }
   }
 }
 
-void ManualDWARFIndex::IndexUnitImpl(DWARFUnit &unit,
-                                     const LanguageType cu_language,
-                                     IndexSet &set) {
+void ManualDWARFIndex::IndexUnitImpl(DWARFUnitPair unitpair, IndexSet &set) {
+
+  DWARFUnit &unit = unitpair;
+  const LanguageType cu_language =
+      SymbolFileDWARF::GetLanguage(*unitpair.GetMainCU());
+
   for (const DWARFDebugInfoEntry &die : unit.dies()) {
     const dw_tag_t tag = die.Tag();
 
@@ -239,7 +265,7 @@
       }
     }
 
-    DIERef ref = *DWARFDIE(&unit, &die).GetDIERef();
+    DIERef ref = *DWARFDIE(unitpair, &die).GetDIERef();
     switch (tag) {
     case DW_TAG_inlined_subroutine:
     case DW_TAG_subprogram:
@@ -272,7 +298,7 @@
           }
           // If we have a mangled name, then the DW_AT_name attribute is
           // usually the method name without the class or any parameters
-          bool is_method = DWARFDIE(&unit, &die).IsMethod();
+          bool is_method = DWARFDIE(unitpair, &die).IsMethod();
 
           if (is_method)
             set.function_methods.Insert(ConstString(name), ref);
Index: lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp
@@ -268,7 +268,7 @@
     return false;
 
   for (size_t i = 0; i < num_atoms; ++i) {
-    DWARFFormValue form_value(nullptr, header_data.atoms[i].form);
+    DWARFFormValue form_value({}, header_data.atoms[i].form);
 
     if (!form_value.ExtractValue(data, offset_ptr))
       return false;
Index: lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp
@@ -52,6 +52,7 @@
 
   cu = &cu->GetNonSkeletonUnit();
   if (llvm::Optional<uint64_t> die_offset = entry.getDIEUnitOffset())
+    // FIXME: .debug_names have no DWZ support yet.
     return DIERef(cu->GetSymbolFileDWARF().GetDwoNum(),
                   DIERef::Section::DebugInfo, cu->GetOffset() + *die_offset);
 
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnitPair.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnitPair.h
@@ -0,0 +1,39 @@
+//===-- DWARFUnitPair.h -----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_DWARFUnitPair_h_
+#define liblldb_DWARFUnitPair_h_
+
+#include "lldb/Symbol/TypeSystem.h"
+#include "lldb/lldb-enumerations.h"
+#include "llvm/Support/Error.h"
+
+class DWARFUnit;
+
+class DWARFUnitPair {
+public:
+  DWARFUnitPair();
+  DWARFUnitPair(DWARFUnit *cu, DWARFUnit *main_cu);
+  DWARFUnitPair(DWARFUnit *main_cu);
+  DWARFUnit *operator->() const;
+  DWARFUnit &operator*() const;
+  DWARFUnit *GetCU() const;
+  DWARFUnit *GetMainCU() const;
+  explicit operator bool() const;
+  operator DWARFUnit *() const;
+  operator DWARFUnit &() const;
+  bool operator==(const DWARFUnitPair &rhs) const;
+  void Clear();
+
+private:
+  DWARFUnit *m_cu;
+  // For non-DWZ setups it is equal to 'm_cu'.
+  DWARFUnit *m_main_cu;
+};
+
+#endif // liblldb_DWARFUnitPair_h_
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnitPair.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnitPair.cpp
@@ -0,0 +1,48 @@
+//===-- DWARFUnitPair.cpp ---------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Plugins/SymbolFile/DWARF/DWARFUnitPair.h"
+#include <assert.h>
+
+DWARFUnitPair::DWARFUnitPair() : m_cu(nullptr), m_main_cu(nullptr) {}
+DWARFUnitPair::DWARFUnitPair(DWARFUnit *cu, DWARFUnit *main_cu)
+    : m_cu(cu), m_main_cu(main_cu) {
+  assert(m_cu);
+  assert(m_main_cu);
+}
+DWARFUnitPair::DWARFUnitPair(DWARFUnit *main_cu)
+    : DWARFUnitPair(static_cast<DWARFUnit *>(main_cu), main_cu) {}
+DWARFUnit *DWARFUnitPair::operator->() const {
+  assert(m_cu);
+  return m_cu;
+}
+DWARFUnit &DWARFUnitPair::operator*() const {
+  assert(m_cu);
+  return *m_cu;
+}
+DWARFUnit *DWARFUnitPair::GetCU() const {
+  assert(m_cu);
+  return m_cu;
+}
+DWARFUnit *DWARFUnitPair::GetMainCU() const { return m_main_cu; }
+
+DWARFUnitPair::operator bool() const { return m_cu != nullptr; }
+DWARFUnitPair::operator DWARFUnit *() const { /*assert(m_cu);*/
+  return m_cu;
+}
+DWARFUnitPair::operator DWARFUnit &() const {
+  assert(m_cu);
+  return *m_cu;
+}
+bool DWARFUnitPair::operator==(const DWARFUnitPair &rhs) const {
+  return m_cu == rhs.m_cu && m_main_cu == rhs.m_main_cu;
+}
+void DWARFUnitPair::Clear() {
+  m_cu = nullptr;
+  m_main_cu = nullptr;
+}
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -169,11 +169,24 @@
 
   void SetBaseAddress(dw_addr_t base_addr);
 
-  DWARFBaseDIE GetUnitDIEOnly() { return {this, GetUnitDIEPtrOnly()}; }
+  DWARFDebugInfoEntry GetUnitDIEOnly() {
+    const DWARFDebugInfoEntry *dieptr = GetUnitDIEPtrOnly();
+    if (!dieptr)
+      return {};
+    return *dieptr;
+  }
+
+  DWARFBaseDIE GetUnitDIEOnly(DWARFUnit *main_cu) {
+    return {DWARFUnitPair(this, main_cu), DIEPtr()};
+  }
+
+  DWARFDIE DIE(DWARFUnit *main_cu) {
+    return {DWARFUnitPair(this, main_cu), DIEPtr()};
+  }
 
-  DWARFDIE DIE() { return DWARFDIE(this, DIEPtr()); }
+  const DWARFDebugInfoEntry *GetDIEPtr(dw_offset_t die_offset);
 
-  DWARFDIE GetDIE(dw_offset_t die_offset);
+  DWARFDIE GetDIE(DWARFUnit *main_cu, dw_offset_t die_offset);
 
   DWARFUnit &GetNonSkeletonUnit();
 
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -87,8 +87,9 @@
     return; // Can't fetch the compile unit from the dwo file.
   dwo_cu->SetUserData(this);
 
-  DWARFBaseDIE dwo_cu_die = dwo_cu->GetUnitDIEOnly();
-  if (!dwo_cu_die.IsValid())
+  // 'main_cu' is not used.
+  const DWARFDebugInfoEntry *dwo_cu_die = dwo_cu->GetUnitDIEPtrOnly();
+  if (!dwo_cu_die)
     return; // Can't fetch the compile unit DIE from the dwo file.
 
   // Here for DWO CU we want to use the address base set in the skeleton unit
@@ -598,31 +599,39 @@
   return die.GetOffset() < die_offset;
 }
 
-// GetDIE()
-//
-// Get the DIE (Debug Information Entry) with the specified offset by first
-// checking if the DIE is contained within this compile unit and grabbing the
-// DIE from this compile unit. Otherwise we grab the DIE from the DWARF file.
-DWARFDIE
-DWARFUnit::GetDIE(dw_offset_t die_offset) {
+const DWARFDebugInfoEntry *DWARFUnit::GetDIEPtr(dw_offset_t die_offset) {
   if (die_offset == DW_INVALID_OFFSET)
-    return DWARFDIE(); // Not found
+    return nullptr;
 
   if (!ContainsDIEOffset(die_offset)) {
     GetSymbolFileDWARF().GetObjectFile()->GetModule()->ReportError(
         "GetDIE for DIE 0x%" PRIx32 " is outside of its CU 0x%" PRIx32,
         die_offset, GetOffset());
-    return DWARFDIE(); // Not found
+    return nullptr;
   }
 
   ExtractDIEsIfNeeded();
   DWARFDebugInfoEntry::const_iterator end = m_die_array.cend();
   DWARFDebugInfoEntry::const_iterator pos =
       lower_bound(m_die_array.cbegin(), end, die_offset, CompareDIEOffset);
+  if (pos != end) {
+    if (die_offset == (*pos).GetOffset())
+      return &(*pos);
+  }
+  return nullptr;
+}
 
-  if (pos != end && die_offset == (*pos).GetOffset())
-    return DWARFDIE(this, &(*pos));
-  return DWARFDIE(); // Not found
+// GetDIE()
+//
+// Get the DIE (Debug Information Entry) with the specified offset by first
+// checking if the DIE is contained within this compile unit and grabbing the
+// DIE from this compile unit. Otherwise we grab the DIE from the DWARF file.
+DWARFDIE
+DWARFUnit::GetDIE(DWARFUnit *main_cu, dw_offset_t die_offset) {
+  const DWARFDebugInfoEntry *die = GetDIEPtr(die_offset);
+  if (!die)
+    return DWARFDIE();
+  return DWARFDIE({this, main_cu}, die);
 }
 
 DWARFUnit &DWARFUnit::GetNonSkeletonUnit() {
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFSimpleDIE.h
===================================================================
--- /dev/null
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFSimpleDIE.h
@@ -0,0 +1,37 @@
+//===-- DWARFSimpleDIE.h ----------------------------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFSIMPLEDIE_H
+#define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFSIMPLEDIE_H
+
+#include "DWARFBaseDIE.h"
+
+class DWARFSimpleDIE {
+public:
+  DWARFSimpleDIE() {}
+  DWARFSimpleDIE(DWARFUnit *cu, const DWARFDebugInfoEntry *die)
+      : m_cu(cu), m_die(die) {
+    assert(m_cu);
+    assert(m_die);
+  }
+  DWARFSimpleDIE(const DWARFBaseDIE &die)
+      : DWARFSimpleDIE(die.GetCU(), die.GetDIE()) {}
+  DWARFUnit *GetCU() const { return m_cu; }
+  const DWARFDebugInfoEntry *GetDIE() const { return m_die; }
+  dw_offset_t GetOffset() const;
+  size_t GetAttributes(DWARFAttributes &attributes,
+                       DWARFBaseDIE::Recurse recurse) const;
+  bool IsValid() const { return m_die != nullptr; }
+  explicit operator bool() const { return IsValid(); }
+
+private:
+  DWARFUnit *m_cu = nullptr;
+  const DWARFDebugInfoEntry *m_die = nullptr;
+};
+
+#endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFSIMPLEDIE_H
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFSimpleDIE.cpp
===================================================================
--- /dev/null
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFSimpleDIE.cpp
@@ -0,0 +1,22 @@
+//===-- DWARFSimpleDIE.cpp ------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "DWARFSimpleDIE.h"
+#include "DWARFDebugInfoEntry.h"
+
+dw_offset_t DWARFSimpleDIE::GetOffset() const {
+  return !m_die ? DW_INVALID_OFFSET : m_die->GetOffset();
+}
+
+size_t DWARFSimpleDIE::GetAttributes(DWARFAttributes &attributes,
+                                     DWARFBaseDIE::Recurse recurse) const {
+  if (IsValid())
+    return m_die->GetAttributes(m_cu, attributes, recurse);
+  attributes.Clear();
+  return 0;
+}
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.h
@@ -16,6 +16,7 @@
 class DWARFUnit;
 class SymbolFileDWARF;
 class DWARFDIE;
+class DWARFSimpleDIE;
 
 class DWARFFormValue {
 public:
@@ -58,7 +59,8 @@
   static llvm::Optional<uint8_t> GetFixedSize(dw_form_t form,
                                               const DWARFUnit *u);
   llvm::Optional<uint8_t> GetFixedSize() const;
-  DWARFDIE Reference() const;
+  DWARFSimpleDIE Reference() const;
+  DWARFDIE Reference(DWARFUnit *main_unit) const;
   uint64_t Reference(dw_offset_t offset) const;
   bool Boolean() const { return m_value.value.uval != 0; }
   uint64_t Unsigned() const { return m_value.value.uval; }
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp
@@ -13,8 +13,10 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Utility/Stream.h"
 
+#include "DWARFCompileUnit.h"
 #include "DWARFDebugInfo.h"
 #include "DWARFFormValue.h"
+#include "DWARFSimpleDIE.h"
 #include "DWARFUnit.h"
 
 class DWARFUnit;
@@ -498,14 +500,14 @@
       &offset, index_size);
 }
 
-DWARFDIE DWARFFormValue::Reference() const {
+DWARFSimpleDIE DWARFFormValue::Reference() const {
   uint64_t value = m_value.value.uval;
   switch (m_form) {
   case DW_FORM_ref1:
   case DW_FORM_ref2:
   case DW_FORM_ref4:
   case DW_FORM_ref8:
-  case DW_FORM_ref_udata:
+  case DW_FORM_ref_udata: {
     assert(m_unit); // Unit must be valid for DW_FORM_ref forms that are compile
                     // unit relative or we will get this wrong
     value += m_unit->GetOffset();
@@ -515,7 +517,9 @@
           value);
       return {};
     }
-    return const_cast<DWARFUnit *>(m_unit)->GetDIE(value);
+    DWARFUnit *cu = const_cast<DWARFUnit *>(m_unit);
+    return {cu, cu->GetDIEPtr(value)};
+  }
 
   case DW_FORM_ref_addr: {
     DWARFUnit *ref_cu =
@@ -527,7 +531,7 @@
           value);
       return {};
     }
-    return ref_cu->GetDIE(value);
+    return {ref_cu, ref_cu->GetDIEPtr(value)};
   }
 
   case DW_FORM_ref_sig8: {
@@ -535,7 +539,7 @@
         m_unit->GetSymbolFileDWARF().DebugInfo().GetTypeUnitForHash(value);
     if (!tu)
       return {};
-    return tu->GetDIE(tu->GetTypeOffset());
+    return {tu, tu->GetDIEPtr(tu->GetTypeOffset())};
   }
 
   default:
@@ -543,6 +547,20 @@
   }
 }
 
+DWARFDIE DWARFFormValue::Reference(DWARFUnit *main_unit) const {
+  DWARFSimpleDIE die = Reference();
+  if (!die.IsValid())
+    return {};
+
+  // MainCU may differ from CU only for DW_TAG_partial_unit units.
+  if (die.GetCU()->GetUnitDIEOnly().Tag() != DW_TAG_partial_unit) {
+    main_unit = die.GetCU();
+    lldbassert(llvm::isa<DWARFCompileUnit>(main_unit) ||
+               llvm::isa<DWARFTypeUnit>(main_unit));
+  }
+  return {{die.GetCU(), main_unit}, die.GetDIE()};
+}
+
 uint64_t DWARFFormValue::Reference(dw_offset_t base_offset) const {
   uint64_t value = m_value.value.uval;
   switch (m_form) {
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.h
@@ -67,10 +67,14 @@
       const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
       bool check_specification_or_abstract_origin = false) const;
 
-  DWARFDIE GetAttributeValueAsReference(
+  DWARFSimpleDIE GetAttributeValueAsReference(
       const DWARFUnit *cu, const dw_attr_t attr,
       bool check_specification_or_abstract_origin = false) const;
 
+  DWARFDIE GetAttributeValueAsReference(
+      DWARFUnitPair cu, const dw_attr_t attr,
+      bool check_specification_or_abstract_origin = false) const;
+
   uint64_t GetAttributeValueAsAddress(
       const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
       bool check_specification_or_abstract_origin = false) const;
@@ -87,21 +91,19 @@
   size_t GetAttributeAddressRanges(
       DWARFUnit *cu, DWARFRangeList &ranges, bool check_hi_lo_pc,
       bool check_specification_or_abstract_origin = false) const;
-
+  const char *GetName(DWARFUnitPair cu) const;
   const char *GetName(const DWARFUnit *cu) const;
-
-  const char *GetMangledName(const DWARFUnit *cu,
+  const char *GetMangledName(DWARFUnitPair cu,
                              bool substitute_name_allowed = true) const;
-
+  const char *GetPubname(DWARFUnitPair cu) const;
   const char *GetPubname(const DWARFUnit *cu) const;
-
-  const char *GetQualifiedName(DWARFUnit *cu, std::string &storage) const;
-
-  const char *GetQualifiedName(DWARFUnit *cu, const DWARFAttributes &attributes,
+  const char *GetQualifiedName(DWARFUnitPair cu, std::string &storage) const;
+  const char *GetQualifiedName(DWARFUnitPair cu,
+                               const DWARFAttributes &attributes,
                                std::string &storage) const;
 
   bool GetDIENamesAndRanges(
-      DWARFUnit *cu, const char *&name, const char *&mangled,
+      DWARFUnitPair cu, const char *&name, const char *&mangled,
       DWARFRangeList &rangeList, int &decl_file, int &decl_line,
       int &decl_column, int &call_file, int &call_line, int &call_column,
       lldb_private::DWARFExpression *frame_base = nullptr) const;
@@ -147,10 +149,10 @@
     return HasChildren() ? this + 1 : nullptr;
   }
 
-  DWARFDeclContext GetDWARFDeclContext(DWARFUnit *cu) const;
+  DWARFDeclContext GetDWARFDeclContext(DWARFUnitPair cu) const;
 
-  DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu) const;
-  DWARFDIE GetParentDeclContextDIE(DWARFUnit *cu,
+  DWARFDIE GetParentDeclContextDIE(DWARFUnitPair cu) const;
+  DWARFDIE GetParentDeclContextDIE(DWARFUnitPair cu,
                                    const DWARFAttributes &attributes) const;
 
   void SetSiblingIndex(uint32_t idx) { m_sibling_idx = idx; }
@@ -163,7 +165,7 @@
 
 protected:
   static DWARFDeclContext
-  GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnit *cu);
+  GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die, DWARFUnitPair cu);
 
   dw_offset_t m_offset; // Offset within the .debug_info/.debug_types
   uint32_t m_parent_idx = 0;   // How many to subtract from "this" to get the
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp
@@ -26,6 +26,7 @@
 #include "DWARFDebugRanges.h"
 #include "DWARFDeclContext.h"
 #include "DWARFFormValue.h"
+#include "DWARFSimpleDIE.h"
 #include "DWARFUnit.h"
 #include "SymbolFileDWARF.h"
 #include "SymbolFileDWARFDwo.h"
@@ -228,7 +229,7 @@
 // Gets the valid address ranges for a given DIE by looking for a
 // DW_AT_low_pc/DW_AT_high_pc pair, DW_AT_entry_pc, or DW_AT_ranges attributes.
 bool DWARFDebugInfoEntry::GetDIENamesAndRanges(
-    DWARFUnit *cu, const char *&name, const char *&mangled,
+    DWARFUnitPair cu, const char *&name, const char *&mangled,
     DWARFRangeList &ranges, int &decl_file, int &decl_line, int &decl_column,
     int &call_file, int &call_line, int &call_column,
     DWARFExpression *frame_base) const {
@@ -302,11 +303,11 @@
           break;
 
         case DW_AT_abstract_origin:
-          dies.push_back(form_value.Reference());
+          dies.push_back(form_value.Reference(cu.GetMainCU()));
           break;
 
         case DW_AT_specification:
-          dies.push_back(form_value.Reference());
+          dies.push_back(form_value.Reference(cu.GetMainCU()));
           break;
 
         case DW_AT_decl_file:
@@ -440,7 +441,7 @@
       if (recurse == Recurse::yes &&
           ((attr == DW_AT_specification) || (attr == DW_AT_abstract_origin))) {
         if (form_value.ExtractValue(data, &offset)) {
-          DWARFDIE spec_die = form_value.Reference();
+          DWARFSimpleDIE spec_die = form_value.Reference();
           if (spec_die)
             spec_die.GetDIE()->GetAttributes(spec_die.GetCU(), attributes,
                                              recurse, curr_depth + 1);
@@ -494,7 +495,7 @@
 
   if (check_specification_or_abstract_origin) {
     if (GetAttributeValue(cu, DW_AT_specification, form_value)) {
-      DWARFDIE die = form_value.Reference();
+      DWARFSimpleDIE die = form_value.Reference();
       if (die) {
         dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
             die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
@@ -504,7 +505,7 @@
     }
 
     if (GetAttributeValue(cu, DW_AT_abstract_origin, form_value)) {
-      DWARFDIE die = form_value.Reference();
+      DWARFSimpleDIE die = form_value.Reference();
       if (die) {
         dw_offset_t die_offset = die.GetDIE()->GetAttributeValue(
             die.GetCU(), attr, form_value, end_attr_offset_ptr, false);
@@ -549,7 +550,7 @@
 //
 // Get the value of an attribute as reference and fix up and compile unit
 // relative offsets as needed.
-DWARFDIE DWARFDebugInfoEntry::GetAttributeValueAsReference(
+DWARFSimpleDIE DWARFDebugInfoEntry::GetAttributeValueAsReference(
     const DWARFUnit *cu, const dw_attr_t attr,
     bool check_specification_or_abstract_origin) const {
   DWARFFormValue form_value;
@@ -559,6 +560,16 @@
   return {};
 }
 
+DWARFDIE DWARFDebugInfoEntry::GetAttributeValueAsReference(
+    DWARFUnitPair cu, const dw_attr_t attr,
+    bool check_specification_or_abstract_origin) const {
+  DWARFSimpleDIE die = GetAttributeValueAsReference(
+      cu.GetCU(), attr, check_specification_or_abstract_origin);
+  if (!die.IsValid())
+    return {};
+  return {{die.GetCU(), cu.GetMainCU()}, die.GetDIE()};
+}
+
 uint64_t DWARFDebugInfoEntry::GetAttributeValueAsAddress(
     const DWARFUnit *cu, const dw_attr_t attr, uint64_t fail_value,
     bool check_specification_or_abstract_origin) const {
@@ -638,7 +649,7 @@
 //
 // Get value of the DW_AT_name attribute and return it if one exists, else
 // return NULL.
-const char *DWARFDebugInfoEntry::GetName(const DWARFUnit *cu) const {
+const char *DWARFDebugInfoEntry::GetName(DWARFUnitPair cu) const {
   return GetAttributeValueAsString(cu, DW_AT_name, nullptr, true);
 }
 
@@ -647,7 +658,7 @@
 // Get value of the DW_AT_MIPS_linkage_name attribute and return it if one
 // exists, else return the value of the DW_AT_name attribute
 const char *
-DWARFDebugInfoEntry::GetMangledName(const DWARFUnit *cu,
+DWARFDebugInfoEntry::GetMangledName(DWARFUnitPair cu,
                                     bool substitute_name_allowed) const {
   const char *name = nullptr;
 
@@ -670,7 +681,7 @@
 //
 // Get value the name for a DIE as it should appear for a .debug_pubnames or
 // .debug_pubtypes section.
-const char *DWARFDebugInfoEntry::GetPubname(const DWARFUnit *cu) const {
+const char *DWARFDebugInfoEntry::GetPubname(DWARFUnitPair cu) const {
   const char *name = nullptr;
   if (!cu)
     return name;
@@ -713,7 +724,7 @@
 
 DWARFDeclContext
 DWARFDebugInfoEntry::GetDWARFDeclContextStatic(const DWARFDebugInfoEntry *die,
-                                               DWARFUnit *cu) {
+                                               DWARFUnitPair cu) {
   DWARFDeclContext dwarf_decl_ctx;
   for (;;) {
     const dw_tag_t tag = die->Tag();
@@ -731,12 +742,13 @@
   }
 }
 
-DWARFDeclContext DWARFDebugInfoEntry::GetDWARFDeclContext(DWARFUnit *cu) const {
+DWARFDeclContext
+DWARFDebugInfoEntry::GetDWARFDeclContext(DWARFUnitPair cu) const {
   return GetDWARFDeclContextStatic(this, cu);
 }
 
 DWARFDIE
-DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnit *cu) const {
+DWARFDebugInfoEntry::GetParentDeclContextDIE(DWARFUnitPair cu) const {
   DWARFAttributes attributes;
   GetAttributes(cu, attributes, Recurse::yes);
   return GetParentDeclContextDIE(cu, attributes);
@@ -744,7 +756,7 @@
 
 DWARFDIE
 DWARFDebugInfoEntry::GetParentDeclContextDIE(
-    DWARFUnit *cu, const DWARFAttributes &attributes) const {
+    DWARFUnitPair cu, const DWARFAttributes &attributes) const {
   DWARFDIE die(cu, const_cast<DWARFDebugInfoEntry *>(this));
 
   while (die) {
@@ -766,14 +778,16 @@
       }
     }
 
-    DWARFDIE spec_die = attributes.FormValueAsReference(DW_AT_specification);
+    DWARFDIE spec_die =
+        attributes.FormValueAsReference(DW_AT_specification, cu.GetMainCU());
     if (spec_die) {
       DWARFDIE decl_ctx_die = spec_die.GetParentDeclContextDIE();
       if (decl_ctx_die)
         return decl_ctx_die;
     }
 
-    DWARFDIE abs_die = attributes.FormValueAsReference(DW_AT_abstract_origin);
+    DWARFDIE abs_die =
+        attributes.FormValueAsReference(DW_AT_abstract_origin, cu.GetMainCU());
     if (abs_die) {
       DWARFDIE decl_ctx_die = abs_die.GetParentDeclContextDIE();
       if (decl_ctx_die)
@@ -785,7 +799,7 @@
   return DWARFDIE();
 }
 
-const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
+const char *DWARFDebugInfoEntry::GetQualifiedName(DWARFUnitPair cu,
                                                   std::string &storage) const {
   DWARFAttributes attributes;
   GetAttributes(cu, attributes, Recurse::yes);
@@ -793,7 +807,7 @@
 }
 
 const char *
-DWARFDebugInfoEntry::GetQualifiedName(DWARFUnit *cu,
+DWARFDebugInfoEntry::GetQualifiedName(DWARFUnitPair cu,
                                       const DWARFAttributes &attributes,
                                       std::string &storage) const {
 
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -41,6 +41,7 @@
   DWARFUnit *GetUnitContainingDIEOffset(DIERef::Section section,
                                         dw_offset_t die_offset);
   DWARFUnit *GetUnit(const DIERef &die_ref);
+  DWARFUnit *GetMainUnit(const DIERef &die_ref);
   DWARFTypeUnit *GetTypeUnitForHash(uint64_t hash);
   bool ContainsTypeUnits();
   DWARFDIE GetDIE(const DIERef &die_ref);
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -57,6 +57,8 @@
   const size_t num_units = GetNumUnits();
   for (size_t idx = 0; idx < num_units; ++idx) {
     DWARFUnit *cu = GetUnitAtIndex(idx);
+    if (!llvm::isa<DWARFCompileUnit>(cu))
+      continue;
 
     dw_offset_t offset = cu->GetOffset();
     if (cus_with_data.find(offset) == cus_with_data.end())
@@ -151,6 +153,10 @@
   return GetUnitContainingDIEOffset(die_ref.section(), die_ref.die_offset());
 }
 
+DWARFUnit *DWARFDebugInfo::GetMainUnit(const DIERef &die_ref) {
+  return GetUnit(die_ref);
+}
+
 DWARFUnit *
 DWARFDebugInfo::GetUnitContainingDIEOffset(DIERef::Section section,
                                            dw_offset_t die_offset) {
@@ -180,7 +186,9 @@
 DWARFDIE
 DWARFDebugInfo::GetDIE(const DIERef &die_ref) {
   DWARFUnit *cu = GetUnit(die_ref);
-  if (cu)
-    return cu->GetNonSkeletonUnit().GetDIE(die_ref.die_offset());
+  if (cu) {
+    DWARFUnit *main_cu = GetMainUnit(die_ref);
+    return cu->GetNonSkeletonUnit().GetDIE(main_cu, die_ref.die_offset());
+  }
   return DWARFDIE(); // Not found
 }
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.h
@@ -37,7 +37,7 @@
 
   void AppendTypeName(lldb_private::Stream &s) const;
 
-  lldb_private::Type *ResolveType() const;
+  lldb_private::Type *ResolveType(SymbolFileDWARF &dwarf) const;
 
   // Resolve a type by UID using this DIE's DWARF file
   lldb_private::Type *ResolveTypeUID(const DWARFDIE &die) const;
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp
@@ -9,6 +9,7 @@
 #include "DWARFDIE.h"
 
 #include "DWARFASTParser.h"
+#include "DWARFCompileUnit.h"
 #include "DWARFDebugInfo.h"
 #include "DWARFDebugInfoEntry.h"
 #include "DWARFDeclContext.h"
@@ -121,7 +122,7 @@
 DWARFDIE
 DWARFDIE::GetDIE(dw_offset_t die_offset) const {
   if (IsValid())
-    return m_cu->GetDIE(die_offset);
+    return m_cu->GetDIE(GetMainCU(), die_offset);
   else
     return DWARFDIE();
 }
@@ -129,12 +130,12 @@
 DWARFDIE
 DWARFDIE::GetAttributeValueAsReferenceDIE(const dw_attr_t attr) const {
   if (IsValid()) {
-    DWARFUnit *cu = GetCU();
+    DWARFUnitPair cu = GetCU();
     const bool check_specification_or_abstract_origin = true;
     DWARFFormValue form_value;
     if (m_die->GetAttributeValue(cu, attr, form_value, nullptr,
                                  check_specification_or_abstract_origin))
-      return form_value.Reference();
+      return form_value.Reference(cu.GetMainCU());
   }
   return DWARFDIE();
 }
@@ -345,15 +346,15 @@
   }
 }
 
-lldb_private::Type *DWARFDIE::ResolveType() const {
+lldb_private::Type *DWARFDIE::ResolveType(SymbolFileDWARF &dwarf) const {
   if (IsValid())
-    return GetDWARF()->ResolveType(*this, true);
+    return dwarf.ResolveType(*this, true);
   else
     return nullptr;
 }
 
 lldb_private::Type *DWARFDIE::ResolveTypeUID(const DWARFDIE &die) const {
-  if (SymbolFileDWARF *dwarf = GetDWARF())
+  if (SymbolFileDWARF *dwarf = GetMainDWARF())
     return dwarf->ResolveTypeUID(die, true);
   return nullptr;
 }
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -24,6 +24,14 @@
 
   DWARFDIE LookupAddress(const dw_addr_t address);
 
+  DWARFDIE GetDIE(dw_offset_t die_offset) {
+    return DWARFUnit::GetDIE(this, die_offset);
+  }
+
+  DWARFBaseDIE GetUnitDIEOnly() { return {DWARFUnitPair(this), DIEPtr()}; }
+
+  DWARFDIE DIE() { return {DWARFUnitPair(this), DIEPtr()}; }
+
 private:
   DWARFCompileUnit(SymbolFileDWARF &dwarf, lldb::user_id_t uid,
                    const DWARFUnitHeader &header,
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -39,6 +39,8 @@
   const dw_offset_t cu_offset = GetOffset();
   if (die) {
     DWARFRangeList ranges;
+    // It does not make sense to build address table for DW_TAG_partial_unit as
+    // those never contain any addresses.
     const size_t num_ranges =
         die->GetAttributeAddressRanges(this, ranges, /*check_hi_lo_pc=*/true);
     if (num_ranges > 0) {
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -9,6 +9,7 @@
 #ifndef LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H
 #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFBASEDIE_H
 
+#include "Plugins/SymbolFile/DWARF/DWARFUnitPair.h"
 #include "lldb/Core/dwarf.h"
 #include "lldb/lldb-types.h"
 
@@ -26,19 +27,12 @@
 public:
   DWARFBaseDIE() = default;
 
-  DWARFBaseDIE(DWARFUnit *cu, DWARFDebugInfoEntry *die)
+  DWARFBaseDIE(DWARFUnitPair cu, DWARFDebugInfoEntry *die)
       : m_cu(cu), m_die(die) {}
 
-  DWARFBaseDIE(const DWARFUnit *cu, DWARFDebugInfoEntry *die)
-      : m_cu(const_cast<DWARFUnit *>(cu)), m_die(die) {}
-
-  DWARFBaseDIE(DWARFUnit *cu, const DWARFDebugInfoEntry *die)
+  DWARFBaseDIE(DWARFUnitPair cu, const DWARFDebugInfoEntry *die)
       : m_cu(cu), m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
 
-  DWARFBaseDIE(const DWARFUnit *cu, const DWARFDebugInfoEntry *die)
-      : m_cu(const_cast<DWARFUnit *>(cu)),
-        m_die(const_cast<DWARFDebugInfoEntry *>(die)) {}
-
   // Tests
   explicit operator bool() const { return IsValid(); }
 
@@ -50,14 +44,16 @@
 
   // Accessors
   SymbolFileDWARF *GetDWARF() const;
+  SymbolFileDWARF *GetMainDWARF() const;
 
-  DWARFUnit *GetCU() const { return m_cu; }
+  DWARFUnitPair GetCU() const { return m_cu; }
+  DWARFUnit *GetMainCU() const { return m_cu.GetMainCU(); }
 
   DWARFDebugInfoEntry *GetDIE() const { return m_die; }
 
   llvm::Optional<DIERef> GetDIERef() const;
 
-  void Set(DWARFUnit *cu, DWARFDebugInfoEntry *die) {
+  void Set(DWARFUnitPair cu, DWARFDebugInfoEntry *die) {
     if (cu && die) {
       m_cu = cu;
       m_die = die;
@@ -67,7 +63,7 @@
   }
 
   void Clear() {
-    m_cu = nullptr;
+    m_cu.Clear();
     m_die = nullptr;
   }
 
@@ -115,8 +111,8 @@
                        Recurse recurse = Recurse::yes) const;
 
 protected:
-  DWARFUnit *m_cu = nullptr;
-  DWARFDebugInfoEntry *m_die = nullptr;
+  DWARFUnitPair m_cu;
+  DWARFDebugInfoEntry *m_die;
 };
 
 bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs);
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -8,8 +8,10 @@
 
 #include "DWARFBaseDIE.h"
 
-#include "DWARFUnit.h"
+#include "DWARFCompileUnit.h"
 #include "DWARFDebugInfoEntry.h"
+#include "DWARFSimpleDIE.h"
+#include "DWARFUnit.h"
 #include "SymbolFileDWARF.h"
 
 #include "lldb/Core/Module.h"
@@ -63,7 +65,7 @@
 
 lldb::user_id_t DWARFBaseDIE::GetID() const {
   if (IsValid())
-    return GetDWARF()->GetUID(*this);
+    return GetMainDWARF()->GetUID(*this);
   return LLDB_INVALID_UID;
 }
 
@@ -96,6 +98,12 @@
     return nullptr;
 }
 
+SymbolFileDWARF *DWARFBaseDIE::GetMainDWARF() const {
+  if (m_cu.GetMainCU())
+    return &m_cu.GetMainCU()->GetSymbolFileDWARF();
+  return GetDWARF();
+}
+
 bool DWARFBaseDIE::HasChildren() const {
   return m_die && m_die->HasChildren();
 }
@@ -106,14 +114,12 @@
 
 size_t DWARFBaseDIE::GetAttributes(DWARFAttributes &attributes,
                                    Recurse recurse) const {
-  if (IsValid())
-    return m_die->GetAttributes(m_cu, attributes, recurse);
-  attributes.Clear();
-  return 0;
+  return DWARFSimpleDIE(*this).GetAttributes(attributes, recurse);
 }
 
 bool operator==(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs) {
-  return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU();
+  return lhs.GetDIE() == rhs.GetDIE() && lhs.GetCU() == rhs.GetCU() &&
+         lhs.GetMainCU() == rhs.GetMainCU();
 }
 
 bool operator!=(const DWARFBaseDIE &lhs, const DWARFBaseDIE &rhs) {
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
@@ -60,8 +60,8 @@
     return m_infos[i].attr.get_value();
   }
   bool ExtractFormValueAtIndex(uint32_t i, DWARFFormValue &form_value) const;
-  DWARFDIE FormValueAsReferenceAtIndex(uint32_t i) const;
-  DWARFDIE FormValueAsReference(dw_attr_t attr) const;
+  DWARFDIE FormValueAsReferenceAtIndex(uint32_t i, DWARFUnit *main_unit) const;
+  DWARFDIE FormValueAsReference(dw_attr_t attr, DWARFUnit *main_unit) const;
   uint32_t FindAttributeIndex(dw_attr_t attr) const;
   void Clear() { m_infos.clear(); }
   size_t Size() const { return m_infos.size(); }
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp
@@ -47,17 +47,19 @@
 }
 
 DWARFDIE
-DWARFAttributes::FormValueAsReference(dw_attr_t attr) const {
+DWARFAttributes::FormValueAsReference(dw_attr_t attr,
+                                      DWARFUnit *main_unit) const {
   const uint32_t attr_idx = FindAttributeIndex(attr);
   if (attr_idx != UINT32_MAX)
-    return FormValueAsReferenceAtIndex(attr_idx);
+    return FormValueAsReferenceAtIndex(attr_idx, main_unit);
   return {};
 }
 
 DWARFDIE
-DWARFAttributes::FormValueAsReferenceAtIndex(uint32_t i) const {
+DWARFAttributes::FormValueAsReferenceAtIndex(uint32_t i,
+                                             DWARFUnit *main_unit) const {
   DWARFFormValue form_value;
   if (ExtractFormValueAtIndex(i, form_value))
-    return form_value.Reference();
+    return form_value.Reference(main_unit);
   return {};
 }
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -9,6 +9,7 @@
 #include <cstdlib>
 
 #include "DWARFASTParserClang.h"
+#include "DWARFCompileUnit.h"
 #include "DWARFDebugInfo.h"
 #include "DWARFDeclContext.h"
 #include "DWARFDefines.h"
@@ -134,7 +135,7 @@
     if (clang_module_die) {
       const char *module_name = clang_module_die.GetName();
       if (module_name)
-        return die.GetDWARF()->GetExternalModule(
+        return die.GetMainDWARF()->GetExternalModule(
             lldb_private::ConstString(module_name));
     }
   }
@@ -157,7 +158,7 @@
 
   // The type in the Clang module must have the same language as the current CU.
   LanguageSet languages;
-  languages.Insert(SymbolFileDWARF::GetLanguageFamily(*die.GetCU()));
+  languages.Insert(SymbolFileDWARF::GetLanguageFamily(*die.GetMainCU()));
   llvm::DenseSet<SymbolFile *> searched_symbol_files;
   clang_module_sp->GetSymbolFile()->FindTypes(decl_context, languages,
                                               searched_symbol_files, pcm_types);
@@ -166,7 +167,7 @@
     // by this symbol file, search all of them. Instead of calling
     // sym_file->FindTypes(), which would return this again, go straight
     // to the imported modules.
-    auto &sym_file = die.GetCU()->GetSymbolFileDWARF();
+    auto &sym_file = die.GetMainCU()->GetSymbolFileDWARF();
 
     // Well-formed clang modules never form cycles; guard against corrupted
     // ones by inserting the current file.
@@ -208,7 +209,7 @@
   if (pcm_type.IsDefined())
     GetClangASTImporter().RequireCompleteType(ClangUtil::GetQualType(type));
 
-  SymbolFileDWARF *dwarf = die.GetDWARF();
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
   TypeSP type_sp(new Type(die.GetID(), dwarf, pcm_type_sp->GetName(),
                           pcm_type_sp->GetByteSize(nullptr), nullptr,
                           LLDB_INVALID_UID, Type::eEncodingInvalid,
@@ -288,7 +289,7 @@
     auto qual_type = ClangUtil::GetQualType(type);
     if (ast_importer.RequireCompleteType(qual_type))
       return;
-    die.GetDWARF()->GetObjectFile()->GetModule()->ReportError(
+    die.GetMainDWARF()->GetObjectFile()->GetModule()->ReportError(
         "Unable to complete the Decl context for DIE '%s' at offset "
         "0x%8.8x.\nPlease file a bug report.",
         type_name_cstr ? type_name_cstr : "", die.GetOffset());
@@ -387,7 +388,7 @@
       break;
 
     case DW_AT_object_pointer:
-      object_pointer = form_value.Reference();
+      object_pointer = form_value.Reference(die.GetMainCU());
       break;
 
     case DW_AT_signature:
@@ -429,7 +430,7 @@
 }
 
 static std::string GetUnitName(const DWARFDIE &die) {
-  if (DWARFUnit *unit = die.GetCU())
+  if (DWARFUnit *unit = die.GetCU().GetCU())
     return unit->GetAbsolutePath().GetPath();
   return "<missing DWARF unit path>";
 }
@@ -446,7 +447,7 @@
   Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
                                         DWARF_LOG_LOOKUPS));
 
-  SymbolFileDWARF *dwarf = die.GetDWARF();
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
   if (log) {
     DWARFDIE context_die;
     clang::DeclContext *context =
@@ -471,7 +472,7 @@
 
   ParsedDWARFTypeAttributes attrs(die);
 
-  if (DWARFDIE signature_die = attrs.signature.Reference()) {
+  if (DWARFDIE signature_die = attrs.signature.Reference(die.GetMainCU())) {
     if (TypeSP type_sp =
             ParseTypeFromDWARF(sc, signature_die, type_is_new_ptr)) {
       dwarf->GetDIERefToType()[dieref] = type_sp.get();
@@ -551,9 +552,9 @@
                                        ParsedDWARFTypeAttributes &attrs) {
   Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
                                         DWARF_LOG_LOOKUPS));
-  SymbolFileDWARF *dwarf = die.GetDWARF();
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
   const dw_tag_t tag = die.Tag();
-  LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());
+  LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetMainCU());
   Type::ResolveState resolve_state = Type::ResolveState::Unresolved;
   Type::EncodingDataType encoding_data_type = Type::eEncodingIsUID;
   TypeSP type_sp;
@@ -591,7 +592,7 @@
       // unnammed structure type in the module debug info, so we make
       // sure we don't get into this situation by always resolving
       // typedefs from the module.
-      const DWARFDIE encoding_die = attrs.type.Reference();
+      const DWARFDIE encoding_die = attrs.type.Reference(die.GetMainCU());
 
       // First make sure that the die that this is typedef'ed to _is_
       // just a declaration (DW_AT_declaration == 1), not a full
@@ -609,7 +610,7 @@
 
   DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\") type => 0x%8.8lx\n", die.GetID(),
                DW_TAG_value_to_name(tag), type_name_cstr,
-               encoding_uid.Reference());
+               encoding_uid.Reference(die.GetMainCU()));
 
   switch (tag) {
   default:
@@ -738,7 +739,7 @@
         // Clang sometimes erroneously emits id as objc_object*.  In that
         // case we fix up the type to "id".
 
-        const DWARFDIE encoding_die = attrs.type.Reference();
+        const DWARFDIE encoding_die = attrs.type.Reference(die.GetMainCU());
 
         if (encoding_die && encoding_die.Tag() == DW_TAG_structure_type) {
           llvm::StringRef struct_name = encoding_die.GetName();
@@ -762,8 +763,9 @@
 
   type_sp = std::make_shared<Type>(
       die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
-      dwarf->GetUID(attrs.type.Reference()), encoding_data_type, &attrs.decl,
-      clang_type, resolve_state, TypePayloadClang(GetOwningClangModule(die)));
+      dwarf->GetUID(attrs.type.Reference(die.GetMainCU())), encoding_data_type,
+      &attrs.decl, clang_type, resolve_state,
+      TypePayloadClang(GetOwningClangModule(die)));
 
   dwarf->GetDIERefToType()[*die.GetDIERef()] = type_sp.get();
   return type_sp;
@@ -774,7 +776,7 @@
                                       ParsedDWARFTypeAttributes &attrs) {
   Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
                                         DWARF_LOG_LOOKUPS));
-  SymbolFileDWARF *dwarf = die.GetDWARF();
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
   const dw_tag_t tag = die.Tag();
   TypeSP type_sp;
 
@@ -830,7 +832,7 @@
   if (!clang_type) {
     if (attrs.type.IsValid()) {
       Type *enumerator_type =
-          dwarf->ResolveTypeUID(attrs.type.Reference(), true);
+          dwarf->ResolveTypeUID(attrs.type.Reference(die.GetMainCU()), true);
       if (enumerator_type)
         enumerator_clang_type = enumerator_type->GetFullCompilerType();
     }
@@ -856,9 +858,9 @@
 
   type_sp = std::make_shared<Type>(
       die.GetID(), dwarf, attrs.name, attrs.byte_size, nullptr,
-      dwarf->GetUID(attrs.type.Reference()), Type::eEncodingIsUID, &attrs.decl,
-      clang_type, Type::ResolveState::Forward,
-      TypePayloadClang(GetOwningClangModule(die)));
+      dwarf->GetUID(attrs.type.Reference(die.GetMainCU())),
+      Type::eEncodingIsUID, &attrs.decl, clang_type,
+      Type::ResolveState::Forward, TypePayloadClang(GetOwningClangModule(die)));
 
   if (TypeSystemClang::StartTagDeclarationDefinition(clang_type)) {
     if (die.HasChildren()) {
@@ -883,7 +885,7 @@
   Log *log(LogChannelDWARF::GetLogIfAny(DWARF_LOG_TYPE_COMPLETION |
                                         DWARF_LOG_LOOKUPS));
 
-  SymbolFileDWARF *dwarf = die.GetDWARF();
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
   const dw_tag_t tag = die.Tag();
 
   bool is_variadic = false;
@@ -906,7 +908,8 @@
   Type *func_type = NULL;
 
   if (attrs.type.IsValid())
-    func_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true);
+    func_type =
+        dwarf->ResolveTypeUID(attrs.type.Reference(die.GetMainCU()), true);
 
   if (func_type)
     return_clang_type = func_type->GetForwardCompilerType();
@@ -1048,7 +1051,7 @@
             // If we have a specification, then the function type should
             // have been made with the specification and not with this
             // die.
-            DWARFDIE spec_die = attrs.specification.Reference();
+            DWARFDIE spec_die = attrs.specification.Reference(die.GetMainCU());
             clang::DeclContext *spec_clang_decl_ctx =
                 GetClangDeclContextForDIE(spec_die);
             if (spec_clang_decl_ctx) {
@@ -1067,7 +1070,7 @@
             // the abstract origin has a valid clang decl context.
             class_type->GetForwardCompilerType();
 
-            DWARFDIE abs_die = attrs.abstract_origin.Reference();
+            DWARFDIE abs_die = attrs.abstract_origin.Reference(die.GetMainCU());
             clang::DeclContext *abs_clang_decl_ctx =
                 GetClangDeclContextForDIE(abs_die);
             if (abs_clang_decl_ctx) {
@@ -1215,7 +1218,7 @@
       clang::FunctionDecl *template_function_decl = nullptr;
 
       if (attrs.abstract_origin.IsValid()) {
-        DWARFDIE abs_die = attrs.abstract_origin.Reference();
+        DWARFDIE abs_die = attrs.abstract_origin.Reference(die.GetMainCU());
 
         if (dwarf->ResolveType(abs_die)) {
           function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(
@@ -1301,12 +1304,12 @@
 
 TypeSP DWARFASTParserClang::ParseArrayType(const DWARFDIE &die,
                                            ParsedDWARFTypeAttributes &attrs) {
-  SymbolFileDWARF *dwarf = die.GetDWARF();
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
 
   DEBUG_PRINTF("0x%8.8" PRIx64 ": %s (\"%s\")\n", die.GetID(),
                DW_TAG_value_to_name(tag), type_name_cstr);
 
-  DWARFDIE type_die = attrs.type.Reference();
+  DWARFDIE type_die = attrs.type.Reference(die.GetMainCU());
   Type *element_type = dwarf->ResolveTypeUID(type_die, true);
 
   if (!element_type)
@@ -1354,10 +1357,11 @@
 
 TypeSP DWARFASTParserClang::ParsePointerToMemberType(
     const DWARFDIE &die, const ParsedDWARFTypeAttributes &attrs) {
-  SymbolFileDWARF *dwarf = die.GetDWARF();
-  Type *pointee_type = dwarf->ResolveTypeUID(attrs.type.Reference(), true);
-  Type *class_type =
-      dwarf->ResolveTypeUID(attrs.containing_type.Reference(), true);
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
+  Type *pointee_type =
+      dwarf->ResolveTypeUID(attrs.type.Reference(die.GetMainCU()), true);
+  Type *class_type = dwarf->ResolveTypeUID(
+      attrs.containing_type.Reference(die.GetMainCU()), true);
 
   CompilerType pointee_clang_type = pointee_type->GetForwardCompilerType();
   CompilerType class_clang_type = class_type->GetForwardCompilerType();
@@ -1380,7 +1384,7 @@
   if (!type_sp)
     return type_sp;
 
-  SymbolFileDWARF *dwarf = die.GetDWARF();
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
   TypeList &type_list = dwarf->GetTypeList();
   DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die);
   dw_tag_t sc_parent_tag = sc_parent_die.Tag();
@@ -1416,8 +1420,8 @@
   TypeSP type_sp;
   CompilerType clang_type;
   const dw_tag_t tag = die.Tag();
-  SymbolFileDWARF *dwarf = die.GetDWARF();
-  LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetCU());
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
+  LanguageType cu_language = SymbolFileDWARF::GetLanguage(*die.GetMainCU());
   Log *log = LogChannelDWARF::GetLogIfAll(DWARF_LOG_TYPE_COMPLETION |
                                           DWARF_LOG_LOOKUPS);
 
@@ -1870,7 +1874,8 @@
 
         case DW_AT_type:
           if (attributes.ExtractFormValueAtIndex(i, form_value)) {
-            Type *lldb_type = die.ResolveTypeUID(form_value.Reference());
+            Type *lldb_type =
+                die.ResolveTypeUID(form_value.Reference(die.GetMainCU()));
             if (lldb_type)
               clang_type = lldb_type->GetForwardCompilerType();
           }
@@ -1958,7 +1963,7 @@
                                              lldb_private::Type *type,
                                              CompilerType &clang_type) {
   const dw_tag_t tag = die.Tag();
-  SymbolFileDWARF *dwarf = die.GetDWARF();
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
 
   ClangASTImporter::LayoutInfo layout_info;
 
@@ -1996,7 +2001,7 @@
       ConstString class_name(clang_type.GetTypeName());
       if (class_name) {
         dwarf->GetObjCMethods(class_name, [&](DWARFDIE method_die) {
-          method_die.ResolveType();
+          method_die.ResolveType(*dwarf);
           return true;
         });
 
@@ -2062,7 +2067,7 @@
 bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
                                                 lldb_private::Type *type,
                                                 CompilerType &clang_type) {
-  SymbolFileDWARF *dwarf = die.GetDWARF();
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
 
   std::lock_guard<std::recursive_mutex> guard(
       dwarf->GetObjectFile()->GetModule()->GetMutex());
@@ -2249,9 +2254,9 @@
       else if ((die.GetParent().Tag() == DW_TAG_compile_unit ||
                 die.GetParent().Tag() == DW_TAG_partial_unit) &&
                Language::LanguageIsCPlusPlus(
-                   SymbolFileDWARF::GetLanguage(*die.GetCU())) &&
+                   SymbolFileDWARF::GetLanguage(*die.GetMainCU())) &&
                !Language::LanguageIsObjC(
-                   SymbolFileDWARF::GetLanguage(*die.GetCU())) &&
+                   SymbolFileDWARF::GetLanguage(*die.GetMainCU())) &&
                name && strcmp(name, "main") != 0) {
         // If the mangled name is not present in the DWARF, generate the
         // demangled name using the decl context. We skip if the function is
@@ -2294,7 +2299,7 @@
         decl_up = std::make_unique<Declaration>(die.GetCU()->GetFile(decl_file),
                                                 decl_line, decl_column);
 
-      SymbolFileDWARF *dwarf = die.GetDWARF();
+      SymbolFileDWARF *dwarf = die.GetMainDWARF();
       // Supply the type _only_ if it has already been parsed
       Type *func_type = dwarf->GetDIERefToType().lookup(*die.GetDIERef());
 
@@ -2327,7 +2332,7 @@
     DelayedPropertyList &delayed_properties,
     lldb_private::ClangASTImporter::LayoutInfo &layout_info,
     FieldInfo &last_field_info) {
-  ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
+  ModuleSP module_sp = parent_die.GetMainDWARF()->GetObjectFile()->GetModule();
   const dw_tag_t tag = die.Tag();
   // Get the parent byte size so we can verify any members will fit
   const uint64_t parent_byte_size =
@@ -2506,7 +2511,8 @@
 
   // Handle static members
   if (is_external && member_byte_offset == UINT32_MAX) {
-    Type *var_type = die.ResolveTypeUID(encoding_form.Reference());
+    Type *var_type =
+        die.ResolveTypeUID(encoding_form.Reference(die.GetMainCU()));
 
     if (var_type) {
       if (accessibility == eAccessNone)
@@ -2519,7 +2525,8 @@
   }
 
   if (!is_artificial) {
-    Type *member_type = die.ResolveTypeUID(encoding_form.Reference());
+    Type *member_type =
+        die.ResolveTypeUID(encoding_form.Reference(die.GetMainCU()));
 
     clang::FieldDecl *field_decl = nullptr;
     const uint64_t character_width = 8;
@@ -2545,7 +2552,7 @@
             if (!byte_size)
               byte_size = member_type->GetByteSize(nullptr);
 
-            ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+            ObjectFile *objfile = die.GetMainDWARF()->GetObjectFile();
             if (objfile->GetByteOrder() == eByteOrderLittle) {
               this_field_info.bit_offset += byte_size.getValueOr(0) * 8;
               this_field_info.bit_offset -= (bit_offset + bit_size);
@@ -2566,7 +2573,7 @@
                (last_field_info.IsBitfield() &&
                 !last_field_info.NextBitfieldOffsetIsValid(
                     this_field_info.bit_offset)))) {
-            ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
+            ObjectFile *objfile = die.GetMainDWARF()->GetObjectFile();
             objfile->GetModule()->ReportWarning(
                 "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid "
                 "bit offset (0x%8.8" PRIx64
@@ -2681,7 +2688,8 @@
                     "0x%8.8" PRIx64
                     ": DW_TAG_member '%s' refers to type 0x%8.8x"
                     " which extends beyond the bounds of 0x%8.8" PRIx64,
-                    die.GetID(), name, encoding_form.Reference().GetOffset(),
+                    die.GetID(), name,
+                    encoding_form.Reference(die.GetMainCU()).GetOffset(),
                     parent_die.GetID());
               }
 
@@ -2706,12 +2714,14 @@
           module_sp->ReportError(
               "0x%8.8" PRIx64 ": DW_TAG_member '%s' refers to type 0x%8.8x"
               " which was unable to be parsed",
-              die.GetID(), name, encoding_form.Reference().GetOffset());
+              die.GetID(), name,
+              encoding_form.Reference(die.GetMainCU()).GetOffset());
         else
           module_sp->ReportError(
               "0x%8.8" PRIx64 ": DW_TAG_member refers to type 0x%8.8x"
               " which was unable to be parsed",
-              die.GetID(), encoding_form.Reference().GetOffset());
+              die.GetID(),
+              encoding_form.Reference(die.GetMainCU()).GetOffset());
       }
     }
 
@@ -2747,7 +2757,7 @@
 
   FieldInfo last_field_info;
 
-  ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
+  ModuleSP module_sp = parent_die.GetMainDWARF()->GetObjectFile()->GetModule();
   TypeSystemClang *ast =
       llvm::dyn_cast_or_null<TypeSystemClang>(class_clang_type.GetTypeSystem());
   if (ast == nullptr)
@@ -2830,16 +2840,18 @@
           }
         }
 
-        Type *base_class_type = die.ResolveTypeUID(encoding_form.Reference());
+        Type *base_class_type =
+            die.ResolveTypeUID(encoding_form.Reference(die.GetMainCU()));
         if (base_class_type == nullptr) {
-          module_sp->ReportError("0x%8.8x: DW_TAG_inheritance failed to "
-                                 "resolve the base class at 0x%8.8x"
-                                 " from enclosing type 0x%8.8x. \nPlease file "
-                                 "a bug and attach the file at the start of "
-                                 "this error message",
-                                 die.GetOffset(),
-                                 encoding_form.Reference().GetOffset(),
-                                 parent_die.GetOffset());
+          module_sp->ReportError(
+              "0x%8.8x: DW_TAG_inheritance failed to "
+              "resolve the base class at 0x%8.8x"
+              " from enclosing type 0x%8.8x. \nPlease file "
+              "a bug and attach the file at the start of "
+              "this error message",
+              die.GetOffset(),
+              encoding_form.Reference(die.GetMainCU()).GetOffset(),
+              parent_die.GetOffset());
           break;
         }
 
@@ -2953,8 +2965,8 @@
               // specification DIEs, so we can't rely upon the name being in
               // the formal parameter DIE...
               (name == nullptr || ::strcmp(name, "this") == 0)) {
-            Type *this_type =
-                die.ResolveTypeUID(param_type_die_form.Reference());
+            Type *this_type = die.ResolveTypeUID(
+                param_type_die_form.Reference(die.GetMainCU()));
             if (this_type) {
               uint32_t encoding_mask = this_type->GetEncodingMask();
               if (encoding_mask & Type::eEncodingIsPointerUID) {
@@ -2971,7 +2983,8 @@
         }
 
         if (!skip) {
-          Type *type = die.ResolveTypeUID(param_type_die_form.Reference());
+          Type *type = die.ResolveTypeUID(
+              param_type_die_form.Reference(die.GetMainCU()));
           if (type) {
             function_param_types.push_back(type->GetForwardCompilerType());
 
@@ -3106,7 +3119,7 @@
 
 Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) {
   if (die) {
-    SymbolFileDWARF *dwarf = die.GetDWARF();
+    SymbolFileDWARF *dwarf = die.GetMainDWARF();
     DWARFAttributes attributes;
     const size_t num_attributes = die.GetAttributes(attributes);
     if (num_attributes > 0) {
@@ -3117,7 +3130,8 @@
 
         if (attr == DW_AT_type &&
             attributes.ExtractFormValueAtIndex(i, form_value))
-          return dwarf->ResolveTypeUID(form_value.Reference(), true);
+          return dwarf->ResolveTypeUID(form_value.Reference(die.GetMainCU()),
+                                       true);
       }
     }
   }
@@ -3163,7 +3177,7 @@
   case DW_TAG_variable:
   case DW_TAG_constant:
   case DW_TAG_formal_parameter: {
-    SymbolFileDWARF *dwarf = die.GetDWARF();
+    SymbolFileDWARF *dwarf = die.GetMainDWARF();
     Type *type = GetTypeForDIE(die);
     if (dwarf && type) {
       const char *name = die.GetName();
@@ -3177,7 +3191,7 @@
     break;
   }
   case DW_TAG_imported_declaration: {
-    SymbolFileDWARF *dwarf = die.GetDWARF();
+    SymbolFileDWARF *dwarf = die.GetMainDWARF();
     DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
     if (imported_uid) {
       CompilerDecl imported_decl = SymbolFileDWARF::GetDecl(imported_uid);
@@ -3195,7 +3209,7 @@
     break;
   }
   case DW_TAG_imported_module: {
-    SymbolFileDWARF *dwarf = die.GetDWARF();
+    SymbolFileDWARF *dwarf = die.GetMainDWARF();
     DWARFDIE imported_uid = die.GetAttributeValueAsReferenceDIE(DW_AT_import);
 
     if (imported_uid) {
@@ -3253,7 +3267,7 @@
     }
 
     if (decl_ctx == nullptr && try_parsing_type) {
-      Type *type = die.GetDWARF()->ResolveType(die);
+      Type *type = die.GetMainDWARF()->ResolveType(die);
       if (type)
         decl_ctx = GetCachedClangDeclContextForDIE(die);
     }
@@ -3398,7 +3412,7 @@
       Log *log =
           nullptr; // (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO));
       if (log) {
-        SymbolFileDWARF *dwarf = die.GetDWARF();
+        SymbolFileDWARF *dwarf = die.GetMainDWARF();
         if (namespace_name) {
           dwarf->GetObjectFile()->GetModule()->LogMessage(
               log,
@@ -3430,7 +3444,7 @@
 
 clang::DeclContext *DWARFASTParserClang::GetClangDeclContextContainingDIE(
     const DWARFDIE &die, DWARFDIE *decl_ctx_die_copy) {
-  SymbolFileDWARF *dwarf = die.GetDWARF();
+  SymbolFileDWARF *dwarf = die.GetMainDWARF();
 
   DWARFDIE decl_ctx_die = dwarf->GetDeclContextDIEContainingDIE(die);
 
@@ -3461,7 +3475,7 @@
                                                const DWARFDIE &die) {
   DIERef ref = *die.GetDIERef();
   m_dieref_to_decl_ctx[ref] = decl_ctx;
-  SymbolFileDWARF *sym_file = &die.GetCU()->GetSymbolFileDWARF();
+  SymbolFileDWARF *sym_file = &die.GetMainCU()->GetSymbolFileDWARF();
   // There can be many DIEs for a single decl context
   // m_decl_ctx_to_filedieref[decl_ctx].insert(...);
   m_decl_ctx_to_filedieref.insert(
@@ -3581,10 +3595,10 @@
 
   DWARFASTParserClang *src_dwarf_ast_parser =
       static_cast<DWARFASTParserClang *>(
-          SymbolFileDWARF::GetDWARFParser(*src_die.GetCU()));
+          SymbolFileDWARF::GetDWARFParser(*src_die.GetMainCU()));
   DWARFASTParserClang *dst_dwarf_ast_parser =
       static_cast<DWARFASTParserClang *>(
-          SymbolFileDWARF::GetDWARFParser(*dst_die.GetCU()));
+          SymbolFileDWARF::GetDWARFParser(*dst_die.GetMainCU()));
 
   // Now do the work of linking the DeclContexts and Types.
   if (fast_path) {
@@ -3609,14 +3623,14 @@
       }
 
       Type *src_child_type =
-          dst_die.GetDWARF()->GetDIERefToType()[*src_die.GetDIERef()];
+          dst_die.GetMainDWARF()->GetDIERefToType()[*src_die.GetDIERef()];
       if (src_child_type) {
         LLDB_LOGF(log,
                   "uniquing type %p (uid=0x%" PRIx64
                   ") from 0x%8.8x for 0x%8.8x",
                   static_cast<void *>(src_child_type), src_child_type->GetID(),
                   src_die.GetOffset(), dst_die.GetOffset());
-        dst_die.GetDWARF()->GetDIERefToType()[*dst_die.GetDIERef()] =
+        dst_die.GetMainDWARF()->GetDIERefToType()[*dst_die.GetDIERef()] =
             src_child_type;
       } else {
         LLDB_LOGF(log,
@@ -3654,14 +3668,14 @@
           }
 
           Type *src_child_type =
-              dst_die.GetDWARF()->GetDIERefToType()[*src_die.GetDIERef()];
+              dst_die.GetMainDWARF()->GetDIERefToType()[*src_die.GetDIERef()];
           if (src_child_type) {
             LLDB_LOGF(
                 log,
                 "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
                 static_cast<void *>(src_child_type), src_child_type->GetID(),
                 src_die.GetOffset(), dst_die.GetOffset());
-            dst_die.GetDWARF()->GetDIERefToType()[*dst_die.GetDIERef()] =
+            dst_die.GetMainDWARF()->GetDIERefToType()[*dst_die.GetDIERef()] =
                 src_child_type;
           } else {
             LLDB_LOGF(log,
@@ -3709,14 +3723,14 @@
         }
 
         Type *src_child_type =
-            dst_die.GetDWARF()->GetDIERefToType()[*src_die.GetDIERef()];
+            dst_die.GetMainDWARF()->GetDIERefToType()[*src_die.GetDIERef()];
         if (src_child_type) {
           LLDB_LOGF(
               log,
               "uniquing type %p (uid=0x%" PRIx64 ") from 0x%8.8x for 0x%8.8x",
               static_cast<void *>(src_child_type), src_child_type->GetID(),
               src_die.GetOffset(), dst_die.GetOffset());
-          dst_die.GetDWARF()->GetDIERefToType()[*dst_die.GetDIERef()] =
+          dst_die.GetMainDWARF()->GetDIERefToType()[*dst_die.GetDIERef()] =
               src_child_type;
         } else {
           LLDB_LOGF(log,
Index: lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
+++ lldb/source/Plugins/SymbolFile/DWARF/CMakeLists.txt
@@ -29,8 +29,10 @@
   DWARFDIE.cpp
   DWARFFormValue.cpp
   DWARFIndex.cpp
+  DWARFSimpleDIE.cpp
   DWARFTypeUnit.cpp
   DWARFUnit.cpp
+  DWARFUnitPair.cpp
   HashedNameToDIE.cpp
   LogChannelDWARF.cpp
   ManualDWARFIndex.cpp
Index: lldb/source/Expression/DWARFExpression.cpp
===================================================================
--- lldb/source/Expression/DWARFExpression.cpp
+++ lldb/source/Expression/DWARFExpression.cpp
@@ -59,7 +59,7 @@
 
 DWARFExpression::DWARFExpression(lldb::ModuleSP module_sp,
                                  const DataExtractor &data,
-                                 const DWARFUnit *dwarf_cu)
+                                 DWARFUnitPair dwarf_cu)
     : m_module_wp(), m_data(data), m_dwarf_cu(dwarf_cu),
       m_reg_kind(eRegisterKindDWARF) {
   if (module_sp)
@@ -951,7 +951,7 @@
 bool DWARFExpression::Evaluate(
     ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
     lldb::ModuleSP module_sp, const DataExtractor &opcodes,
-    const DWARFUnit *dwarf_cu, const lldb::RegisterKind reg_kind,
+    DWARFUnitPair dwarf_cu, const lldb::RegisterKind reg_kind,
     const Value *initial_value_ptr, const Value *object_address_ptr,
     Value &result, Status *error_ptr) {
 
@@ -2469,8 +2469,8 @@
         }
       } else {
         // Retrieve the type DIE that the value is being converted to.
-        // FIXME: the constness has annoying ripple effects.
-        DWARFDIE die = const_cast<DWARFUnit *>(dwarf_cu)->GetDIE(die_offset);
+        DWARFDIE die =
+            dwarf_cu.GetCU()->GetDIE(dwarf_cu.GetMainCU(), die_offset);
         if (!die) {
           if (error_ptr)
             error_ptr->SetErrorString("Cannot resolve DW_OP_convert type DIE");
Index: lldb/include/lldb/Expression/DWARFExpression.h
===================================================================
--- lldb/include/lldb/Expression/DWARFExpression.h
+++ lldb/include/lldb/Expression/DWARFExpression.h
@@ -9,6 +9,7 @@
 #ifndef LLDB_EXPRESSION_DWARFEXPRESSION_H
 #define LLDB_EXPRESSION_DWARFEXPRESSION_H
 
+#include "Plugins/SymbolFile/DWARF/DWARFUnitPair.h"
 #include "lldb/Core/Address.h"
 #include "lldb/Core/Disassembler.h"
 #include "lldb/Utility/DataExtractor.h"
@@ -42,7 +43,7 @@
   ///     A data extractor configured to read the DWARF location expression's
   ///     bytecode.
   DWARFExpression(lldb::ModuleSP module, const DataExtractor &data,
-                  const DWARFUnit *dwarf_cu);
+                  DWARFUnitPair dwarf_cu);
 
   /// Destructor
   virtual ~DWARFExpression();
@@ -202,8 +203,7 @@
   ///     details of the failure are provided through it.
   static bool Evaluate(ExecutionContext *exe_ctx, RegisterContext *reg_ctx,
                        lldb::ModuleSP opcode_ctx, const DataExtractor &opcodes,
-                       const DWARFUnit *dwarf_cu,
-                       const lldb::RegisterKind reg_set,
+                       DWARFUnitPair dwarf_cu, const lldb::RegisterKind reg_set,
                        const Value *initial_value_ptr,
                        const Value *object_address_ptr, Value &result,
                        Status *error_ptr);
@@ -250,7 +250,7 @@
   /// The DWARF compile unit this expression belongs to. It is used to evaluate
   /// values indexing into the .debug_addr section (e.g. DW_OP_GNU_addr_index,
   /// DW_OP_GNU_const_index)
-  const DWARFUnit *m_dwarf_cu = nullptr;
+  DWARFUnitPair m_dwarf_cu;
 
   /// One of the defines that starts with LLDB_REGKIND_
   lldb::RegisterKind m_reg_kind = lldb::eRegisterKindDWARF;
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to