summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/lit/SymbolFile/DWARF/debug-types-line-tables.s185
-rw-r--r--lldb/lit/SymbolFile/DWARF/forward-declarations.s111
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp80
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h9
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp7
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h4
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp105
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h12
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp61
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h7
12 files changed, 480 insertions, 105 deletions
diff --git a/lldb/lit/SymbolFile/DWARF/debug-types-line-tables.s b/lldb/lit/SymbolFile/DWARF/debug-types-line-tables.s
new file mode 100644
index 00000000000..888c36afbf4
--- /dev/null
+++ b/lldb/lit/SymbolFile/DWARF/debug-types-line-tables.s
@@ -0,0 +1,185 @@
+# REQUIRES: x86
+
+# 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:
diff --git a/lldb/lit/SymbolFile/DWARF/forward-declarations.s b/lldb/lit/SymbolFile/DWARF/forward-declarations.s
new file mode 100644
index 00000000000..952c4ee7f87
--- /dev/null
+++ b/lldb/lit/SymbolFile/DWARF/forward-declarations.s
@@ -0,0 +1,111 @@
+# Test handling of the situation (including the error message) where a structure
+# has a incomplete member.
+
+# REQUIRES: x86
+
+# 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:
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index ceddac4dbf2..eb92a73a58b 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -233,7 +233,7 @@ namespace {
/// 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 @@ struct ParsedTypeAttributes {
};
} // 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,7 @@ ParsedTypeAttributes::ParsedTypeAttributes(const DWARFDIE &die,
break;
case DW_AT_decl_file:
- decl.SetFile(comp_unit.GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
+ decl.SetFile(die.GetCU()->GetFile(form_value.Unsigned()));
break;
case DW_AT_decl_line:
decl.SetLine(form_value.Unsigned());
@@ -385,6 +383,12 @@ ParsedTypeAttributes::ParsedTypeAttributes(const DWARFDIE &die,
}
}
+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 +420,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
// 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 +1111,9 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
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 +1177,10 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
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 +1467,6 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
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 +1575,7 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
"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 +1664,8 @@ TypeSP DWARFASTParserClang::ParseTypeFromDWARF(const SymbolContext &sc,
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 +1966,6 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
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 +1973,7 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
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 +2164,9 @@ bool DWARFASTParserClang::CompleteTypeFromDWARF(const DWARFDIE &die,
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 +2216,8 @@ DWARFASTParserClang::GetDeclContextContainingUIDFromDWARF(const DWARFDIE &die) {
}
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 +2256,7 @@ size_t DWARFASTParserClang::ParseChildEnumerators(
case DW_AT_description:
default:
case DW_AT_decl_file:
- decl.SetFile(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(
- form_value.Unsigned()));
+ decl.SetFile(die.GetCU()->GetFile(form_value.Unsigned()));
break;
case DW_AT_decl_line:
decl.SetLine(form_value.Unsigned());
@@ -2393,9 +2390,9 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
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 +2412,8 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
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.GetCU()->GetFile(decl_file),
+ decl_line, decl_column));
SymbolFileDWARF *dwarf = die.GetDWARF();
// Supply the type _only_ if it has already been parsed
@@ -2446,8 +2442,8 @@ Function *DWARFASTParserClang::ParseFunctionFromDWARF(CompileUnit &comp_unit,
}
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 +2702,12 @@ bool DWARFASTParserClang::ParseChildMembers(
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 +2860,7 @@ bool DWARFASTParserClang::ParseChildMembers(
"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 +3057,9 @@ bool DWARFASTParserClang::ParseChildMembers(
}
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)
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
index e561ac5b3b8..5b5d83d6593 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.h
@@ -81,8 +81,7 @@ protected:
&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 @@ protected:
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 @@ protected:
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);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
index 0722e63a1c2..4c18dc58506 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.cpp
@@ -90,13 +90,6 @@ lldb::ModuleSP DWARFBaseDIE::GetModule() const {
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();
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
index 1c81131829e..ad56a4f2586 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFBaseDIE.h
@@ -101,8 +101,6 @@ public:
lldb::ModuleSP GetModule() const;
- lldb_private::CompileUnit *GetLLDBCompileUnit() const;
-
// Getting attribute values from the DIE.
//
// GetAttributeValueAsXXX() functions should only be used if you are
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
index dc5fe25b40f..307b88c77a8 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h
@@ -18,6 +18,8 @@ public:
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,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
index aaf94df96b3..3c75c34bd4a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFTypeUnit.h
@@ -22,9 +22,7 @@ public:
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,
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
index aadbe65b19c..94a9f45798e 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp
@@ -283,24 +283,47 @@ static void SetDwoStrOffsetsBase(DWARFUnit *dwo_cu) {
// 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 @@ void DWARFUnit::AddUnitDIE(const DWARFDebugInfoEntry &cu_die) {
// 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 @@ dw_offset_t DWARFUnit::GetAbbrevOffset() const {
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,16 @@ const FileSpec &DWARFUnit::GetCompilationDirectory() {
return *m_comp_dir;
}
+const FileSpec &DWARFUnit::GetAbsolutePath() {
+ if (!m_file_spec)
+ ComputeAbsolutePath();
+ return *m_file_spec;
+}
+
+FileSpec DWARFUnit::GetFile(size_t file_idx) {
+ return m_dwarf->GetFile(*this, file_idx);
+}
+
// DWARF2/3 suggests the form hostname:pathname for compilation directory.
// Remove the host part if present.
static llvm::StringRef
@@ -670,6 +707,20 @@ void DWARFUnit::ComputeCompDirAndGuessPathStyle() {
}
}
+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();
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
index 73f4d2ea3e0..26a658669d7 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h
@@ -141,8 +141,9 @@ public:
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,8 @@ public:
bool GetIsOptimized();
const lldb_private::FileSpec &GetCompilationDirectory();
+ const lldb_private::FileSpec &GetAbsolutePath();
+ lldb_private::FileSpec GetFile(size_t file_idx);
lldb_private::FileSpec::Style GetPathStyle();
SymbolFileDWARFDwo *GetDwoSymbolFile() const;
@@ -210,6 +213,7 @@ public:
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 +281,16 @@ protected:
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 +302,7 @@ private:
void AddUnitDIE(const DWARFDebugInfoEntry &cu_die);
void ComputeCompDirAndGuessPathStyle();
+ void ComputeAbsolutePath();
DISALLOW_COPY_AND_ASSIGN(DWARFUnit);
};
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 0ae204e2272..7bc46954309 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/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 @@ size_t SymbolFileDWARF::ParseFunctions(CompileUnit &comp_unit) {
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);
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 1b13b06d70c..b56089d052a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -49,6 +49,7 @@ class DWARFDebugLine;
class DWARFDebugRangesBase;
class DWARFDeclContext;
class DWARFFormValue;
+class DWARFTypeUnit;
class SymbolFileDWARFDebugMap;
class SymbolFileDWARFDwo;
class SymbolFileDWARFDwp;
@@ -299,6 +300,8 @@ public:
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 @@ protected:
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 @@ protected:
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_
OpenPOWER on IntegriCloud