labath updated this revision to Diff 203845.
labath added a comment.

- address code review comments


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

https://reviews.llvm.org/D62894

Files:
  lit/SymbolFile/DWARF/debug-types-line-tables.s
  lit/SymbolFile/DWARF/forward-declarations.s
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
  source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
  source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
  source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
  source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
  source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
  source/Plugins/SymbolFile/DWARF/DWARFUnit.h
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h

Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -49,6 +49,7 @@
 class DWARFDebugRangesBase;
 class DWARFDeclContext;
 class DWARFFormValue;
+class DWARFTypeUnit;
 class SymbolFileDWARFDebugMap;
 class SymbolFileDWARFDwo;
 class SymbolFileDWARFDwp;
@@ -299,6 +300,8 @@
 
   lldb_private::DWARFContext &GetDWARFContext() { return m_context; }
 
+  lldb_private::FileSpec GetFile(DWARFUnit &unit, size_t file_idx);
+
 protected:
   typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *>
       DIEToTypePtr;
@@ -438,6 +441,8 @@
 
   SymbolFileDWARFDwp *GetDwpSymbolFile();
 
+  const lldb_private::FileSpecList &GetTypeUnitSupportFiles(DWARFTypeUnit &tu);
+
   lldb::ModuleWP m_debug_map_module_wp;
   SymbolFileDWARFDebugMap *m_debug_map_symfile;
 
@@ -476,6 +481,8 @@
   DIEToVariableSP m_die_to_variable_sp;
   DIEToClangType m_forward_decl_die_to_clang_type;
   ClangTypeToDIE m_forward_decl_clang_type_to_die;
+  llvm::DenseMap<dw_offset_t, lldb_private::FileSpecList>
+      m_type_unit_support_files;
 };
 
 #endif // SymbolFileDWARF_SymbolFileDWARF_h_
Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -54,6 +54,7 @@
 #include "AppleDWARFIndex.h"
 #include "DWARFASTParser.h"
 #include "DWARFASTParserClang.h"
+#include "DWARFCompileUnit.h"
 #include "DWARFDebugAbbrev.h"
 #include "DWARFDebugAranges.h"
 #include "DWARFDebugInfo.h"
@@ -62,6 +63,7 @@
 #include "DWARFDebugRanges.h"
 #include "DWARFDeclContext.h"
 #include "DWARFFormValue.h"
+#include "DWARFTypeUnit.h"
 #include "DWARFUnit.h"
 #include "DebugNamesDWARFIndex.h"
 #include "LogChannelDWARF.h"
