This revision was automatically updated to reflect the committed changes.
Closed by commit rL363250: DWARF: Don't create lldb CompileUnits for DWARF 
type units (authored by labath, committed by ).
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.

Changed prior to commit:
  https://reviews.llvm.org/D63005?vs=203820&id=204483#toc

Repository:
  rL LLVM

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

https://reviews.llvm.org/D63005

Files:
  lldb/trunk/lit/SymbolFile/DWARF/debug-types-dwarf5.s
  lldb/trunk/lit/SymbolFile/DWARF/debug-types-line-tables.s
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
  lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
  lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
  lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
  lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h

Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -13,11 +13,11 @@
 
 class SymbolFileDWARFDwo : public SymbolFileDWARF {
 public:
-  SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFUnit *dwarf_cu);
+  SymbolFileDWARFDwo(lldb::ObjectFileSP objfile, DWARFCompileUnit &dwarf_cu);
 
   ~SymbolFileDWARFDwo() override = default;
 
-  lldb::CompUnitSP ParseCompileUnit(DWARFUnit *dwarf_cu) override;
+  lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu) override;
 
   DWARFUnit *GetCompileUnit();
 
@@ -42,7 +42,7 @@
     return nullptr;
   }
 
-  DWARFUnit *GetBaseCompileUnit() override;
+  DWARFCompileUnit *GetBaseCompileUnit() override { return &m_base_dwarf_cu; }
 
 protected:
   void LoadSectionData(lldb::SectionType sect_type,
@@ -68,7 +68,7 @@
   SymbolFileDWARF *GetBaseSymbolFile();
 
   lldb::ObjectFileSP m_obj_file_sp;
-  DWARFUnit *m_base_dwarf_cu;
+  DWARFCompileUnit &m_base_dwarf_cu;
 };
 
 #endif // SymbolFileDWARFDwo_SymbolFileDWARFDwo_h_
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.cpp
@@ -81,7 +81,7 @@
 {}
 
 std::unique_ptr<SymbolFileDWARFDwo>
-SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFUnit *dwarf_cu,
+SymbolFileDWARFDwp::GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu,
                                           uint64_t dwo_id) {
   return std::unique_ptr<SymbolFileDWARFDwo>(
       new SymbolFileDWARFDwoDwp(this, m_obj_file, dwarf_cu, dwo_id));
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -13,18 +13,19 @@
 #include "lldb/Symbol/ObjectFile.h"
 #include "lldb/Utility/LLDBAssert.h"
 
-#include "DWARFUnit.h"
+#include "DWARFCompileUnit.h"
 #include "DWARFDebugInfo.h"
+#include "DWARFUnit.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
 SymbolFileDWARFDwo::SymbolFileDWARFDwo(ObjectFileSP objfile,
-                                       DWARFUnit *dwarf_cu)
+                                       DWARFCompileUnit &dwarf_cu)
     : SymbolFileDWARF(objfile.get(), objfile->GetSectionList(
                                          /*update_module_section_list*/ false)),
       m_obj_file_sp(objfile), m_base_dwarf_cu(dwarf_cu) {
-  SetID(((lldb::user_id_t)dwarf_cu->GetID()) << 32);
+  SetID(((lldb::user_id_t)dwarf_cu.GetID()) << 32);
 }
 
 void SymbolFileDWARFDwo::LoadSectionData(lldb::SectionType sect_type,
@@ -45,10 +46,11 @@
   SymbolFileDWARF::LoadSectionData(sect_type, data);
 }
 
-lldb::CompUnitSP SymbolFileDWARFDwo::ParseCompileUnit(DWARFUnit *dwarf_cu) {
-  assert(GetCompileUnit() == dwarf_cu && "SymbolFileDWARFDwo::ParseCompileUnit "
-                                         "called with incompatible compile "
-                                         "unit");
+lldb::CompUnitSP
+SymbolFileDWARFDwo::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
+  assert(GetCompileUnit() == &dwarf_cu &&
+         "SymbolFileDWARFDwo::ParseCompileUnit called with incompatible "
+         "compile unit");
   return GetBaseSymbolFile()->ParseCompileUnit(m_base_dwarf_cu);
 }
 
@@ -106,12 +108,8 @@
       die, type_name, must_be_implementation);
 }
 
-DWARFUnit *SymbolFileDWARFDwo::GetBaseCompileUnit() {
-  return m_base_dwarf_cu;
-}
-
 SymbolFileDWARF *SymbolFileDWARFDwo::GetBaseSymbolFile() {
-  return m_base_dwarf_cu->GetSymbolFileDWARF();
+  return m_base_dwarf_cu.GetSymbolFileDWARF();
 }
 
 DWARFExpression::LocationListFormat
