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: 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> &base_classes, std::vector &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 &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( 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> bases; std::vector member_accessibilities; bool is_a_class = false; @@ -1974,7 +1980,7 @@ std::vector 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 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> &base_classes, std::vector &member_accessibilities, std::vector &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 &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 &function_param_types, std::vector &function_param_decls, unsigned &type_quals) { if (!parent_die) 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/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/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/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 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/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 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 + 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(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::getEmptyKey() || + offset == llvm::DenseMapInfo::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);