@@ -775,26 +777,55 @@
 bool SymbolFileDWARF::ParseSupportFiles(CompileUnit &comp_unit,
                                         FileSpecList &support_files) {
   ASSERT_MODULE_LOCK(this);
-  DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
-  if (dwarf_cu) {
-    const DWARFBaseDIE cu_die = dwarf_cu->GetUnitDIEOnly();
-
-    if (cu_die) {
-      const dw_offset_t stmt_list = cu_die.GetAttributeValueAsUnsigned(
-          DW_AT_stmt_list, DW_INVALID_OFFSET);
-      if (stmt_list != DW_INVALID_OFFSET) {
-        // All file indexes in DWARF are one based and a file of index zero is
-        // supposed to be the compile unit itself.
-        support_files.Append(comp_unit);
-        return DWARFDebugLine::ParseSupportFiles(
-            comp_unit.GetModule(), m_context.getOrLoadLineData(), stmt_list,
-            support_files, dwarf_cu);
-      }
+  DWARFUnit *unit = GetDWARFCompileUnit(&comp_unit);
+  if (auto *tu = llvm::dyn_cast_or_null<DWARFTypeUnit>(unit)) {
+    support_files = GetTypeUnitSupportFiles(*tu);
+    return true;
+  }
+
+  if (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
+      // supposed to be the compile unit itself.
+      support_files.Append(comp_unit);
+      return DWARFDebugLine::ParseSupportFiles(comp_unit.GetModule(),
+                                               m_context.getOrLoadLineData(),
+                                               stmt_list, support_files, unit);
     }
   }
   return false;
 }
 
+FileSpec SymbolFileDWARF::GetFile(DWARFUnit &unit, size_t file_idx) {
+  if (CompileUnit *lldb_cu = GetCompUnitForDWARFCompUnit(&unit))
+    return lldb_cu->GetSupportFiles().GetFileSpecAtIndex(file_idx);
+  return FileSpec();
+}
+
+const FileSpecList &
+SymbolFileDWARF::GetTypeUnitSupportFiles(DWARFTypeUnit &tu) {
+  static FileSpecList empty_list;
+
+  dw_offset_t offset = tu.GetLineTableOffset();
+  if (offset == DW_INVALID_OFFSET ||
+      offset == llvm::DenseMapInfo<dw_offset_t>::getEmptyKey() ||
+      offset == llvm::DenseMapInfo<dw_offset_t>::getTombstoneKey())
+    return empty_list;
+
+  // Many type units can share a line table, so parse the support file list
+  // once, and cache it based on the offset field.
+  auto iter_bool = m_type_unit_support_files.try_emplace(offset);
+  FileSpecList &list = iter_bool.first->second;
+  if (iter_bool.second) {
+    list.Append(FileSpec());
+    DWARFDebugLine::ParseSupportFiles(GetObjectFile()->GetModule(),
+                                      m_context.getOrLoadLineData(), offset,
+                                      list, &tu);
+  }
+  return list;
+}
+
 bool SymbolFileDWARF::ParseIsOptimized(CompileUnit &comp_unit) {
   ASSERT_MODULE_LOCK(this);
   DWARFUnit *dwarf_cu = GetDWARFCompileUnit(&comp_unit);
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -141,8 +141,9 @@
   const DWARFAbbreviationDeclarationSet *GetAbbreviations() const;
   dw_offset_t GetAbbrevOffset() const;
   uint8_t GetAddressByteSize() const { return m_header.GetAddressByteSize(); }
-  dw_addr_t GetBaseAddress() const { return m_base_addr; }
   dw_addr_t GetAddrBase() const { return m_addr_base; }
+  dw_addr_t GetBaseAddress() const { return m_base_addr; }
+  dw_offset_t GetLineTableOffset();
   dw_addr_t GetRangesBase() const { return m_ranges_base; }
   dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; }
   void SetAddrBase(dw_addr_t addr_base);
@@ -196,6 +197,7 @@
   bool GetIsOptimized();
 
   const lldb_private::FileSpec &GetCompilationDirectory();
+  const lldb_private::FileSpec &GetAbsolutePath();
   lldb_private::FileSpec::Style GetPathStyle();
 
   SymbolFileDWARFDwo *GetDwoSymbolFile() const;
@@ -210,6 +212,7 @@
   DIERef::Section GetDebugSection() const { return m_section; }
 
   uint8_t GetUnitType() const { return m_header.GetUnitType(); }
+  bool IsTypeUnit() const { return m_header.IsTypeUnit(); }
 
   /// Return a list of address ranges resulting from a (possibly encoded)
   /// range list starting at a given offset in the appropriate ranges section.
@@ -277,11 +280,16 @@
   lldb::LanguageType m_language_type = lldb::eLanguageTypeUnknown;
   lldb_private::LazyBool m_is_optimized = lldb_private::eLazyBoolCalculate;
   llvm::Optional<lldb_private::FileSpec> m_comp_dir;
+  llvm::Optional<lldb_private::FileSpec> m_file_spec;
   dw_addr_t m_addr_base = 0;   // Value of DW_AT_addr_base
   dw_addr_t m_ranges_base = 0; // Value of DW_AT_ranges_base
   // If this is a dwo compile unit this is the offset of the base compile unit
   // in the main object file
   dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
+
+  /// Value of DW_AT_stmt_list.
+  dw_offset_t m_line_table_offset = DW_INVALID_OFFSET;
+
   dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base.
   const DIERef::Section m_section;
 
@@ -293,6 +301,7 @@
   void AddUnitDIE(const DWARFDebugInfoEntry &cu_die);
 
   void ComputeCompDirAndGuessPathStyle();
+  void ComputeAbsolutePath();
 
   DISALLOW_COPY_AND_ASSIGN(DWARFUnit);
 };
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -283,24 +283,47 @@
 
 // m_die_array_mutex must be already held as read/write.
 void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