@@ -126,7 +124,7 @@
 
 DWARFDIE
 SymbolFileDWARFDwo::GetDIE(const DIERef &die_ref) {
-  lldbassert(die_ref.cu_offset == m_base_dwarf_cu->GetOffset() ||
+  lldbassert(die_ref.cu_offset == m_base_dwarf_cu.GetOffset() ||
              die_ref.cu_offset == DW_INVALID_OFFSET);
   return DebugInfo()->GetDIEForDIEOffset(die_ref.section, die_ref.die_offset);
 }
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -40,7 +40,7 @@
 class DebugMapModule;
 class DWARFAbbreviationDeclaration;
 class DWARFAbbreviationDeclarationSet;
-class DWARFileUnit;
+class DWARFCompileUnit;
 class DWARFDebugAbbrev;
 class DWARFDebugAranges;
 class DWARFDebugInfo;
@@ -239,7 +239,8 @@
   bool
   HasForwardDeclForClangType(const lldb_private::CompilerType &compiler_type);
 
-  lldb_private::CompileUnit *GetCompUnitForDWARFCompUnit(DWARFUnit *dwarf_cu);
+  lldb_private::CompileUnit *
+  GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu);
 
   virtual size_t GetObjCMethodDIEOffsets(lldb_private::ConstString class_name,
                                          DIEArray &method_die_offsets);
@@ -250,7 +251,7 @@
 
   static DWARFDIE GetParentSymbolContextDIE(const DWARFDIE &die);
 
-  virtual lldb::CompUnitSP ParseCompileUnit(DWARFUnit *dwarf_cu);
+  virtual lldb::CompUnitSP ParseCompileUnit(DWARFCompileUnit &dwarf_cu);
 
   virtual lldb_private::DWARFExpression::LocationListFormat
   GetLocationListFormat() const;
@@ -285,7 +286,7 @@
   // For regular SymbolFileDWARF instances the method returns nullptr,
   // for the instances of the subclass SymbolFileDWARFDwo
   // the method returns a pointer to the base compile unit.
-  virtual DWARFUnit *GetBaseCompileUnit();
+  virtual DWARFCompileUnit *GetBaseCompileUnit() { return nullptr; }
 
   static bool
   DIEInDeclContext(const lldb_private::CompilerDeclContext *parent_decl_ctx,
@@ -433,6 +434,9 @@
     return m_forward_decl_clang_type_to_die;
   }
 
+  void BuildCuTranslationTable();
+  llvm::Optional<uint32_t> GetDWARFUnitIndex(uint32_t cu_idx);
+
   struct DecodedUID {
     SymbolFileDWARF *dwarf;
     DIERef ref;
@@ -483,6 +487,7 @@
   ClangTypeToDIE m_forward_decl_clang_type_to_die;
   llvm::DenseMap<dw_offset_t, lldb_private::FileSpecList>
       m_type_unit_support_files;
+  std::vector<uint32_t> m_lldb_cu_to_dwarf_unit;
 };
 
 #endif // SymbolFileDWARF_SymbolFileDWARF_h_
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp
@@ -182,6 +182,11 @@
   return llvm::cast<DWARFTypeUnit>(GetUnitAtIndex(pos->second));
 }
 
+bool DWARFDebugInfo::ContainsTypeUnits() {
+  ParseUnitHeadersIfNeeded();
+  return !m_type_hash_to_unit_index.empty();
+}
+
 DWARFDIE
 DWARFDebugInfo::GetDIEForDIEOffset(DIERef::Section section,
                                    dw_offset_t die_offset) {
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.cpp
@@ -21,7 +21,7 @@
 
 SymbolFileDWARFDwoDwp::SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
                                              ObjectFileSP objfile,
-                                             DWARFUnit *dwarf_cu,
+                                             DWARFCompileUnit &dwarf_cu,
                                              uint64_t dwo_id)
     : SymbolFileDWARFDwo(objfile, dwarf_cu), m_dwp_symfile(dwp_symfile),
       m_dwo_id(dwo_id) {}
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp
@@ -70,7 +70,7 @@
     // We got nothing from the functions, maybe we have a line tables only
     // situation. Check the line tables and build the arange table from this.
     SymbolContext sc;
