labath created this revision.
labath added reviewers: clayborg, aprantl, JDevlieghere.
Herald added a subscriber: jdoerfert.

This patch creates a cache of file lists in line tables referenced by
type units.  This cache is used to avoid parsing a line table twice
(since a file list will generally be shared by many type units).

It also sets things up in a way that parsing of DW_AT_decl_file
attributes will keep working even when we stop creating lldb compile
units for dwarf type units, but it stops short of actually doing that.
This means that the request for files now go directly to SymbolFileDWARF
instead of being routed there indirectly via the
lldb_private::CompileUnit class.

As a result of this, a number of occurences of SymbolContext variables
in DWARFASTParserClang have become unused, so I remove them.

This patch reduces the number of times a file list is being parsed, but
the situation is still suboptimal, as the parsed list is being copied
multiple times. This will be fixed when we stop creating CompileUnits
for DWARF type units.


https://reviews.llvm.org/D62894

Files:
  lit/SymbolFile/DWARF/debug-types-line-tables.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 GetSupportFile(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::GetSupportFile(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
@@ -145,6 +145,7 @@
   dw_addr_t GetAddrBase() const { return m_addr_base; }
   dw_addr_t GetRangesBase() const { return m_ranges_base; }
   dw_addr_t GetStrOffsetsBase() const { return m_str_offsets_base; }
+  dw_offset_t GetLineTableOffset();
   void SetAddrBase(dw_addr_t addr_base);
   void SetRangesBase(dw_addr_t ranges_base);
   void SetBaseObjOffset(dw_offset_t base_obj_offset);
@@ -210,6 +211,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.
@@ -283,6 +285,8 @@
   // in the main object file
   dw_offset_t m_base_obj_offset = DW_INVALID_OFFSET;
   dw_offset_t m_str_offsets_base = 0; // Value of DW_AT_str_offsets_base.
+  dw_offset_t m_line_table_offset =
+      DW_INVALID_OFFSET; // Value of DW_AT_stmt_list.
   const DIERef::Section m_section;
 
 private:
Index: source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
===================================================================
--- source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -302,6 +302,9 @@
     base_addr = cu_die.GetAttributeValueAsAddress(this, DW_AT_entry_pc, 0);
   SetBaseAddress(base_addr);
 
+  m_line_table_offset = cu_die.GetAttributeValueAsUnsigned(
+      this, DW_AT_stmt_list, DW_INVALID_OFFSET);
+
   std::unique_ptr<SymbolFileDWARFDwo> dwo_symbol_file =
       m_dwarf->GetDwoSymbolFileForCompileUnit(*this, cu_die);
   if (!dwo_symbol_file)
@@ -387,6 +390,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) {
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()->GetSupportFile(*die.GetCU(), form_value.Unsigned()));
       break;
     case DW_AT_decl_line:
       decl.SetLine(form_value.Unsigned());
@@ -385,6 +384,18 @@
   }
 }
 
+static std::string GetUnitName(const DWARFDIE &die) {
+  std::string result = "the source file";
+  DWARFUnit *unit = die.GetCU();
+  if (!unit)
+    return result;
+  if (FileSpec spec =
+          unit->GetCompilationDirectory().CopyByAppendingPathComponent(
+              unit->GetUnitDIEOnly().GetName()))
+    return spec.GetPath();
+  return result;
+}
+
 TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
                                                const DWARFDIE &die, Log *log,
                                                bool *type_is_new_ptr) {
@@ -416,7 +427,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 +1118,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 +1184,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 +1474,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 +1582,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 +1671,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 +1973,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 +1980,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 +2171,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 +2223,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 +2263,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()->GetSupportFile(
+                  *die.GetCU(), form_value.Unsigned()));
               break;
             case DW_AT_decl_line:
               decl.SetLine(form_value.Unsigned());
@@ -2393,9 +2398,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)
@@ -2416,8 +2421,8 @@
       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));
+            die.GetDWARF()->GetSupportFile(*die.GetCU(), decl_file), decl_line,
+            decl_column));
 
       SymbolFileDWARF *dwarf = die.GetDWARF();
       // Supply the type _only_ if it has already been parsed
@@ -2446,8 +2451,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 +2711,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 +2869,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 +3066,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/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