-  dw_addr_t addr_base = cu_die.GetAttributeValueAsUnsigned(
-      this, DW_AT_addr_base, LLDB_INVALID_ADDRESS);
-  if (addr_base != LLDB_INVALID_ADDRESS)
-    SetAddrBase(addr_base);
-
-  dw_addr_t ranges_base = cu_die.GetAttributeValueAsUnsigned(
-      this, DW_AT_rnglists_base, LLDB_INVALID_ADDRESS);
-  if (ranges_base != LLDB_INVALID_ADDRESS)
-    SetRangesBase(ranges_base);
-
-  SetStrOffsetsBase(
-      cu_die.GetAttributeValueAsUnsigned(this, DW_AT_str_offsets_base, 0));
-
-  uint64_t base_addr = cu_die.GetAttributeValueAsAddress(this, DW_AT_low_pc,
-                                                         LLDB_INVALID_ADDRESS);
-  if (base_addr == LLDB_INVALID_ADDRESS)
-    base_addr = cu_die.GetAttributeValueAsAddress(this, DW_AT_entry_pc, 0);
-  SetBaseAddress(base_addr);
+  llvm::Optional<uint64_t> addr_base, gnu_addr_base, ranges_base,
+      gnu_ranges_base;
+
+  DWARFAttributes attributes;
+  size_t num_attributes = cu_die.GetAttributes(this, attributes);
+  for (size_t i = 0; i < num_attributes; ++i) {
+    dw_attr_t attr = attributes.AttributeAtIndex(i);
+    DWARFFormValue form_value;
+    if (!attributes.ExtractFormValueAtIndex(i, form_value))
+      continue;
+    switch (attr) {
+    case DW_AT_addr_base:
+      addr_base = form_value.Unsigned();
+      SetAddrBase(*addr_base);
+      break;
+    case DW_AT_rnglists_base:
+      ranges_base = form_value.Unsigned();
+      SetRangesBase(*ranges_base);
+      break;
+    case DW_AT_str_offsets_base:
+      SetStrOffsetsBase(form_value.Unsigned());
+      break;
+    case DW_AT_low_pc:
+      SetBaseAddress(form_value.Address());
+      break;
+    case DW_AT_entry_pc:
+      // If the value was already set by DW_AT_low_pc, don't update it.
+      if (m_base_addr == LLDB_INVALID_ADDRESS)
+        SetBaseAddress(form_value.Address());
+      break;
+    case DW_AT_stmt_list:
+      m_line_table_offset = form_value.Unsigned();
+      break;
+    case DW_AT_GNU_addr_base:
+      gnu_addr_base = form_value.Unsigned();
+      break;
+    case DW_AT_GNU_ranges_base:
+      gnu_ranges_base = form_value.Unsigned();
+      break;
+    }
+  }
 
   std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
       m_dwarf->GetDwoSymbolFileForCompileUnit(*this, cu_die);
@@ -331,18 +354,17 @@
   // attributes which were applicable to the DWO units. The corresponding
   // DW_AT_* attributes standardized in DWARF v5 are also applicable to the main
   // unit in contrast.
-  if (addr_base == LLDB_INVALID_ADDRESS)
-    addr_base =
-        cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_addr_base, 0);
-  dwo_cu->SetAddrBase(addr_base);
+  if (addr_base)
+    dwo_cu->SetAddrBase(*addr_base);
+  else if (gnu_addr_base)
+    dwo_cu->SetAddrBase(*gnu_addr_base);
 
-  if (ranges_base == LLDB_INVALID_ADDRESS)
-    ranges_base =
-        cu_die.GetAttributeValueAsUnsigned(this, DW_AT_GNU_ranges_base, 0);
-  dwo_cu->SetRangesBase(ranges_base);
+  if (ranges_base)
+    dwo_cu->SetRangesBase(*ranges_base);
+  else if (gnu_ranges_base)
+    dwo_cu->SetRangesBase(*gnu_ranges_base);
 
   dwo_cu->SetBaseObjOffset(GetOffset());
-
   SetDwoStrOffsetsBase(dwo_cu);
 }
 
@@ -387,6 +409,11 @@
   return m_abbrevs ? m_abbrevs->GetOffset() : DW_INVALID_OFFSET;
 }
 
+dw_offset_t DWARFUnit::GetLineTableOffset() {
+  ExtractUnitDIEIfNeeded();
+  return m_line_table_offset;
+}
+
 void DWARFUnit::SetAddrBase(dw_addr_t addr_base) { m_addr_base = addr_base; }
 
 void DWARFUnit::SetRangesBase(dw_addr_t ranges_base) {
@@ -611,6 +638,12 @@
   return *m_comp_dir;
 }
 
+const FileSpec &DWARFUnit::GetAbsolutePath() {
+  if (!m_file_spec)
+    ComputeAbsolutePath();
+  return *m_file_spec;
+}
+
 // DWARF2/3 suggests the form hostname:pathname for compilation directory.
 // Remove the host part if present.
 static llvm::StringRef
@@ -670,6 +703,20 @@
   }
 }
 
+void DWARFUnit::ComputeAbsolutePath() {
+  m_file_spec = FileSpec();
+  const DWARFDebugInfoEntry *die = GetUnitDIEPtrOnly();
+  if (!die)
+    return;
+
+  m_file_spec =
+      FileSpec(die->GetAttributeValueAsString(this, DW_AT_name, nullptr),
+               GetPathStyle());
+
+  if (m_file_spec->IsRelative())
+    m_file_spec->MakeAbsolute(GetCompilationDirectory());
+}
+
 SymbolFileDWARFDwo *DWARFUnit::GetDwoSymbolFile() const {
   return m_dwo_symbol_file.get();
 }
Index: source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
@@ -22,9 +22,7 @@
 
   dw_offset_t GetTypeOffset() { return GetOffset() + m_header.GetTypeOffset(); }
 
-  static bool classof(const DWARFUnit *unit) {
-    return unit->GetUnitType() == DW_UT_type;
-  }
+  static bool classof(const DWARFUnit *unit) { return unit->IsTypeUnit(); }
 
 private:
   DWARFTypeUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid,