-    sc.comp_unit = m_dwarf->GetCompUnitForDWARFCompUnit(this);
+    sc.comp_unit = m_dwarf->GetCompUnitForDWARFCompUnit(*this);
     if (sc.comp_unit) {
       SymbolFileDWARFDebugMap *debug_map_sym_file =
           m_dwarf->GetDebugMapSymfile();
@@ -96,7 +96,7 @@
     // We got nothing from the functions, maybe we have a line tables only
     // situation. Check the line tables and build the arange table from this.
     SymbolContext sc;
-    sc.comp_unit = m_dwarf->GetCompUnitForDWARFCompUnit(this);
+    sc.comp_unit = m_dwarf->GetCompUnitForDWARFCompUnit(*this);
     if (sc.comp_unit) {
       if (LineTable *line_table = sc.comp_unit->GetLineTable()) {
         LineTable::FileAddressRanges file_ranges;
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwp.h
@@ -24,7 +24,7 @@
   Create(lldb::ModuleSP module_sp, const lldb_private::FileSpec &file_spec);
 
   std::unique_ptr<SymbolFileDWARFDwo>
-  GetSymbolFileForDwoId(DWARFUnit *dwarf_cu, uint64_t dwo_id);
+  GetSymbolFileForDwoId(DWARFCompileUnit &dwarf_cu, uint64_t dwo_id);
 
   bool LoadSectionData(uint64_t dwo_id, lldb::SectionType sect_type,
                        lldb_private::DWARFDataExtractor &data);
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.h
@@ -48,6 +48,7 @@
                                         dw_offset_t die_offset);
   DWARFUnit *GetUnit(const DIERef &die_ref);
   DWARFTypeUnit *GetTypeUnitForHash(uint64_t hash);
+  bool ContainsTypeUnits();
   DWARFDIE GetDIEForDIEOffset(DIERef::Section section,
                               dw_offset_t die_offset);
   DWARFDIE GetDIE(const DIERef &die_ref);
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -165,10 +165,6 @@
   return GetGlobalPluginProperties()->GetSymLinkPaths();
 }
 
-DWARFUnit *SymbolFileDWARF::GetBaseCompileUnit() {
-  return nullptr;
-}
-
 void SymbolFileDWARF::Initialize() {
   LogChannelDWARF::Initialize();
   PluginManager::RegisterPlugin(GetPluginNameStatic(),
@@ -651,51 +647,51 @@
   return m_rnglists.get();
 }
 
-lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFUnit *dwarf_cu) {
+lldb::CompUnitSP SymbolFileDWARF::ParseCompileUnit(DWARFCompileUnit &dwarf_cu) {
   CompUnitSP cu_sp;
-  if (dwarf_cu) {
-    CompileUnit *comp_unit = (CompileUnit *)dwarf_cu->GetUserData();
-    if (comp_unit) {
-      // We already parsed this compile unit, had out a shared pointer to it
-      cu_sp = comp_unit->shared_from_this();
+  CompileUnit *comp_unit = (CompileUnit *)dwarf_cu.GetUserData();
+  if (comp_unit) {
+    // We already parsed this compile unit, had out a shared pointer to it
+    cu_sp = comp_unit->shared_from_this();
+  } else {
+    if (dwarf_cu.GetSymbolFileDWARF() != this) {
+      return dwarf_cu.GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu);
+    } else if (dwarf_cu.GetOffset() == 0 && GetDebugMapSymfile()) {
+      // Let the debug map create the compile unit
+      cu_sp = m_debug_map_symfile->GetCompileUnit(this);
+      dwarf_cu.SetUserData(cu_sp.get());
     } else {
-      if (dwarf_cu->GetSymbolFileDWARF() != this) {
-        return dwarf_cu->GetSymbolFileDWARF()->ParseCompileUnit(dwarf_cu);
-      } else if (dwarf_cu->GetOffset() == 0 && GetDebugMapSymfile()) {
-        // Let the debug map create the compile unit
-        cu_sp = m_debug_map_symfile->GetCompileUnit(this);
-        dwarf_cu->SetUserData(cu_sp.get());
-      } else {
-        ModuleSP module_sp(m_obj_file->GetModule());
-        if (module_sp) {
-          const DWARFDIE cu_die = dwarf_cu->DIE();
-          if (cu_die) {
-            FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu->GetPathStyle());
-            if (cu_file_spec) {
-              // If we have a full path to the compile unit, we don't need to
-              // resolve the file.  This can be expensive e.g. when the source
-              // files are NFS mounted.
-              cu_file_spec.MakeAbsolute(dwarf_cu->GetCompilationDirectory());
-
-              std::string remapped_file;
-              if (module_sp->RemapSourceFile(cu_file_spec.GetPath(),
-                                             remapped_file))
-                cu_file_spec.SetFile(remapped_file, FileSpec::Style::native);
-            }
-
-            LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF(
-                cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
-
-            bool is_optimized = dwarf_cu->GetIsOptimized();
-            cu_sp = std::make_shared<CompileUnit>(
-                module_sp, dwarf_cu, cu_file_spec, dwarf_cu->GetID(),
-                cu_language, is_optimized ? eLazyBoolYes : eLazyBoolNo);
+      ModuleSP module_sp(m_obj_file->GetModule());
+      if (module_sp) {
+        const DWARFDIE cu_die = dwarf_cu.DIE();
+        if (cu_die) {
+          FileSpec cu_file_spec(cu_die.GetName(), dwarf_cu.GetPathStyle());
+          if (cu_file_spec) {
+            // If we have a full path to the compile unit, we don't need to
+            // resolve the file.  This can be expensive e.g. when the source
+            // files are NFS mounted.
+            cu_file_spec.MakeAbsolute(dwarf_cu.GetCompilationDirectory());
+
+            std::string remapped_file;
+            if (module_sp->RemapSourceFile(cu_file_spec.GetPath(),
+                                           remapped_file))
+              cu_file_spec.SetFile(remapped_file, FileSpec::Style::native);
+          }
+
+          LanguageType cu_language = DWARFUnit::LanguageTypeFromDWARF(
+              cu_die.GetAttributeValueAsUnsigned(DW_AT_language, 0));
+
+          bool is_optimized = dwarf_cu.GetIsOptimized();
+          BuildCuTranslationTable();
+          cu_sp = std::make_shared<CompileUnit>(
+              module_sp, &dwarf_cu, cu_file_spec,
+              *GetDWARFUnitIndex(dwarf_cu.GetID()), cu_language,
+              is_optimized ? eLazyBoolYes : eLazyBoolNo);
 
-            dwarf_cu->SetUserData(cu_sp.get());
+          dwarf_cu.SetUserData(cu_sp.get());
 
-            m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
-                dwarf_cu->GetID(), cu_sp);
-          }
+          m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex(
+              dwarf_cu.GetID(), cu_sp);
         }
       }
     }
@@ -703,23 +699,56 @@
   return cu_sp;
 }
 
+void SymbolFileDWARF::BuildCuTranslationTable() {
+  if (!m_lldb_cu_to_dwarf_unit.empty())
+    return;
+
+  DWARFDebugInfo *info = DebugInfo();
+  if (!info)
+    return;
+
+  if (!info->ContainsTypeUnits()) {
+    // We can use a 1-to-1 mapping. No need to build a translation table.
+    return;
+  }
+  for (uint32_t i = 0, num = info->GetNumUnits(); i < num; ++i) {
+    if (auto *cu = llvm::dyn_cast<DWARFCompileUnit>(info->GetUnitAtIndex(i))) {
+      cu->SetID(m_lldb_cu_to_dwarf_unit.size());
+      m_lldb_cu_to_dwarf_unit.push_back(i);
+    }
+  }
+}
+
+llvm::Optional<uint32_t> SymbolFileDWARF::GetDWARFUnitIndex(uint32_t cu_idx) {
+  BuildCuTranslationTable();
+  if (m_lldb_cu_to_dwarf_unit.empty())
+    return cu_idx;
+  if (cu_idx >= m_lldb_cu_to_dwarf_unit.size())
+    return llvm::None;
+  return m_lldb_cu_to_dwarf_unit[cu_idx];
+}
+
 uint32_t SymbolFileDWARF::GetNumCompileUnits() {
   DWARFDebugInfo *info = DebugInfo();
-  if (info)
-    return info->GetNumUnits();
-  return 0;
+  if (!info)
+    return 0;
+  BuildCuTranslationTable();
+  return m_lldb_cu_to_dwarf_unit.empty() ? info->GetNumUnits()
+                                         : m_lldb_cu_to_dwarf_unit.size();
 }
 
 CompUnitSP SymbolFileDWARF::ParseCompileUnitAtIndex(uint32_t cu_idx) {
   ASSERT_MODULE_LOCK(this);
-  CompUnitSP cu_sp;
   DWARFDebugInfo *info = DebugInfo();
-  if (info) {
-    DWARFUnit *dwarf_cu = info->GetUnitAtIndex(cu_idx);
-    if (dwarf_cu)
-      cu_sp = ParseCompileUnit(dwarf_cu);
+  if (!info)
+    return {};
+
+  if (llvm::Optional<uint32_t> dwarf_idx = GetDWARFUnitIndex(cu_idx)) {
+    if (auto *dwarf_cu = llvm::cast_or_null<DWARFCompileUnit>(
+            info->GetUnitAtIndex(*dwarf_idx)))
+      return ParseCompileUnit(*dwarf_cu);
   }
-  return cu_sp;
+  return {};
 }
 
 Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
@@ -777,13 +806,7 @@
 bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit,
                                         FileSpecList &support_files) {
   ASSERT_MODULE_LOCK(this);
-  DWARFUnit *unit = GetDWARFCompileUnit(&comp_unit);
-  if (auto *tu = llvm::dyn_cast_or_null<DWARFTypeUnit>(unit)) {
-    support_files = GetTypeUnitSupportFiles(*tu);
-    return true;
-  }
-
-  if (unit) {
+  if (DWARFUnit *unit = GetDWARFCompileUnit(&comp_unit)) {
     const dw_offset_t stmt_list = unit->GetLineTableOffset();
     if (stmt_list != DW_INVALID_OFFSET) {
       // All file indexes in DWARF are one based and a file of index zero is
@@ -798,9 +821,14 @@
 }
 
 FileSpec SymbolFileDWARF::GetFile(DWARFUnit &unit, size_t file_idx) {
-  if (CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(&unit))
-    return lldb_cu->GetSupportFiles().GetFileSpecAtIndex(file_idx);
-  return FileSpec();
+  if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit)) {
+    if (CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(*dwarf_cu))
+      return lldb_cu->GetSupportFiles().GetFileSpecAtIndex(file_idx);
+    return FileSpec();
+  }
+
+  auto &tu = llvm::cast<DWARFTypeUnit>(unit);
+  return GetTypeUnitSupportFiles(tu).GetFileSpecAtIndex(file_idx);
 }
 
 const FileSpecList &
@@ -1425,14 +1453,15 @@
   return nullptr;
 }
 
-CompileUnit *SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFUnit *dwarf_cu) {
+CompileUnit *
+SymbolFileDWARF::GetCompUnitForDWARFCompUnit(DWARFCompileUnit &dwarf_cu) {
   // Check if the symbol vendor already knows about this compile unit?
-  if (dwarf_cu->GetUserData() == nullptr) {
+  if (dwarf_cu.GetUserData() == nullptr) {
     // The symbol vendor doesn't know about this compile unit, we need to parse
     // and add it to the symbol vendor object.
     return ParseCompileUnit(dwarf_cu).get();
   }
-  return (CompileUnit *)dwarf_cu->GetUserData();
+  return (CompileUnit *)dwarf_cu.GetUserData();
 }
 
 size_t SymbolFileDWARF::GetObjCMethodDIEOffsets(ConstString class_name,
@@ -1445,9 +1474,10 @@
 bool SymbolFileDWARF::GetFunction(const DWARFDIE &die, SymbolContext &sc) {
   sc.Clear(false);
 
-  if (die) {
+  if (die && llvm::isa<DWARFCompileUnit>(die.GetCU())) {
     // Check if the symbol vendor already knows about this compile unit?
-    sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU());
+    sc.comp_unit =
+        GetCompUnitForDWARFCompUnit(llvm::cast<DWARFCompileUnit>(*die.GetCU()));
 
     sc.function = sc.comp_unit->FindFunctionByUID(die.GetID()).get();
     if (sc.function == nullptr)
@@ -1482,24 +1512,29 @@
 
 std::unique_ptr<SymbolFileDWARFDwo>
 SymbolFileDWARF::GetDwoSymbolFileForCompileUnit(
-    DWARFUnit &dwarf_cu, const DWARFDebugInfoEntry &cu_die) {
+    DWARFUnit &unit, const DWARFDebugInfoEntry &cu_die) {
   // If we are using a dSYM file, we never want the standard DWO files since
   // the -gmodules support uses the same DWO machanism to specify full debug
   // info files for modules.
   if (GetDebugMapSymfile())
     return nullptr;
 
+  DWARFCompileUnit *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(&unit);
+  // Only compile units can be split into two parts.
+  if (!dwarf_cu)
+    return nullptr;
+
   const char *dwo_name =
-      cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
+      cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_GNU_dwo_name, nullptr);
   if (!dwo_name)
     return nullptr;
 
   SymbolFileDWARFDwp *dwp_symfile = GetDwpSymbolFile();
   if (dwp_symfile) {
     uint64_t dwo_id =
-        cu_die.GetAttributeValueAsUnsigned(&dwarf_cu, DW_AT_GNU_dwo_id, 0);
+        cu_die.GetAttributeValueAsUnsigned(dwarf_cu, DW_AT_GNU_dwo_id, 0);
     std::unique_ptr<SymbolFileDWARFDwo> dwo_symfile =
-        dwp_symfile->GetSymbolFileForDwoId(&dwarf_cu, dwo_id);
+        dwp_symfile->GetSymbolFileForDwoId(*dwarf_cu, dwo_id);
     if (dwo_symfile)
       return dwo_symfile;
   }
@@ -1508,7 +1543,7 @@
   FileSystem::Instance().Resolve(dwo_file);
   if (dwo_file.IsRelative()) {
     const char *comp_dir =
-        cu_die.GetAttributeValueAsString(&dwarf_cu, DW_AT_comp_dir, nullptr);
+        cu_die.GetAttributeValueAsString(dwarf_cu, DW_AT_comp_dir, nullptr);
     if (!comp_dir)
       return nullptr;
 
@@ -1530,7 +1565,7 @@
   if (dwo_obj_file == nullptr)
     return nullptr;
 
-  return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, &dwarf_cu);
+  return llvm::make_unique<SymbolFileDWARFDwo>(dwo_obj_file, *dwarf_cu);
 }
 
 void SymbolFileDWARF::UpdateExternalModuleListIfNeeded() {
@@ -1706,10 +1741,10 @@
         }
       } else {
         uint32_t cu_idx = DW_INVALID_INDEX;
-        DWARFUnit *dwarf_cu = debug_info->GetUnitAtOffset(DIERef::Section::DebugInfo,
-                                                          cu_offset, &cu_idx);
-        if (dwarf_cu) {
-          sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu);
+        if (auto *dwarf_cu = llvm::dyn_cast_or_null<DWARFCompileUnit>(
+                debug_info->GetUnitAtOffset(DIERef::Section::DebugInfo,
+                                            cu_offset, &cu_idx))) {
+          sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
           if (sc.comp_unit) {
             resolved |= eSymbolContextCompUnit;
 
@@ -1802,110 +1837,100 @@
                                                SymbolContextList &sc_list) {
   const uint32_t prev_size = sc_list.GetSize();
   if (resolve_scope & eSymbolContextCompUnit) {
-    DWARFDebugInfo *debug_info = DebugInfo();
-    if (debug_info) {
-      uint32_t cu_idx;
-      DWARFUnit *dwarf_cu = nullptr;
-
-      for (cu_idx = 0;
-           (dwarf_cu = debug_info->GetUnitAtIndex(cu_idx)) != nullptr;
-           ++cu_idx) {
-        CompileUnit *dc_cu = GetCompUnitForDWARFCompUnit(dwarf_cu);
-        const bool full_match = (bool)file_spec.GetDirectory();
-        bool file_spec_matches_cu_file_spec =
-            dc_cu != nullptr && FileSpec::Equal(file_spec, *dc_cu, full_match);
-        if (check_inlines || file_spec_matches_cu_file_spec) {
-          SymbolContext sc(m_obj_file->GetModule());
-          sc.comp_unit = GetCompUnitForDWARFCompUnit(dwarf_cu);
-          if (sc.comp_unit) {
-            uint32_t file_idx = UINT32_MAX;
-
-            // If we are looking for inline functions only and we don't find it
-            // in the support files, we are done.
-            if (check_inlines) {
+    for (uint32_t cu_idx = 0, num_cus = GetNumCompileUnits(); cu_idx < num_cus;
+         ++cu_idx) {
+      CompileUnit *dc_cu = ParseCompileUnitAtIndex(cu_idx).get();
+      if (!dc_cu)
+        continue;
+
+      const bool full_match = (bool)file_spec.GetDirectory();
+      bool file_spec_matches_cu_file_spec =
+          FileSpec::Equal(file_spec, *dc_cu, full_match);
+      if (check_inlines || file_spec_matches_cu_file_spec) {
+        SymbolContext sc(m_obj_file->GetModule());
+        sc.comp_unit = dc_cu;
+        uint32_t file_idx = UINT32_MAX;
+
+        // If we are looking for inline functions only and we don't find it
+        // in the support files, we are done.
+        if (check_inlines) {
+          file_idx =
+              sc.comp_unit->GetSupportFiles().FindFileIndex(1, file_spec, true);
+          if (file_idx == UINT32_MAX)
+            continue;
+        }
+
+        if (line != 0) {
+          LineTable *line_table = sc.comp_unit->GetLineTable();
+
+          if (line_table != nullptr && line != 0) {
+            // We will have already looked up the file index if we are
+            // searching for inline entries.
+            if (!check_inlines)
               file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
                   1, file_spec, true);
-              if (file_idx == UINT32_MAX)
-                continue;
-            }
-
-            if (line != 0) {
-              LineTable *line_table = sc.comp_unit->GetLineTable();
 
-              if (line_table != nullptr && line != 0) {
-                // We will have already looked up the file index if we are
-                // searching for inline entries.
-                if (!check_inlines)
-                  file_idx = sc.comp_unit->GetSupportFiles().FindFileIndex(
-                      1, file_spec, true);
-
-                if (file_idx != UINT32_MAX) {
-                  uint32_t found_line;
-                  uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex(
-                      0, file_idx, line, false, &sc.line_entry);
-                  found_line = sc.line_entry.line;
-
-                  while (line_idx != UINT32_MAX) {
-                    sc.function = nullptr;
-                    sc.block = nullptr;
-                    if (resolve_scope &
-                        (eSymbolContextFunction | eSymbolContextBlock)) {
-                      const lldb::addr_t file_vm_addr =
-                          sc.line_entry.range.GetBaseAddress().GetFileAddress();
-                      if (file_vm_addr != LLDB_INVALID_ADDRESS) {
-                        DWARFDIE function_die =
-                            dwarf_cu->LookupAddress(file_vm_addr);
-                        DWARFDIE block_die;
-                        if (function_die) {
-                          sc.function =
-                              sc.comp_unit
-                                  ->FindFunctionByUID(function_die.GetID())
-                                  .get();
-                          if (sc.function == nullptr)
-                            sc.function =
-                                ParseFunction(*sc.comp_unit, function_die);
-
-                          if (sc.function &&
-                              (resolve_scope & eSymbolContextBlock))
-                            block_die =
-                                function_die.LookupDeepestBlock(file_vm_addr);
-                        }
+            if (file_idx != UINT32_MAX) {
+              uint32_t found_line;
+              uint32_t line_idx = line_table->FindLineEntryIndexByFileIndex(
+                  0, file_idx, line, false, &sc.line_entry);
+              found_line = sc.line_entry.line;
+
+              while (line_idx != UINT32_MAX) {
+                sc.function = nullptr;
+                sc.block = nullptr;
+                if (resolve_scope &
+                    (eSymbolContextFunction | eSymbolContextBlock)) {
+                  const lldb::addr_t file_vm_addr =
+                      sc.line_entry.range.GetBaseAddress().GetFileAddress();
+                  if (file_vm_addr != LLDB_INVALID_ADDRESS) {
+                    DWARFDIE function_die =
+                        GetDWARFCompileUnit(dc_cu)->LookupAddress(file_vm_addr);
+                    DWARFDIE block_die;
+                    if (function_die) {
+                      sc.function =
+                          sc.comp_unit->FindFunctionByUID(function_die.GetID())
+                              .get();
+                      if (sc.function == nullptr)
+                        sc.function =
+                            ParseFunction(*sc.comp_unit, function_die);
+
+                      if (sc.function && (resolve_scope & eSymbolContextBlock))
+                        block_die =
+                            function_die.LookupDeepestBlock(file_vm_addr);
+                    }
 
-                        if (sc.function != nullptr) {
-                          Block &block = sc.function->GetBlock(true);
+                    if (sc.function != nullptr) {
+                      Block &block = sc.function->GetBlock(true);
 
-                          if (block_die)
-                            sc.block = block.FindBlockByID(block_die.GetID());
-                          else if (function_die)
-                            sc.block =
-                                block.FindBlockByID(function_die.GetID());
-                        }
-                      }
+                      if (block_die)
+                        sc.block = block.FindBlockByID(block_die.GetID());
+                      else if (function_die)
+                        sc.block = block.FindBlockByID(function_die.GetID());
                     }
-
-                    sc_list.Append(sc);
-                    line_idx = line_table->FindLineEntryIndexByFileIndex(
-                        line_idx + 1, file_idx, found_line, true,
-                        &sc.line_entry);
                   }
                 }
-              } else if (file_spec_matches_cu_file_spec && !check_inlines) {
-                // only append the context if we aren't looking for inline call
-                // sites by file and line and if the file spec matches that of
-                // the compile unit
+
                 sc_list.Append(sc);
+                line_idx = line_table->FindLineEntryIndexByFileIndex(
+                    line_idx + 1, file_idx, found_line, true, &sc.line_entry);
               }
-            } else if (file_spec_matches_cu_file_spec && !check_inlines) {
-              // only append the context if we aren't looking for inline call
-              // sites by file and line and if the file spec matches that of
-              // the compile unit
-              sc_list.Append(sc);
             }
-
-            if (!check_inlines)
-              break;
-          }
+          } else if (file_spec_matches_cu_file_spec && !check_inlines) {
+            // only append the context if we aren't looking for inline call
+            // sites by file and line and if the file spec matches that of
+            // the compile unit
+            sc_list.Append(sc);
+          }
+        } else if (file_spec_matches_cu_file_spec && !check_inlines) {
+          // only append the context if we aren't looking for inline call
+          // sites by file and line and if the file spec matches that of
+          // the compile unit
+          sc_list.Append(sc);
         }
+
+        if (!check_inlines)
+          break;
       }
     }
   }
@@ -2007,7 +2032,10 @@
           break;
 
         case DW_TAG_variable: {
-          sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU());
+          auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
+          if (!dwarf_cu)
+            continue;
+          sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
 
           if (parent_decl_ctx) {
             DWARFASTParser *dwarf_ast = die.GetDWARFParser();
@@ -2089,7 +2117,11 @@
       DWARFDIE die = GetDIE(die_ref);
 
       if (die) {
-        sc.comp_unit = GetCompUnitForDWARFCompUnit(die.GetCU());
+        DWARFCompileUnit *dwarf_cu =
+            llvm::dyn_cast<DWARFCompileUnit>(die.GetCU());
+        if (!dwarf_cu)
+          continue;
+        sc.comp_unit = GetCompUnitForDWARFCompUnit(*dwarf_cu);
 
         ParseVariables(sc, die, LLDB_INVALID_ADDRESS, false, false, &variables);
 
@@ -2533,9 +2565,13 @@
   if (die) {
     Type *type_ptr = GetDIEToType().lookup(die.GetDIE());
     if (type_ptr == nullptr) {
-      CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU());
-      assert(lldb_cu);
-      SymbolContext sc(lldb_cu);
+      SymbolContextScope *scope;
+      if (auto *dwarf_cu = llvm::dyn_cast<DWARFCompileUnit>(die.GetCU()))
+        scope = GetCompUnitForDWARFCompUnit(*dwarf_cu);
+      else
+        scope = GetObjectFile()->GetModule().get();
+      assert(scope);
+      SymbolContext sc(scope);
       const DWARFDebugInfoEntry *parent_die = die.GetParent().GetDIE();
       while (parent_die != nullptr) {
         if (parent_die->Tag() == DW_TAG_subprogram)
Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
===================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwoDwp.h
@@ -15,7 +15,7 @@
 class SymbolFileDWARFDwoDwp : public SymbolFileDWARFDwo {
 public:
   SymbolFileDWARFDwoDwp(SymbolFileDWARFDwp *dwp_symfile,
-                        lldb::ObjectFileSP objfile, DWARFUnit *dwarf_cu,
+                        lldb::ObjectFileSP objfile, DWARFCompileUnit &dwarf_cu,
                         uint64_t dwo_id);
 
 protected:
Index: lldb/trunk/lit/SymbolFile/DWARF/debug-types-line-tables.s
===================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/debug-types-line-tables.s
+++ lldb/trunk/lit/SymbolFile/DWARF/debug-types-line-tables.s
@@ -169,6 +169,13 @@
         .byte   1                       # DW_CHILDREN_yes
         .byte   0                       # EOM(1)
         .byte   0                       # EOM(2)
+        .byte   5                       # Abbreviation Code
+        .byte   19                      # DW_TAG_structure_type
+        .byte   0                       # DW_CHILDREN_no
+        .byte   105                     # DW_AT_signature
+        .byte   32                      # DW_FORM_ref_sig8
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
         .byte   0                       # EOM(3)
         .section        .debug_info,"",@progbits
 .Lcu_begin0:
@@ -178,6 +185,16 @@
         .long   .debug_abbrev           # Offset Into Abbrev. Section
         .byte   8                       # Address Size (in bytes)
         .byte   4                       # Abbrev [4] 0xb:0x32 DW_TAG_compile_unit
+        .byte   5                       # Abbrev [5] DW_TAG_structure_type
+        .quad   5390450678491038984     # DW_AT_signature
+        .byte   5                       # Abbrev [5] DW_TAG_structure_type
+        .quad   5390450678491038985     # DW_AT_signature
+        .byte   5                       # Abbrev [5] DW_TAG_structure_type
+        .quad   5390450678491038986     # DW_AT_signature
+        .byte   5                       # Abbrev [5] DW_TAG_structure_type
+        .quad   5390450678491038987     # DW_AT_signature
+        .byte   5                       # Abbrev [5] DW_TAG_structure_type
+        .quad   5390450678491038988     # DW_AT_signature
         .byte   0                       # End Of Children Mark
 .Ldebug_info_end1:
 
Index: lldb/trunk/lit/SymbolFile/DWARF/debug-types-dwarf5.s
===================================================================
--- lldb/trunk/lit/SymbolFile/DWARF/debug-types-dwarf5.s
+++ lldb/trunk/lit/SymbolFile/DWARF/debug-types-dwarf5.s
@@ -0,0 +1,94 @@
+# RUN: llvm-mc -triple=x86_64-pc-linux -filetype=obj %s > %t
+# RUN: %lldb %t -o "image lookup -v -s f1" -o exit | FileCheck %s
+
+# CHECK:  Function: id = {0x7fffffff0000003c}, name = "f1", range = [0x0000000000000000-0x0000000000000001)
+# CHECK:    Blocks: id = {0x7fffffff0000003c}, range = [0x00000000-0x00000001)
+
+
+        .text
+        .globl  f1
+        .type   f1,@function
+f1:
+        nop
+.Lfunc_end0:
+        .size   f1, .Lfunc_end0-f1
+                                        # -- End function
+        .section        .debug_str,"MS",@progbits,1
+.Lproducer:
+        .asciz  "Hand-written DWARF"
+.Lf1:
+        .asciz  "f1"
+.Le1:
+        .asciz  "e1"
+
+        .section        .debug_abbrev,"",@progbits
+        .byte   1                       # Abbreviation Code
+        .byte   17                      # DW_TAG_compile_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   37                      # DW_AT_producer
+        .byte   14                      # DW_FORM_strp
+        .byte   17                      # DW_AT_low_pc
+        .byte   1                       # DW_FORM_addr
+        .byte   18                      # DW_AT_high_pc
+        .byte   6                       # DW_FORM_data4
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   2                       # Abbreviation Code
+        .byte   46                      # DW_TAG_subprogram
+        .byte   0                       # DW_CHILDREN_no
+        .byte   17                      # DW_AT_low_pc
+        .byte   1                       # DW_FORM_addr
+        .byte   18                      # DW_AT_high_pc
+        .byte   6                       # DW_FORM_data4
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   3                       # Abbreviation Code
+        .byte   65                      # DW_TAG_type_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   5                       # Abbreviation Code
+        .byte   4                       # DW_TAG_enumeration_type
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   0                       # EOM(3)
+
+        .section        .debug_info,"",@progbits
+.Ltu_begin0:
+        .long   .Ltu_end0-.Ltu_start0   # Length of Unit
+.Ltu_start0:
+        .short  5                       # DWARF version number
+        .byte   2                       # DWARF Unit Type
+        .byte   8                       # Address Size (in bytes)
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .quad   47                      # Type Signature
+        .long   .Ltype-.Ltu_begin0      # Type DIE Offset
+        .byte   3                       # Abbrev [1] 0x18:0x1d DW_TAG_type_unit
+.Ltype:
+        .byte   5                       # Abbrev [5] 0x2e:0x9 DW_TAG_enumeration_type
+        .long   .Le1                    # DW_AT_name
+        .byte   0                       # End Of Children Mark
+.Ltu_end0:
+
+.Lcu_begin0:
+        .long   .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+        .short  5                       # DWARF version number
+        .byte   1                       # DWARF Unit Type
+        .byte   8                       # Address Size (in bytes)
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   1                       # Abbrev [1] 0xc:0x5f DW_TAG_compile_unit
+        .long   .Lproducer              # DW_AT_producer
+        .quad   f1                      # DW_AT_low_pc
+        .long   .Lfunc_end0-f1          # DW_AT_high_pc
+        .byte   2                       # Abbrev [2] 0x2b:0x37 DW_TAG_subprogram
+        .quad   f1                      # DW_AT_low_pc
+        .long   .Lfunc_end0-f1          # DW_AT_high_pc
+        .long   .Lf1                    # DW_AT_name
+        .byte   0                       # End Of Children Mark
+.Ldebug_info_end0:
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to