Index: source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -18,6 +18,8 @@
 
   void Dump(lldb_private::Stream *s) const override;
 
+  static bool classof(const DWARFUnit *unit) { return !unit->IsTypeUnit(); }
+
 private:
   DWARFCompileUnit(SymbolFileDWARF *dwarf, lldb::user_id_t uid,
                    const DWARFUnitHeader &header,
Index: source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -101,8 +101,6 @@
 
   lldb::ModuleSP GetModule() const;
 
-  lldb_private::CompileUnit *GetLLDBCompileUnit() const;
-
   // Getting attribute values from the DIE.
   //
   // GetAttributeValueAsXXX() functions should only be used if you are
Index: source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -90,13 +90,6 @@
     return lldb::ModuleSP();
 }
 
-lldb_private::CompileUnit *DWARFBaseDIE::GetLLDBCompileUnit() const {
-  if (IsValid())
-    return GetDWARF()->GetCompUnitForDWARFCompUnit(GetCU());
-  else
-    return nullptr;
-}
-
 dw_offset_t DWARFBaseDIE::GetOffset() const {
   if (IsValid())
     return m_die->GetOffset();
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -81,8 +81,7 @@
           &template_param_infos);
 
   bool ParseChildMembers(
-      const lldb_private::SymbolContext &sc, const DWARFDIE &die,
-      lldb_private::CompilerType &class_compiler_type,
+      const DWARFDIE &die, lldb_private::CompilerType &class_compiler_type,
       const lldb::LanguageType class_language,
       std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
       std::vector<int> &member_accessibilities,
@@ -92,8 +91,7 @@
       lldb_private::ClangASTImporter::LayoutInfo &layout_info);
 
   size_t
-  ParseChildParameters(lldb_private::CompileUnit &comp_unit,
-                       clang::DeclContext *containing_decl_ctx,
+  ParseChildParameters(clang::DeclContext *containing_decl_ctx,
                        const DWARFDIE &parent_die, bool skip_artificial,
                        bool &is_static, bool &is_variadic,
                        bool &has_template_params,
@@ -101,8 +99,7 @@
                        std::vector<clang::ParmVarDecl *> &function_param_decls,
                        unsigned &type_quals);
 
-  size_t ParseChildEnumerators(const lldb_private::SymbolContext &sc,
-                               lldb_private::CompilerType &compiler_type,
+  size_t ParseChildEnumerators(lldb_private::CompilerType &compiler_type,
                                bool is_signed, uint32_t enumerator_byte_size,
                                const DWARFDIE &parent_die);
 
Index: source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -233,7 +233,7 @@
 /// Some attributes are relevant for all kinds of types (declaration), while
 /// others are only meaningful to a specific type (is_virtual)
 struct ParsedTypeAttributes {
-  ParsedTypeAttributes(const DWARFDIE &die, CompileUnit &comp_unit);
+  explicit ParsedTypeAttributes(const DWARFDIE &die);
 
   AccessType accessibility = eAccessNone;
   bool is_artificial = false;
@@ -263,8 +263,7 @@
 };
 } // namespace
 
-ParsedTypeAttributes::ParsedTypeAttributes(const DWARFDIE &die,
-                                           CompileUnit &comp_unit) {
+ParsedTypeAttributes::ParsedTypeAttributes(const DWARFDIE &die) {
   DWARFAttributes attributes;
   size_t num_attributes = die.GetAttributes(attributes);
   for (size_t i = 0; i < num_attributes; ++i) {
@@ -306,8 +305,8 @@
       break;
 
     case DW_AT_decl_file:
-      decl.SetFile(comp_unit.GetSupportFiles().GetFileSpecAtIndex(
-          form_value.Unsigned()));
+      decl.SetFile(
+          die.GetDWARF()->GetFile(*die.GetCU(), form_value.Unsigned()));
       break;
     case DW_AT_decl_line:
       decl.SetLine(form_value.Unsigned());
@@ -385,6 +384,12 @@
   }
 }
 
+static std::string GetUnitName(const DWARFDIE &die) {
+  if (DWARFUnit *unit = die.GetCU())
+    return unit->GetAbsolutePath().GetPath();
+  return "<missing DWARF unit path>";
+}
+
 TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
                                                const DWARFDIE &die, Log *log,
                                                bool *type_is_new_ptr) {
@@ -416,7 +421,7 @@
   // Set a bit that lets us know that we are currently parsing this
   dwarf->GetDIEToType()[die.GetDIE()] = DIE_IS_BEING_PARSED;
 
-  ParsedTypeAttributes attrs(die, *sc.comp_unit);
+  ParsedTypeAttributes attrs(die);
 
   if (DWARFDIE signature_die = attrs.signature.Reference()) {
     if (TypeSP type_sp =
@@ -1107,10 +1112,9 @@
 
     if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
       if (die.HasChildren()) {
-        SymbolContext cu_sc(die.GetLLDBCompileUnit());
         bool is_signed = false;
         enumerator_clang_type.IsIntegerType(is_signed);
-        ParseChildEnumerators(cu_sc, clang_type, is_signed,
+        ParseChildEnumerators(clang_type, is_signed,
                               type_sp->GetByteSize().getValueOr(0), die);
       }
       ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
@@ -1174,10 +1178,10 @@
 
     if (die.HasChildren()) {
       bool skip_artificial = true;
-      ParseChildParameters(*sc.comp_unit, containing_decl_ctx, die,
-                           skip_artificial, is_static, is_variadic,
-                           has_template_params, function_param_types,
-                           function_param_decls, type_quals);
+      ParseChildParameters(containing_decl_ctx, die, skip_artificial, is_static,
+                           is_variadic, has_template_params,
+                           function_param_types, function_param_decls,
+                           type_quals);
     }
 
     bool ignore_containing_context = false;
@@ -1464,8 +1468,6 @@
         if (attrs.abstract_origin.IsValid()) {
           DWARFDIE abs_die = attrs.abstract_origin.Reference();
 
-          SymbolContext sc;
-
           if (dwarf->ResolveType(abs_die)) {
             function_decl = llvm::dyn_cast_or_null<clang::FunctionDecl>(
                 GetCachedClangDeclContextForDIE(abs_die));
@@ -1574,9 +1576,7 @@
                 "file a bug against the compiler and include the "
                 "preprocessed output for %s",
                 die.GetOffset(), type_die_ref.die_offset,
-                die.GetLLDBCompileUnit()
-                    ? die.GetLLDBCompileUnit()->GetPath().c_str()
-                    : "the source file");
+                GetUnitName(die).c_str());
         }
 
         // We have no choice other than to pretend that the element class
@@ -1665,7 +1665,8 @@
           sc.function->GetBlock(true).FindBlockByID(sc_parent_die.GetID());
       if (symbol_context_scope == NULL)
         symbol_context_scope = sc.function;
-    }
+    } else
+      symbol_context_scope = sc.module_sp.get();
 
     if (symbol_context_scope != NULL) {
       type_sp->SetSymbolContextScope(symbol_context_scope);
@@ -1966,7 +1967,6 @@
           default_accessibility = eAccessPrivate;
         }
 
-        SymbolContext sc(die.GetLLDBCompileUnit());
         std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases;
         std::vector<int> member_accessibilities;
         bool is_a_class = false;
@@ -1974,7 +1974,7 @@
         std::vector<DWARFDIE> member_function_dies;
 
         DelayedPropertyList delayed_properties;
-        ParseChildMembers(sc, die, clang_type, class_language, bases,
+        ParseChildMembers(die, clang_type, class_language, bases,
                           member_accessibilities, member_function_dies,
                           delayed_properties, default_accessibility, is_a_class,
                           layout_info);
@@ -2165,10 +2165,9 @@
   case DW_TAG_enumeration_type:
     if (ClangASTContext::StartTagDeclarationDefinition(clang_type)) {
       if (die.HasChildren()) {
-        SymbolContext sc(die.GetLLDBCompileUnit());
         bool is_signed = false;
         clang_type.IsIntegerType(is_signed);
-        ParseChildEnumerators(sc, clang_type, is_signed,
+        ParseChildEnumerators(clang_type, is_signed,
                               type->GetByteSize().getValueOr(0), die);
       }
       ClangASTContext::CompleteTagDeclarationDefinition(clang_type);
@@ -2218,8 +2217,8 @@
 }
 
 size_t DWARFASTParserClang::ParseChildEnumerators(
-    const SymbolContext &sc, lldb_private::CompilerType &clang_type,
-    bool is_signed, uint32_t enumerator_byte_size, const DWARFDIE &parent_die) {
+    lldb_private::CompilerType &clang_type, bool is_signed,
+    uint32_t enumerator_byte_size, const DWARFDIE &parent_die) {
   if (!parent_die)
     return 0;
 
@@ -2258,8 +2257,8 @@
             case DW_AT_description:
             default:
             case DW_AT_decl_file:
-              decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
-                  form_value.Unsigned()));
+              decl.SetFile(
+                  die.GetDWARF()->GetFile(*die.GetCU(), form_value.Unsigned()));
               break;
             case DW_AT_decl_line:
               decl.SetLine(form_value.Unsigned());
@@ -2393,9 +2392,9 @@
 
         clang::DeclContext *containing_decl_ctx =
             GetClangDeclContextContainingDIE(die, nullptr);
-        ParseChildParameters(comp_unit, containing_decl_ctx, die, true,
-                             is_static, is_variadic, has_template_params,
-                             param_types, param_decls, type_quals);
+        ParseChildParameters(containing_decl_ctx, die, true, is_static,
+                             is_variadic, has_template_params, param_types,
+                             param_decls, type_quals);
         sstr << "(";
         for (size_t i = 0; i < param_types.size(); i++) {
           if (i > 0)
@@ -2415,9 +2414,9 @@
       FunctionSP func_sp;
       std::unique_ptr<Declaration> decl_up;
       if (decl_file != 0 || decl_line != 0 || decl_column != 0)
-        decl_up.reset(new Declaration(
-            comp_unit.GetSupportFiles().GetFileSpecAtIndex(decl_file),
-            decl_line, decl_column));
+        decl_up.reset(
+            new Declaration(die.GetDWARF()->GetFile(*die.GetCU(), decl_file),
+                            decl_line, decl_column));
 
       SymbolFileDWARF *dwarf = die.GetDWARF();
       // Supply the type _only_ if it has already been parsed
@@ -2446,8 +2445,8 @@
 }
 
 bool DWARFASTParserClang::ParseChildMembers(
-    const SymbolContext &sc, const DWARFDIE &parent_die,
-    CompilerType &class_clang_type, const LanguageType class_language,
+    const DWARFDIE &parent_die, CompilerType &class_clang_type,
+    const LanguageType class_language,
     std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
     std::vector<int> &member_accessibilities,
     std::vector<DWARFDIE> &member_function_dies,
@@ -2706,13 +2705,12 @@
                   ObjectFile *objfile = die.GetDWARF()->GetObjectFile();
                   objfile->GetModule()->ReportWarning(
                       "0x%8.8" PRIx64 ": %s bitfield named \"%s\" has invalid "
-                                      "bit offset (0x%8.8" PRIx64
+                      "bit offset (0x%8.8" PRIx64
                       ") member will be ignored. Please file a bug against the "
                       "compiler and include the preprocessed output for %s\n",
                       die.GetID(), DW_TAG_value_to_name(tag), name,
                       this_field_info.bit_offset,
-                      sc.comp_unit ? sc.comp_unit->GetPath().c_str()
-                                   : "the source file");
+                      GetUnitName(parent_die).c_str());
                   this_field_info.Clear();
                   continue;
                 }
@@ -2865,9 +2863,7 @@
                       "complete definition.\nPlease file a bug against the "
                       "compiler and include the preprocessed output for %s",
                       parent_die.GetOffset(), parent_die.GetName(),
-                      die.GetOffset(), name,
-                      sc.comp_unit ? sc.comp_unit->GetPath().c_str()
-                                   : "the source file");
+                      die.GetOffset(), name, GetUnitName(parent_die).c_str());
                 // We have no choice other than to pretend that the member
                 // class is complete. If we don't do this, clang will crash
                 // when trying to layout the class. Since we provide layout
@@ -3064,10 +3060,9 @@
 }
 
 size_t DWARFASTParserClang::ParseChildParameters(
-    CompileUnit &comp_unit, clang::DeclContext *containing_decl_ctx,
-    const DWARFDIE &parent_die, bool skip_artificial, bool &is_static,
-    bool &is_variadic, bool &has_template_params,
-    std::vector<CompilerType> &function_param_types,
+    clang::DeclContext *containing_decl_ctx, const DWARFDIE &parent_die,
+    bool skip_artificial, bool &is_static, bool &is_variadic,
+    bool &has_template_params, std::vector<CompilerType> &function_param_types,
     std::vector<clang::ParmVarDecl *> &function_param_decls,
     unsigned &type_quals) {
   if (!parent_die)
Index: lit/SymbolFile/DWARF/forward-declarations.s
===================================================================
--- /dev/null
+++ lit/SymbolFile/DWARF/forward-declarations.s
@@ -0,0 +1,108 @@
+# Test handling of the situation (including the error message) where a structure
+# has a incomplete member.
+# RUN: llvm-mc -triple x86_64-pc-linux -filetype=obj %s -o %t
+# RUN: %lldb %t -o "target var b" -b 2>&1 | FileCheck %s
+
+# CHECK: error: {{.*}} DWARF DIE at 0x0000002b (class B) has a member variable 0x00000030 (a) whose type is a forward declaration, not a complete definition.
+# CHECK-NEXT: Please file a bug against the compiler and include the preprocessed output for /tmp/a.cc
+
+# CHECK: b = (a = A @ 0x0000000000000001)
+
+        .type   b,@object               # @b
+        .comm   b,1,1
+        .section        .debug_str,"MS",@progbits,1
+.Linfo_string0:
+        .asciz  "Hand-written DWARF"
+.Lcu_name:
+        .asciz  "/tmp/a.cc"
+.Lcu_compdir:
+        .asciz  "/foo/bar"
+.Lb:
+        .asciz  "b"
+.La:
+        .asciz  "a"
+.LA:
+        .asciz  "A"
+.LB:
+        .asciz  "B"
+
+        .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   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   27                      # DW_AT_comp_dir
+        .byte   14                      # DW_FORM_strp
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   2                       # Abbreviation Code
+        .byte   52                      # DW_TAG_variable
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   73                      # DW_AT_type
+        .byte   19                      # DW_FORM_ref4
+        .byte   2                       # DW_AT_location
+        .byte   24                      # DW_FORM_exprloc
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   3                       # Abbreviation Code
+        .byte   19                      # DW_TAG_structure_type
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   4                       # Abbreviation Code
+        .byte   13                      # DW_TAG_member
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   73                      # DW_AT_type
+        .byte   19                      # DW_FORM_ref4
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   5                       # Abbreviation Code
+        .byte   19                      # DW_TAG_structure_type
+        .byte   0                       # DW_CHILDREN_no
+        .byte   60                      # DW_AT_declaration
+        .byte   25                      # DW_FORM_flag_present
+        .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
+.Lcu_begin0:
+        .long   .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
+.Ldebug_info_start0:
+        .short  4                       # DWARF version number
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .byte   1                       # Abbrev [1] 0xb:0x46 DW_TAG_compile_unit
+        .long   .Linfo_string0          # DW_AT_producer
+        .long   .Lcu_name               # DW_AT_name
+        .long   .Lcu_compdir            # DW_AT_comp_dir
+        .byte   2                       # Abbrev [2] 0x1e:0x15 DW_TAG_variable
+        .long   .Lb                     # DW_AT_name
+        .long   .LB_die-.Lcu_begin0     # DW_AT_type
+        .byte   9                       # DW_AT_location
+        .byte   3
+        .quad   b
+.LB_die:
+        .byte   3                       # Abbrev [3] 0x33:0x15 DW_TAG_structure_type
+        .long   .LB                     # DW_AT_name
+        .byte   4                       # Abbrev [4] 0x3b:0xc DW_TAG_member
+        .long   .La                     # DW_AT_name
+        .long   .LA_die-.Lcu_begin0     # DW_AT_type
+        .byte   0                       # End Of Children Mark
+.LA_die:
+        .byte   5                       # Abbrev [5] 0x48:0x8 DW_TAG_structure_type
+                                        # DW_AT_declaration
+        .long   .LA                     # DW_AT_name
+        .byte   0                       # End Of Children Mark
+.Ldebug_info_end0:
Index: lit/SymbolFile/DWARF/debug-types-line-tables.s
===================================================================
--- /dev/null
+++ lit/SymbolFile/DWARF/debug-types-line-tables.s
@@ -0,0 +1,183 @@
+# RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux %s -o %t
+# RUN: lldb-test symbols %t | FileCheck %s
+
+        .file   1 "/tmp" "b.cc"
+
+        .section        .debug_types,"",@progbits
+
+# CHECK: Types:
+# Type unit one: "struct A" defined at b.cc:1
+# CHECK-DAG: name = "A", size = 4, decl = b.cc:1
+1:
+        .long   4f-2f                   # Length of Unit
+2:
+        .short  4                       # DWARF version number
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .quad   5390450678491038984     # Type Signature
+        .long   3f-1b                   # Type DIE Offset
+        .byte   1                       # Abbrev [1] 0x17:0x1b DW_TAG_type_unit
+        .short  4                       # DW_AT_language
+        .long   .Lline_table_start0     # DW_AT_stmt_list
+3:
+        .byte   2                       # Abbrev [2] 0x1e:0xc DW_TAG_structure_type
+        .long   .LA                     # DW_AT_name
+        .byte   4                       # DW_AT_byte_size
+        .byte   1                       # DW_AT_decl_file
+        .byte   1                       # DW_AT_decl_line
+        .byte   0                       # End Of Children Mark
+4:
+
+# Type unit two: "struct B" defined at b.cc:2
+# It shares the same line table as unit one.
+# CHECK-DAG: name = "B", size = 4, decl = b.cc:2
+1:
+        .long   4f-2f                   # Length of Unit
+2:
+        .short  4                       # DWARF version number
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .quad   5390450678491038985     # Type Signature
+        .long   3f-1b                   # Type DIE Offset
+        .byte   1                       # Abbrev [1] 0x17:0x1b DW_TAG_type_unit
+        .short  4                       # DW_AT_language
+        .long   .Lline_table_start0     # DW_AT_stmt_list
+3:
+        .byte   2                       # Abbrev [2] 0x1e:0xc DW_TAG_structure_type
+        .long   .LB                     # DW_AT_name
+        .byte   4                       # DW_AT_byte_size
+        .byte   1                       # DW_AT_decl_file
+        .byte   2                       # DW_AT_decl_line
+        .byte   0                       # End Of Children Mark
+4:
+
+# Type unit three: "struct C".
+# DW_AT_stmt_list missing
+# CHECK-DAG: name = "C", size = 4, line = 3
+1:
+        .long   4f-2f                   # Length of Unit
+2:
+        .short  4                       # DWARF version number
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .quad   5390450678491038986     # Type Signature
+        .long   3f-1b                   # Type DIE Offset
+        .byte   4                       # Abbrev [4] 0x17:0x1b DW_TAG_type_unit
+        .short  4                       # DW_AT_language
+3:
+        .byte   2                       # Abbrev [2] 0x1e:0xc DW_TAG_structure_type
+        .long   .LC                     # DW_AT_name
+        .byte   4                       # DW_AT_byte_size
+        .byte   1                       # DW_AT_decl_file
+        .byte   3                       # DW_AT_decl_line
+        .byte   0                       # End Of Children Mark
+4:
+
+# Type unit four: "struct D".
+# DW_AT_stmt_list invalid
+# CHECK-DAG: name = "D", size = 4, line = 4
+1:
+        .long   4f-2f                   # Length of Unit
+2:
+        .short  4                       # DWARF version number
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .quad   5390450678491038987     # Type Signature
+        .long   3f-1b                   # Type DIE Offset
+        .byte   1                       # Abbrev [1] 0x17:0x1b DW_TAG_type_unit
+        .short  4                       # DW_AT_language
+        .long   .Lline_table_start0+47  # DW_AT_stmt_list
+3:
+        .byte   2                       # Abbrev [2] 0x1e:0xc DW_TAG_structure_type
+        .long   .LD                     # DW_AT_name
+        .byte   4                       # DW_AT_byte_size
+        .byte   1                       # DW_AT_decl_file
+        .byte   4                       # DW_AT_decl_line
+        .byte   0                       # End Of Children Mark
+4:
+
+# Type unit five: "struct E".
+# DW_AT_decl_file invalid
+# CHECK-DAG: name = "E", size = 4, line = 5
+1:
+        .long   4f-2f                   # Length of Unit
+2:
+        .short  4                       # DWARF version number
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .quad   5390450678491038988     # Type Signature
+        .long   3f-1b                   # Type DIE Offset
+        .byte   1                       # Abbrev [1] 0x17:0x1b DW_TAG_type_unit
+        .short  4                       # DW_AT_language
+        .long   .Lline_table_start0     # DW_AT_stmt_list
+3:
+        .byte   2                       # Abbrev [2] 0x1e:0xc DW_TAG_structure_type
+        .long   .LE                     # DW_AT_name
+        .byte   4                       # DW_AT_byte_size
+        .byte   47                      # DW_AT_decl_file
+        .byte   5                       # DW_AT_decl_line
+        .byte   0                       # End Of Children Mark
+4:
+
+
+        .section        .debug_str,"MS",@progbits,1
+.LA:
+        .asciz  "A"
+.LB:
+        .asciz  "B"
+.LC:
+        .asciz  "C"
+.LD:
+        .asciz  "D"
+.LE:
+        .asciz  "E"
+
+        .section        .debug_abbrev,"",@progbits
+        .byte   1                       # Abbreviation Code
+        .byte   65                      # DW_TAG_type_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   19                      # DW_AT_language
+        .byte   5                       # DW_FORM_data2
+        .byte   16                      # DW_AT_stmt_list
+        .byte   23                      # DW_FORM_sec_offset
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   2                       # Abbreviation Code
+        .byte   19                      # DW_TAG_structure_type
+        .byte   0                       # DW_CHILDREN_no
+        .byte   3                       # DW_AT_name
+        .byte   14                      # DW_FORM_strp
+        .byte   11                      # DW_AT_byte_size
+        .byte   11                      # DW_FORM_data1
+        .byte   58                      # DW_AT_decl_file
+        .byte   11                      # DW_FORM_data1
+        .byte   59                      # DW_AT_decl_line
+        .byte   11                      # DW_FORM_data1
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   3                       # Abbreviation Code
+        .byte   65                      # DW_TAG_type_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   19                      # DW_AT_language
+        .byte   5                       # DW_FORM_data2
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   4                       # Abbreviation Code
+        .byte   17                      # DW_TAG_compile_unit
+        .byte   1                       # DW_CHILDREN_yes
+        .byte   0                       # EOM(1)
+        .byte   0                       # EOM(2)
+        .byte   0                       # EOM(3)
+        .section        .debug_info,"",@progbits
+.Lcu_begin0:
+        .long   .Ldebug_info_end1-.Ldebug_info_start1 # Length of Unit
+.Ldebug_info_start1:
+        .short  4                       # DWARF version number
+        .long   .debug_abbrev           # Offset Into Abbrev. Section
+        .byte   8                       # Address Size (in bytes)
+        .byte   4                       # Abbrev [4] 0xb:0x32 DW_TAG_compile_unit
+        .byte   0                       # End Of Children Mark
+.Ldebug_info_end1:
+
+        .section        .debug_line,"",@progbits
+.Lline_table_start0:
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to