diff options
Diffstat (limited to 'source/Plugins/SymbolFile/DWARF')
11 files changed, 591 insertions, 362 deletions
diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp index 8935f7143e48..75934f966bcd 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.cpp @@ -51,6 +51,7 @@ DWARFCompileUnit::DWARFCompileUnit(SymbolFileDWARF* dwarf2Data) : m_producer_version_major (0), m_producer_version_minor (0), m_producer_version_update (0), + m_language_type (eLanguageTypeUnknown), m_is_dwarf64 (false) { } @@ -68,6 +69,7 @@ DWARFCompileUnit::Clear() m_func_aranges_ap.reset(); m_user_data = NULL; m_producer = eProducerInvalid; + m_language_type = eLanguageTypeUnknown; m_is_dwarf64 = false; } @@ -444,6 +446,31 @@ DWARFCompileUnit::BuildAddressRangeTable (SymbolFileDWARF* dwarf2Data, } } + if (debug_aranges->IsEmpty()) + { + // We got nothing from the functions, maybe we have a line tables only + // situation. Check the line tables and build the arange table from this. + SymbolContext sc; + sc.comp_unit = dwarf2Data->GetCompUnitForDWARFCompUnit(this); + if (sc.comp_unit) + { + LineTable *line_table = sc.comp_unit->GetLineTable(); + + if (line_table) + { + LineTable::FileAddressRanges file_ranges; + const bool append = true; + const size_t num_ranges = line_table->GetContiguousFileAddressRanges (file_ranges, append); + for (uint32_t idx=0; idx<num_ranges; ++idx) + { + const LineTable::FileAddressRanges::Entry &range = file_ranges.GetEntryRef(idx); + debug_aranges->AppendRange(GetOffset(), range.GetRangeBase(), range.GetRangeEnd()); + printf ("0x%8.8x: [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n", GetOffset(), range.GetRangeBase(), range.GetRangeEnd()); + } + } + } + } + // Keep memory down by clearing DIEs if this generate function // caused them to be parsed if (clear_dies) @@ -1042,6 +1069,35 @@ DWARFCompileUnit::GetProducerVersionUpdate() return m_producer_version_update; } +LanguageType +DWARFCompileUnit::LanguageTypeFromDWARF(uint64_t val) +{ + // Note: user languages between lo_user and hi_user + // must be handled explicitly here. + switch (val) + { + case DW_LANG_Mips_Assembler: + return eLanguageTypeMipsAssembler; + case 0x8e57: // FIXME: needs to be added to llvm + return eLanguageTypeExtRenderScript; + default: + return static_cast<LanguageType>(val); + } +} + +LanguageType +DWARFCompileUnit::GetLanguageType() +{ + if (m_language_type != eLanguageTypeUnknown) + return m_language_type; + + const DWARFDebugInfoEntry *die = GetCompileUnitDIEOnly(); + if (die) + m_language_type = LanguageTypeFromDWARF( + die->GetAttributeValueAsUnsigned(m_dwarf2Data, this, DW_AT_language, 0)); + return m_language_type; +} + bool DWARFCompileUnit::IsDWARF64() const { diff --git a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h index 3e904892dbd5..93c8df822dcc 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFCompileUnit.h @@ -10,6 +10,7 @@ #ifndef SymbolFileDWARF_DWARFCompileUnit_h_ #define SymbolFileDWARF_DWARFCompileUnit_h_ +#include "lldb/lldb-enumerations.h" #include "DWARFDebugInfoEntry.h" #include "SymbolFileDWARF.h" @@ -186,6 +187,12 @@ public: uint32_t GetProducerVersionUpdate(); + static lldb::LanguageType + LanguageTypeFromDWARF(uint64_t val); + + lldb::LanguageType + GetLanguageType(); + bool IsDWARF64() const; @@ -204,6 +211,7 @@ protected: uint32_t m_producer_version_major; uint32_t m_producer_version_minor; uint32_t m_producer_version_update; + lldb::LanguageType m_language_type; bool m_is_dwarf64; void diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 6a8c4e6d57b9..0ad1f1a3a95a 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -1582,17 +1582,21 @@ DWARFDebugInfoEntry::GetName DWARFFormValue form_value; if (GetAttributeValue(dwarf2Data, cu, DW_AT_name, form_value)) return form_value.AsCString(&dwarf2Data->get_debug_str_data()); - else + else if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) { - if (GetAttributeValue(dwarf2Data, cu, DW_AT_specification, form_value)) - { - DWARFCompileUnitSP cu_sp_ptr; - const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr); - if (die) - return die->GetName(dwarf2Data, cu_sp_ptr.get()); - } + DWARFCompileUnitSP cu_sp_ptr; + const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr); + if (die) + return die->GetName(dwarf2Data, cu_sp_ptr.get()); } - return NULL; + else if (GetAttributeValue(dwarf2Data, cu, DW_AT_abstract_origin, form_value)) + { + DWARFCompileUnitSP cu_sp_ptr; + const DWARFDebugInfoEntry* die = const_cast<SymbolFileDWARF*>(dwarf2Data)->DebugInfo()->GetDIEPtr(form_value.Reference(), &cu_sp_ptr); + if (die) + return die->GetName(dwarf2Data, cu_sp_ptr.get()); + } + return nullptr; } diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp index 11589aede708..48e11bd80089 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFDebugLine.cpp @@ -488,7 +488,6 @@ DWARFDebugLine::ParseSupportFiles (const lldb::ModuleSP &module_sp, lldb::offset_t offset = stmt_list; // Skip the total length (void)debug_line_data.GetDWARFInitialLength(&offset); - const char * s; uint32_t version = debug_line_data.GetU16(&offset); if (version < 2 || version > 4) return false; @@ -502,68 +501,38 @@ DWARFDebugLine::ParseSupportFiles (const lldb::ModuleSP &module_sp, // Skip opcode base, and all opcode lengths const uint8_t opcode_base = debug_line_data.GetU8(&offset); offset += opcode_base - 1; - std::vector<std::string> include_directories; - include_directories.push_back(""); // Directory at index zero doesn't exist + std::vector<FileSpec> include_directories{{}}; // Directory at index zero doesn't exist while (offset < end_prologue_offset) { - s = debug_line_data.GetCStr(&offset); - if (s && s[0]) - include_directories.push_back(s); + FileSpec dir{debug_line_data.GetCStr(&offset), false}; + if (dir) + include_directories.emplace_back(std::move(dir)); else break; } - std::string fullpath; - std::string remapped_fullpath; while (offset < end_prologue_offset) { - const char* path = debug_line_data.GetCStr( &offset ); - if (path && path[0]) + FileSpec file_spec{debug_line_data.GetCStr(&offset), false}; + if (file_spec) { - uint32_t dir_idx = debug_line_data.GetULEB128( &offset ); + uint32_t dir_idx = debug_line_data.GetULEB128(&offset); debug_line_data.Skip_LEB128(&offset); // Skip mod_time debug_line_data.Skip_LEB128(&offset); // Skip length - if (path[0] == '/') - { - // The path starts with a directory delimiter, so we are done. - if (module_sp->RemapSourceFile (path, fullpath)) - support_files.Append(FileSpec (fullpath.c_str(), false)); - else - support_files.Append(FileSpec (path, false)); - } - else + if (file_spec.IsRelative()) { - if (dir_idx > 0 && dir_idx < include_directories.size()) - { - if (cu_comp_dir && include_directories[dir_idx][0] != '/') - { - fullpath = cu_comp_dir; - - if (*fullpath.rbegin() != '/') - fullpath += '/'; - fullpath += include_directories[dir_idx]; - - } - else - fullpath = include_directories[dir_idx]; - } - else if (cu_comp_dir && cu_comp_dir[0]) + if (0 < dir_idx && dir_idx < include_directories.size()) { - fullpath = cu_comp_dir; + const FileSpec &dir = include_directories[dir_idx]; + file_spec.PrependPathComponent(dir); } - - if (!fullpath.empty()) - { - if (*fullpath.rbegin() != '/') - fullpath += '/'; - } - fullpath += path; - if (module_sp->RemapSourceFile (fullpath.c_str(), remapped_fullpath)) - support_files.Append(FileSpec (remapped_fullpath.c_str(), false)); - else - support_files.Append(FileSpec (fullpath.c_str(), false)); + if (file_spec.IsRelative()) + file_spec.PrependPathComponent(cu_comp_dir); } - + std::string remapped_file; + if (module_sp->RemapSourceFile(file_spec.GetCString(), remapped_file)) + file_spec.SetFile(remapped_file, false); + support_files.Append(file_spec); } } diff --git a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h index 2be5d90c37b2..3a99d2b33878 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h +++ b/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.h @@ -100,6 +100,14 @@ public: const char * GetQualifiedName () const; + // Same as GetQaulifiedName, but the life time of the returned string will + // be that of the LLDB session. + lldb_private::ConstString + GetQualifiedNameAsConstString () const + { + return lldb_private::ConstString (GetQualifiedName ()); + } + protected: typedef std::vector<Entry> collection; collection m_entries; diff --git a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index a8c550e9176f..c733832e4f4d 100644 --- a/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -191,7 +191,7 @@ DWARFFormValue::ExtractValue(const DWARFDataExtractor& data, lldb::offset_t* off // Set the string value to also be the data for inlined cstr form values only // so we can tell the difference between DW_FORM_string and DW_FORM_strp form // values; - m_value.data = (uint8_t*)m_value.value.cstr; break; + m_value.data = (const uint8_t*)m_value.value.cstr; break; case DW_FORM_exprloc: case DW_FORM_block: m_value.value.uval = data.GetULEB128(offset_ptr); is_block = true; break; case DW_FORM_block1: m_value.value.uval = data.GetU8(offset_ptr); is_block = true; break; diff --git a/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index e4626900d816..c49237b8fbbc 100644 --- a/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -69,7 +69,7 @@ NameToDIE::Dump (Stream *s) for (uint32_t i=0; i<size; ++i) { const char *cstr = m_map.GetCStringAtIndex(i); - s->Printf("%p: {0x%8.8x} \"%s\"\n", cstr, m_map.GetValueAtIndexUnchecked(i), cstr); + s->Printf("%p: {0x%8.8x} \"%s\"\n", (const void *)cstr, m_map.GetValueAtIndexUnchecked(i), cstr); } } diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 7ba4f52ac297..dafd389449a2 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -26,7 +26,10 @@ #include "llvm/Support/Casting.h" +#include "lldb/Core/ArchSpec.h" #include "lldb/Core/Module.h" +#include "lldb/Core/ModuleList.h" +#include "lldb/Core/ModuleSpec.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/RegularExpression.h" #include "lldb/Core/Scalar.h" @@ -36,6 +39,8 @@ #include "lldb/Core/Timer.h" #include "lldb/Core/Value.h" +#include "lldb/Expression/ClangModulesDeclVendor.h" + #include "lldb/Host/Host.h" #include "lldb/Symbol/Block.h" @@ -515,6 +520,7 @@ SymbolFileDWARF::SymbolFileDWARF(ObjectFile* objfile) : m_indexed (false), m_is_external_ast_source (false), m_using_apple_tables (false), + m_fetched_external_modules (false), m_supports_DW_AT_APPLE_objc_complete_type (eLazyBoolCalculate), m_ranges(), m_unique_ast_type_map () @@ -966,39 +972,25 @@ SymbolFileDWARF::ParseCompileUnit (DWARFCompileUnit* dwarf_cu, uint32_t cu_idx) const DWARFDebugInfoEntry * cu_die = dwarf_cu->GetCompileUnitDIEOnly (); if (cu_die) { - const char * cu_die_name = cu_die->GetName(this, dwarf_cu); - const char * cu_comp_dir = cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, NULL); - LanguageType cu_language = (LanguageType)cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0); - if (cu_die_name) + FileSpec cu_file_spec{cu_die->GetName(this, dwarf_cu), false}; + if (cu_file_spec) { - std::string ramapped_file; - FileSpec cu_file_spec; - - if (cu_die_name[0] == '/' || cu_comp_dir == NULL || cu_comp_dir[0] == '\0') - { - // If we have a full path to the compile unit, we don't need to resolve - // the file. This can be expensive e.g. when the source files are NFS mounted. - if (module_sp->RemapSourceFile(cu_die_name, ramapped_file)) - cu_file_spec.SetFile (ramapped_file.c_str(), false); - else - cu_file_spec.SetFile (cu_die_name, false); - } - else + // If we have a full path to the compile unit, we don't need to resolve + // the file. This can be expensive e.g. when the source files are NFS mounted. + if (cu_file_spec.IsRelative()) { // DWARF2/3 suggests the form hostname:pathname for compilation directory. // Remove the host part if present. - cu_comp_dir = removeHostnameFromPathname(cu_comp_dir); - std::string fullpath(cu_comp_dir); - - if (*fullpath.rbegin() != '/') - fullpath += '/'; - fullpath += cu_die_name; - if (module_sp->RemapSourceFile (fullpath.c_str(), ramapped_file)) - cu_file_spec.SetFile (ramapped_file.c_str(), false); - else - cu_file_spec.SetFile (fullpath.c_str(), false); + const char *cu_comp_dir{cu_die->GetAttributeValueAsString(this, dwarf_cu, DW_AT_comp_dir, nullptr)}; + cu_file_spec.PrependPathComponent(removeHostnameFromPathname(cu_comp_dir)); } + std::string remapped_file; + if (module_sp->RemapSourceFile(cu_file_spec.GetCString(), remapped_file)) + cu_file_spec.SetFile(remapped_file, false); + + LanguageType cu_language = DWARFCompileUnit::LanguageTypeFromDWARF(cu_die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0)); + cu_sp.reset(new CompileUnit (module_sp, dwarf_cu, cu_file_spec, @@ -1095,7 +1087,54 @@ SymbolFileDWARF::ParseCompileUnitFunction (const SymbolContext& sc, DWARFCompile Mangled func_name; if (mangled) func_name.SetValue(ConstString(mangled), true); - else if (name) + else if (die->GetParent()->Tag() == DW_TAG_compile_unit && + LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType()) && + name && strcmp(name, "main") != 0) + { + // If the mangled name is not present in the DWARF, generate the demangled name + // using the decl context. We skip if the function is "main" as its name is + // never mangled. + bool is_static = false; + bool is_variadic = false; + unsigned type_quals = 0; + std::vector<ClangASTType> param_types; + std::vector<clang::ParmVarDecl*> param_decls; + const DWARFDebugInfoEntry *decl_ctx_die = NULL; + DWARFDeclContext decl_ctx; + StreamString sstr; + + die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx); + sstr << decl_ctx.GetQualifiedName(); + + clang::DeclContext *containing_decl_ctx = GetClangDeclContextContainingDIE(dwarf_cu, + die, + &decl_ctx_die); + ParseChildParameters(sc, + containing_decl_ctx, + dwarf_cu, + die, + true, + is_static, + is_variadic, + param_types, + param_decls, + type_quals); + sstr << "("; + for (size_t i = 0; i < param_types.size(); i++) + { + if (i > 0) + sstr << ", "; + sstr << param_types[i].GetTypeName(); + } + if (is_variadic) + sstr << ", ..."; + sstr << ")"; + if (type_quals & clang::Qualifiers::Const) + sstr << " const"; + + func_name.SetValue(ConstString(sstr.GetData()), false); + } + else func_name.SetValue(ConstString(name), false); FunctionSP func_sp; @@ -1153,11 +1192,7 @@ SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc) { const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly(); if (die) - { - const uint32_t language = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0); - if (language) - return (lldb::LanguageType)language; - } + return DWARFCompileUnit::LanguageTypeFromDWARF(die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_language, 0)); } return eLanguageTypeUnknown; } @@ -1216,6 +1251,25 @@ SymbolFileDWARF::ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpec return false; } +bool +SymbolFileDWARF::ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules) +{ + assert (sc.comp_unit); + DWARFCompileUnit* dwarf_cu = GetDWARFCompileUnit(sc.comp_unit); + if (dwarf_cu) + { + if (ClangModulesDeclVendor::LanguageSupportsClangModules(sc.comp_unit->GetLanguage())) + { + UpdateExternalModuleListIfNeeded(); + for (const std::pair<uint64_t, const ClangModuleInfo> &external_type_module : m_external_type_modules) + { + imported_modules.push_back(external_type_module.second.m_name); + } + } + } + return false; +} + struct ParseDWARFLineTableCallbackInfo { LineTable* line_table; @@ -2073,8 +2127,9 @@ SymbolFileDWARF::ParseChildMembers GetClangASTContext().GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, word_width), accessibility, anon_field_info.bit_size); - - layout_info.field_offsets.insert(std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset)); + + layout_info.field_offsets.insert( + std::make_pair(unnamed_bitfield_decl, anon_field_info.bit_offset)); } } last_field_info = this_field_info; @@ -2124,9 +2179,8 @@ SymbolFileDWARF::ParseChildMembers bit_size); GetClangASTContext().SetMetadataAsUserID (field_decl, MakeUserID(die->GetOffset())); - - layout_info.field_offsets.insert(std::make_pair(field_decl, field_bit_offset)); + layout_info.field_offsets.insert(std::make_pair(field_decl, field_bit_offset)); } else { @@ -2261,8 +2315,15 @@ SymbolFileDWARF::ParseChildMembers } Type *base_class_type = ResolveTypeUID(encoding_uid); - assert(base_class_type); - + if (base_class_type == NULL) + { + GetObjectFile()->GetModule()->ReportError("0x%8.8x: DW_TAG_inheritance failed to resolve the base class at 0x%8.8" PRIx64 " from enclosing type 0x%8.8x. \nPlease file a bug and attach the file at the start of this error message", + die->GetOffset(), + encoding_uid, + parent_die->GetOffset()); + break; + } + ClangASTType base_class_clang_type = base_class_type->GetClangFullType(); assert (base_class_clang_type); if (class_language == eLanguageTypeObjC) @@ -2287,8 +2348,9 @@ SymbolFileDWARF::ParseChildMembers } else { - layout_info.base_offsets.insert(std::make_pair(base_class_clang_type.GetAsCXXRecordDecl(), - clang::CharUnits::fromQuantity(member_byte_offset))); + layout_info.base_offsets.insert( + std::make_pair(base_class_clang_type.GetAsCXXRecordDecl(), + clang::CharUnits::fromQuantity(member_byte_offset))); } } } @@ -2671,41 +2733,44 @@ SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (ClangASTType &clang_type) uint32_t idx; { - llvm::DenseMap <const clang::FieldDecl *, uint64_t>::const_iterator pos, end = layout_info.field_offsets.end(); - for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx) + llvm::DenseMap<const clang::FieldDecl *, uint64_t>::const_iterator pos, + end = layout_info.field_offsets.end(); + for (idx = 0, pos = layout_info.field_offsets.begin(); pos != end; ++pos, ++idx) { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = { bit_offset=%u, name='%s' }", - static_cast<void*>(clang_type.GetOpaqueQualType()), - idx, - static_cast<uint32_t>(pos->second), - pos->first->getNameAsString().c_str()); + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) field[%u] = " + "{ bit_offset=%u, name='%s' }", + static_cast<void *>(clang_type.GetOpaqueQualType()), idx, + static_cast<uint32_t>(pos->second), pos->first->getNameAsString().c_str()); } } { - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos, base_end = layout_info.base_offsets.end(); - for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end; ++base_pos, ++idx) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] = { byte_offset=%u, name='%s' }", - clang_type.GetOpaqueQualType(), - idx, - (uint32_t)base_pos->second.getQuantity(), - base_pos->first->getNameAsString().c_str()); - } + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator base_pos, + base_end = layout_info.base_offsets.end(); + for (idx = 0, base_pos = layout_info.base_offsets.begin(); base_pos != base_end; + ++base_pos, ++idx) + { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) base[%u] " + "= { byte_offset=%u, name='%s' }", + clang_type.GetOpaqueQualType(), idx, (uint32_t)base_pos->second.getQuantity(), + base_pos->first->getNameAsString().c_str()); + } } { - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos, vbase_end = layout_info.vbase_offsets.end(); - for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end; ++vbase_pos, ++idx) - { - GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) vbase[%u] = { byte_offset=%u, name='%s' }", - static_cast<void*>(clang_type.GetOpaqueQualType()), - idx, - static_cast<uint32_t>(vbase_pos->second.getQuantity()), - vbase_pos->first->getNameAsString().c_str()); - } + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits>::const_iterator vbase_pos, + vbase_end = layout_info.vbase_offsets.end(); + for (idx = 0, vbase_pos = layout_info.vbase_offsets.begin(); vbase_pos != vbase_end; + ++vbase_pos, ++idx) + { + GetObjectFile()->GetModule()->LogMessage( + log, "SymbolFileDWARF::ResolveClangOpaqueTypeDefinition (clang_type = %p) " + "vbase[%u] = { byte_offset=%u, name='%s' }", + static_cast<void *>(clang_type.GetOpaqueQualType()), idx, + static_cast<uint32_t>(vbase_pos->second.getQuantity()), + vbase_pos->first->getNameAsString().c_str()); + } } } m_record_decl_to_layout_map.insert(std::make_pair(record_decl, layout_info)); @@ -2794,7 +2859,60 @@ SymbolFileDWARF::GetFunction (DWARFCompileUnit* dwarf_cu, const DWARFDebugInfoEn return false; } - +void +SymbolFileDWARF::UpdateExternalModuleListIfNeeded() +{ + if (m_fetched_external_modules) + return; + m_fetched_external_modules = true; + + DWARFDebugInfo * debug_info = DebugInfo(); + debug_info->GetNumCompileUnits(); + + const uint32_t num_compile_units = GetNumCompileUnits(); + for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx) + { + DWARFCompileUnit* dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx); + + const DWARFDebugInfoEntry *die = dwarf_cu->GetCompileUnitDIEOnly(); + if (die && die->HasChildren() == false) + { + const uint64_t name_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_name, UINT64_MAX); + const uint64_t dwo_path_strp = die->GetAttributeValueAsUnsigned(this, dwarf_cu, DW_AT_GNU_dwo_name, UINT64_MAX); + + if (name_strp != UINT64_MAX) + { + if (m_external_type_modules.find(dwo_path_strp) == m_external_type_modules.end()) + { + const char *name = get_debug_str_data().PeekCStr(name_strp); + const char *dwo_path = get_debug_str_data().PeekCStr(dwo_path_strp); + if (name || dwo_path) + { + ModuleSP module_sp; + if (dwo_path) + { + ModuleSpec dwo_module_spec; + dwo_module_spec.GetFileSpec().SetFile(dwo_path, false); + dwo_module_spec.GetArchitecture() = m_obj_file->GetModule()->GetArchitecture(); + //printf ("Loading dwo = '%s'\n", dwo_path); + Error error = ModuleList::GetSharedModule (dwo_module_spec, module_sp, NULL, NULL, NULL); + } + + if (dwo_path_strp != LLDB_INVALID_UID) + { + m_external_type_modules[dwo_path_strp] = ClangModuleInfo { ConstString(name), module_sp }; + } + else + { + // This hack should be removed promptly once clang emits both. + m_external_type_modules[name_strp] = ClangModuleInfo { ConstString(name), module_sp }; + } + } + } + } + } + } +} SymbolFileDWARF::GlobalVariableMap & SymbolFileDWARF::GetGlobalAranges() @@ -3455,16 +3573,18 @@ SymbolFileDWARF::FindGlobalVariables(const RegularExpression& regex, bool append bool SymbolFileDWARF::ResolveFunction (dw_offset_t die_offset, DWARFCompileUnit *&dwarf_cu, + bool include_inlines, SymbolContextList& sc_list) { const DWARFDebugInfoEntry *die = DebugInfo()->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); - return ResolveFunction (dwarf_cu, die, sc_list); + return ResolveFunction (dwarf_cu, die, include_inlines, sc_list); } bool SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, + bool include_inlines, SymbolContextList& sc_list) { SymbolContext sc; @@ -3473,7 +3593,7 @@ SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu, return false; // If we were passed a die that is not a function, just return false... - if (die->Tag() != DW_TAG_subprogram && die->Tag() != DW_TAG_inlined_subroutine) + if (! (die->Tag() == DW_TAG_subprogram || (include_inlines && die->Tag() == DW_TAG_inlined_subroutine))) return false; const DWARFDebugInfoEntry* inlined_die = NULL; @@ -3520,12 +3640,13 @@ SymbolFileDWARF::ResolveFunction (DWARFCompileUnit *cu, void SymbolFileDWARF::FindFunctions (const ConstString &name, const NameToDIE &name_to_die, + bool include_inlines, SymbolContextList& sc_list) { DIEArray die_offsets; if (name_to_die.Find (name, die_offsets)) { - ParseFunctions (die_offsets, sc_list); + ParseFunctions (die_offsets, include_inlines, sc_list); } } @@ -3533,12 +3654,13 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, void SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, const NameToDIE &name_to_die, + bool include_inlines, SymbolContextList& sc_list) { DIEArray die_offsets; if (name_to_die.Find (regex, die_offsets)) { - ParseFunctions (die_offsets, sc_list); + ParseFunctions (die_offsets, include_inlines, sc_list); } } @@ -3546,6 +3668,7 @@ SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, void SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, const DWARFMappedHash::MemoryTable &memory_table, + bool include_inlines, SymbolContextList& sc_list) { DIEArray die_offsets; @@ -3553,24 +3676,23 @@ SymbolFileDWARF::FindFunctions (const RegularExpression ®ex, if (memory_table.AppendAllDIEsThatMatchingRegex (regex, hash_data_array)) { DWARFMappedHash::ExtractDIEArray (hash_data_array, die_offsets); - ParseFunctions (die_offsets, sc_list); + ParseFunctions (die_offsets, include_inlines, sc_list); } } void SymbolFileDWARF::ParseFunctions (const DIEArray &die_offsets, + bool include_inlines, SymbolContextList& sc_list) { const size_t num_matches = die_offsets.size(); if (num_matches) { - SymbolContext sc; - DWARFCompileUnit* dwarf_cu = NULL; for (size_t i=0; i<num_matches; ++i) { const dw_offset_t die_offset = die_offsets[i]; - ResolveFunction (die_offset, dwarf_cu, sc_list); + ResolveFunction (die_offset, dwarf_cu, include_inlines, sc_list); } } } @@ -3761,12 +3883,9 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) continue; - if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine) - continue; - if (resolved_dies.find(die) == resolved_dies.end()) { - if (ResolveFunction (dwarf_cu, die, sc_list)) + if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list)) resolved_dies.insert(die); } } @@ -3796,12 +3915,9 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, const char *die_name = die->GetName(this, dwarf_cu); if (ObjCLanguageRuntime::IsPossibleObjCMethodName(die_name)) { - if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine) - continue; - if (resolved_dies.find(die) == resolved_dies.end()) { - if (ResolveFunction (dwarf_cu, die, sc_list)) + if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list)) resolved_dies.insert(die); } } @@ -3830,15 +3946,12 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offset, &dwarf_cu); if (die) { - if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine) - continue; - if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) continue; // If we get to here, the die is good, and we should add it: if (resolved_dies.find(die) == resolved_dies.end()) - if (ResolveFunction (dwarf_cu, die, sc_list)) + if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list)) { bool keep_die = true; if ((name_type_mask & (eFunctionNameTypeBase|eFunctionNameTypeMethod)) != (eFunctionNameTypeBase|eFunctionNameTypeMethod)) @@ -3907,21 +4020,27 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, if (name_type_mask & eFunctionNameTypeFull) { - FindFunctions (name, m_function_fullname_index, sc_list); + FindFunctions (name, m_function_fullname_index, include_inlines, sc_list); // FIXME Temporary workaround for global/anonymous namespace - // functions on FreeBSD and Linux -#if defined (__FreeBSD__) || defined (__linux__) + // functions debugging FreeBSD and Linux binaries. // If we didn't find any functions in the global namespace try // looking in the basename index but ignore any returned - // functions that have a namespace (ie. mangled names starting with - // '_ZN') but keep functions which have an anonymous namespace + // functions that have a namespace but keep functions which + // have an anonymous namespace + // TODO: The arch in the object file isn't correct for MSVC + // binaries on windows, we should find a way to make it + // correct and handle those symbols as well. if (sc_list.GetSize() == 0) { - SymbolContextList temp_sc_list; - FindFunctions (name, m_function_basename_index, temp_sc_list); - if (!namespace_decl) + ArchSpec arch; + if (!namespace_decl && + GetObjectFile()->GetArchitecture(arch) && + (arch.GetTriple().isOSFreeBSD() || arch.GetTriple().isOSLinux() || + arch.GetMachine() == llvm::Triple::hexagon)) { + SymbolContextList temp_sc_list; + FindFunctions (name, m_function_basename_index, include_inlines, temp_sc_list); SymbolContext sc; for (uint32_t i = 0; i < temp_sc_list.GetSize(); i++) { @@ -3929,6 +4048,8 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, { ConstString mangled_name = sc.GetFunctionName(Mangled::ePreferMangled); ConstString demangled_name = sc.GetFunctionName(Mangled::ePreferDemangled); + // Mangled names on Linux and FreeBSD are of the form: + // _ZN18function_namespace13function_nameEv. if (strncmp(mangled_name.GetCString(), "_ZN", 3) || !strncmp(demangled_name.GetCString(), "(anonymous namespace)", 21)) { @@ -3938,7 +4059,6 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, } } } -#endif } DIEArray die_offsets; DWARFCompileUnit *dwarf_cu = NULL; @@ -3951,16 +4071,13 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu); if (die) { - if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine) - continue; - if (namespace_decl && !DIEIsInNamespace (namespace_decl, dwarf_cu, die)) continue; // If we get to here, the die is good, and we should add it: if (resolved_dies.find(die) == resolved_dies.end()) { - if (ResolveFunction (dwarf_cu, die, sc_list)) + if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list)) resolved_dies.insert(die); } } @@ -3980,13 +4097,10 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, const DWARFDebugInfoEntry* die = info->GetDIEPtrWithCompileUnitHint (die_offsets[i], &dwarf_cu); if (die) { - if (!include_inlines && die->Tag() == DW_TAG_inlined_subroutine) - continue; - // If we get to here, the die is good, and we should add it: if (resolved_dies.find(die) == resolved_dies.end()) { - if (ResolveFunction (dwarf_cu, die, sc_list)) + if (ResolveFunction (dwarf_cu, die, include_inlines, sc_list)) resolved_dies.insert(die); } } @@ -3997,7 +4111,7 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, if ((name_type_mask & eFunctionNameTypeSelector) && (!namespace_decl || !*namespace_decl)) { - FindFunctions (name, m_function_selector_index, sc_list); + FindFunctions (name, m_function_selector_index, include_inlines, sc_list); } } @@ -4008,9 +4122,10 @@ SymbolFileDWARF::FindFunctions (const ConstString &name, if (log && num_matches > 0) { GetObjectFile()->GetModule()->LogMessage (log, - "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, append=%u, sc_list) => %u", + "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, include_inlines=%d, append=%u, sc_list) => %u", name.GetCString(), name_type_mask, + include_inlines, append, num_matches); } @@ -4046,7 +4161,7 @@ SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inli if (m_using_apple_tables) { if (m_apple_names_ap.get()) - FindFunctions (regex, *m_apple_names_ap, sc_list); + FindFunctions (regex, *m_apple_names_ap, include_inlines, sc_list); } else { @@ -4054,9 +4169,9 @@ SymbolFileDWARF::FindFunctions(const RegularExpression& regex, bool include_inli if (!m_indexed) Index (); - FindFunctions (regex, m_function_basename_index, sc_list); + FindFunctions (regex, m_function_basename_index, include_inlines, sc_list); - FindFunctions (regex, m_function_fullname_index, sc_list); + FindFunctions (regex, m_function_fullname_index, include_inlines, sc_list); } // Return the number of variable that were appended to the list @@ -4309,7 +4424,6 @@ SymbolFileDWARF::ParseChildParameters (const SymbolContext& sc, bool skip_artificial, bool &is_static, bool &is_variadic, - TypeList* type_list, std::vector<ClangASTType>& function_param_types, std::vector<clang::ParmVarDecl*>& function_param_decls, unsigned &type_quals) // , @@ -6535,7 +6649,6 @@ SymbolFileDWARF::ParseType (const SymbolContext& sc, DWARFCompileUnit* dwarf_cu, skip_artificial, is_static, is_variadic, - type_list, function_param_types, function_param_decls, type_quals); @@ -7412,6 +7525,24 @@ SymbolFileDWARF::ParseVariableDIE dw_tag_t parent_tag = sc_parent_die ? sc_parent_die->Tag() : 0; SymbolContextScope * symbol_context_scope = NULL; + if (!mangled) + { + // LLDB relies on the mangled name (DW_TAG_linkage_name or DW_AT_MIPS_linkage_name) to + // generate fully qualified names of global variables with commands like "frame var j". + // For example, if j were an int variable holding a value 4 and declared in a namespace + // B which in turn is contained in a namespace A, the command "frame var j" returns + // "(int) A::B::j = 4". If the compiler does not emit a linkage name, we should be able + // to generate a fully qualified name from the declaration context. + if (die->GetParent()->Tag() == DW_TAG_compile_unit && + LanguageRuntime::LanguageIsCPlusPlus(dwarf_cu->GetLanguageType())) + { + DWARFDeclContext decl_ctx; + + die->GetDWARFDeclContext(this, dwarf_cu, decl_ctx); + mangled = decl_ctx.GetQualifiedNameAsConstString().GetCString(); + } + } + // DWARF doesn't specify if a DW_TAG_variable is a local, global // or static variable, so we have to do a little digging by // looking at the location of a variable to see if it contains @@ -7489,7 +7620,7 @@ SymbolFileDWARF::ParseVariableDIE { if (exe_symbol->ValueIsAddress()) { - const addr_t exe_file_addr = exe_symbol->GetAddress().GetFileAddress(); + const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress(); if (exe_file_addr != LLDB_INVALID_ADDRESS) { if (location.Update_DW_OP_addr (exe_file_addr)) @@ -7928,27 +8059,22 @@ SymbolFileDWARF::FindExternalVisibleDeclsByName (void *baton, } } -bool -SymbolFileDWARF::LayoutRecordType (void *baton, - const clang::RecordDecl *record_decl, - uint64_t &size, - uint64_t &alignment, - llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) +bool +SymbolFileDWARF::LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size, + uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) { SymbolFileDWARF *symbol_file_dwarf = (SymbolFileDWARF *)baton; return symbol_file_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets); } - -bool -SymbolFileDWARF::LayoutRecordType (const clang::RecordDecl *record_decl, - uint64_t &bit_size, - uint64_t &alignment, - llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) +bool +SymbolFileDWARF::LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) { Log *log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_INFO)); RecordDeclToLayoutMap::iterator pos = m_record_decl_to_layout_map.find (record_decl); diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index d8efdbcb38a4..2f0b3f05b153 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -103,6 +103,7 @@ public: virtual size_t ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc); virtual bool ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc); virtual bool ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList& support_files); + virtual bool ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules); virtual size_t ParseFunctionBlocks (const lldb_private::SymbolContext& sc); virtual size_t ParseTypes (const lldb_private::SymbolContext& sc); virtual size_t ParseVariablesForContext (const lldb_private::SymbolContext& sc); @@ -151,22 +152,15 @@ public: clang::DeclarationName Name, llvm::SmallVectorImpl <clang::NamedDecl *> *results); - static bool - LayoutRecordType (void *baton, - const clang::RecordDecl *record_decl, - uint64_t &size, - uint64_t &alignment, - llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); - - bool - LayoutRecordType (const clang::RecordDecl *record_decl, - uint64_t &size, - uint64_t &alignment, - llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); + static bool LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); + + bool LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); struct LayoutInfo { @@ -180,9 +174,9 @@ public: } uint64_t bit_size; uint64_t alignment; - llvm::DenseMap <const clang::FieldDecl *, uint64_t> field_offsets; - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> base_offsets; - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets; + llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets; + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets; + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets; }; //------------------------------------------------------------------ // PluginInterface protocol @@ -366,7 +360,6 @@ protected: bool skip_artificial, bool &is_static, bool &is_variadic, - lldb_private::TypeList* type_list, std::vector<lldb_private::ClangASTType>& function_args, std::vector<clang::ParmVarDecl*>& function_param_decls, unsigned &type_quals); @@ -393,10 +386,12 @@ protected: // Given a die_offset, figure out the symbol context representing that die. bool ResolveFunction (dw_offset_t offset, DWARFCompileUnit *&dwarf_cu, + bool include_inlines, lldb_private::SymbolContextList& sc_list); bool ResolveFunction (DWARFCompileUnit *cu, const DWARFDebugInfoEntry *die, + bool include_inlines, lldb_private::SymbolContextList& sc_list); bool FunctionDieMatchesPartialName ( @@ -410,16 +405,19 @@ protected: void FindFunctions( const lldb_private::ConstString &name, const NameToDIE &name_to_die, + bool include_inlines, lldb_private::SymbolContextList& sc_list); void FindFunctions ( const lldb_private::RegularExpression ®ex, const NameToDIE &name_to_die, + bool include_inlines, lldb_private::SymbolContextList& sc_list); void FindFunctions ( const lldb_private::RegularExpression ®ex, const DWARFMappedHash::MemoryTable &memory_table, + bool include_inlines, lldb_private::SymbolContextList& sc_list); lldb::TypeSP FindDefinitionTypeForDWARFDeclContext ( @@ -438,6 +436,7 @@ protected: lldb_private::Symbol * GetObjCClassSymbol (const lldb_private::ConstString &objc_class_name); void ParseFunctions (const DIEArray &die_offsets, + bool include_inlines, lldb_private::SymbolContextList& sc_list); lldb::TypeSP GetTypeForDIE (DWARFCompileUnit *cu, const DWARFDebugInfoEntry* die); @@ -549,6 +548,13 @@ protected: FixupAddress (lldb_private::Address &addr); typedef std::set<lldb_private::Type *> TypeSet; + + typedef struct { + lldb_private::ConstString m_name; + lldb::ModuleSP m_module_sp; + } ClangModuleInfo; + + typedef std::map<uint64_t, ClangModuleInfo> ExternalTypeModuleMap; void GetTypes (DWARFCompileUnit* dwarf_cu, @@ -562,6 +568,9 @@ protected: GlobalVariableMap & GetGlobalAranges(); + + void + UpdateExternalModuleListIfNeeded(); lldb::ModuleWP m_debug_map_module_wp; SymbolFileDWARFDebugMap * m_debug_map_symfile; @@ -591,6 +600,7 @@ protected: std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_namespaces_ap; std::unique_ptr<DWARFMappedHash::MemoryTable> m_apple_objc_ap; std::unique_ptr<GlobalVariableMap> m_global_aranges_ap; + ExternalTypeModuleMap m_external_type_modules; NameToDIE m_function_basename_index; // All concrete functions NameToDIE m_function_fullname_index; // All concrete functions NameToDIE m_function_method_index; // All inlined functions @@ -601,7 +611,8 @@ protected: NameToDIE m_namespace_index; // All type DIE offsets bool m_indexed:1, m_is_external_ast_source:1, - m_using_apple_tables:1; + m_using_apple_tables:1, + m_fetched_external_modules:1; lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type; std::unique_ptr<DWARFDebugRanges> m_ranges; diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index af16c03a8c07..5579a23ce716 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -121,8 +121,8 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa { // Add the inverse OSO file address to debug map entry mapping exe_symfile->AddOSOFileRange (this, - exe_symbol->GetAddress().GetFileAddress(), - oso_fun_symbol->GetAddress().GetFileAddress(), + exe_symbol->GetAddressRef().GetFileAddress(), + oso_fun_symbol->GetAddressRef().GetFileAddress(), std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize())); } @@ -155,8 +155,8 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa { // Add the inverse OSO file address to debug map entry mapping exe_symfile->AddOSOFileRange (this, - exe_symbol->GetAddress().GetFileAddress(), - oso_gsym_symbol->GetAddress().GetFileAddress(), + exe_symbol->GetAddressRef().GetFileAddress(), + oso_gsym_symbol->GetAddressRef().GetFileAddress(), std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize())); } } @@ -227,18 +227,11 @@ public: if (exe_objfile && exe_sym_vendor) { - if (oso_symfile->GetNumCompileUnits() == 1) - { - oso_symfile->SetDebugMapModule(exe_module_sp); - // Set the ID of the symbol file DWARF to the index of the OSO - // shifted left by 32 bits to provide a unique prefix for any - // UserID's that get created in the symbol file. - oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull); - } - else - { - oso_symfile->SetID (UINT64_MAX); - } + oso_symfile->SetDebugMapModule(exe_module_sp); + // Set the ID of the symbol file DWARF to the index of the OSO + // shifted left by 32 bits to provide a unique prefix for any + // UserID's that get created in the symbol file. + oso_symfile->SetID (((uint64_t)m_cu_idx + 1ull) << 32ull); } return symbol_vendor; } @@ -381,7 +374,7 @@ SymbolFileDWARFDebugMap::InitOSO() for (uint32_t sym_idx : m_func_indexes) { const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); - lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress(); + lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); lldb::addr_t byte_size = symbol->GetByteSize(); DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); m_debug_map.Append(debug_map_entry); @@ -389,7 +382,7 @@ SymbolFileDWARFDebugMap::InitOSO() for (uint32_t sym_idx : m_glob_indexes) { const Symbol *symbol = symtab->SymbolAtIndex(sym_idx); - lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress(); + lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress(); lldb::addr_t byte_size = symbol->GetByteSize(); DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS)); m_debug_map.Append(debug_map_entry); @@ -412,11 +405,11 @@ SymbolFileDWARFDebugMap::InitOSO() m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false); m_compile_unit_infos[i].oso_path = oso_symbol->GetName(); TimeValue oso_mod_time; - oso_mod_time.OffsetWithSeconds(oso_symbol->GetAddress().GetOffset()); + oso_mod_time.OffsetWithSeconds(oso_symbol->GetIntegerValue(0)); m_compile_unit_infos[i].oso_mod_time = oso_mod_time; uint32_t sibling_idx = so_symbol->GetSiblingIndex(); // The sibling index can't be less that or equal to the current index "i" - if (sibling_idx <= i) + if (sibling_idx == UINT32_MAX) { m_obj_file->GetModule()->ReportError ("N_SO in symbol with UID %u has invalid sibling in debug map, please file a bug and attach the binary listed in this error", so_symbol->GetID()); } @@ -743,6 +736,14 @@ SymbolFileDWARFDebugMap::ParseCompileUnitSupportFiles (const SymbolContext& sc, return false; } +bool +SymbolFileDWARFDebugMap::ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules) +{ + SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); + if (oso_dwarf) + return oso_dwarf->ParseImportedModules(sc, imported_modules); + return false; +} size_t SymbolFileDWARFDebugMap::ParseFunctionBlocks (const SymbolContext& sc) @@ -909,31 +910,33 @@ SymbolFileDWARFDebugMap::FindGlobalVariables (const ConstString &name, const Cla const uint32_t original_size = variables.GetSize(); uint32_t total_matches = 0; - SymbolFileDWARF *oso_dwarf; - for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) - { + + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (name, namespace_decl, - true, - max_matches, + true, + max_matches, variables); if (oso_matches > 0) { total_matches += oso_matches; - + // Are we getting all matches? if (max_matches == UINT32_MAX) - continue; // Yep, continue getting everything - + return false; // Yep, continue getting everything + // If we have found enough matches, lets get out if (max_matches >= total_matches) - break; - + return true; + // Update the max matches for any subsequent calls to find globals // in any other object files with DWARF max_matches -= oso_matches; } - } + + return false; + }); + // Return the number of variable that were appended to the list return variables.GetSize() - original_size; } @@ -951,10 +954,8 @@ SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bo const uint32_t original_size = variables.GetSize(); uint32_t total_matches = 0; - SymbolFileDWARF *oso_dwarf; - for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) - { - const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex, + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + const uint32_t oso_matches = oso_dwarf->FindGlobalVariables (regex, true, max_matches, variables); @@ -964,17 +965,20 @@ SymbolFileDWARFDebugMap::FindGlobalVariables (const RegularExpression& regex, bo // Are we getting all matches? if (max_matches == UINT32_MAX) - continue; // Yep, continue getting everything + return false; // Yep, continue getting everything // If we have found enough matches, lets get out if (max_matches >= total_matches) - break; + return true; // Update the max matches for any subsequent calls to find globals // in any other object files with DWARF max_matches -= oso_matches; } - } + + return false; + }); + // Return the number of variable that were appended to the list return variables.GetSize() - original_size; } @@ -1099,16 +1103,14 @@ SymbolFileDWARFDebugMap::FindFunctions(const ConstString &name, const ClangNames else sc_list.Clear(); - uint32_t oso_idx = 0; - SymbolFileDWARF *oso_dwarf; - while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) - { + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { uint32_t sc_idx = sc_list.GetSize(); if (oso_dwarf->FindFunctions(name, namespace_decl, name_type_mask, include_inlines, true, sc_list)) { RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); } - } + return false; + }); return sc_list.GetSize() - initial_size; } @@ -1127,17 +1129,15 @@ SymbolFileDWARFDebugMap::FindFunctions (const RegularExpression& regex, bool inc else sc_list.Clear(); - uint32_t oso_idx = 0; - SymbolFileDWARF *oso_dwarf; - while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) - { + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { uint32_t sc_idx = sc_list.GetSize(); if (oso_dwarf->FindFunctions(regex, include_inlines, true, sc_list)) { RemoveFunctionsWithModuleNotEqualTo (m_obj_file->GetModule(), sc_list, sc_idx); } - } + return false; + }); return sc_list.GetSize() - initial_size; } @@ -1169,11 +1169,10 @@ SymbolFileDWARFDebugMap::GetTypes (SymbolContextScope *sc_scope, } else { - uint32_t oso_idx = 0; - while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) - { + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { oso_dwarf->GetTypes (sc_scope, type_mask, type_list); - } + return false; + }); } return type_list.GetSize() - initial_size; } @@ -1183,13 +1182,10 @@ TypeSP SymbolFileDWARFDebugMap::FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx) { TypeSP type_sp; - SymbolFileDWARF *oso_dwarf; - for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) - { + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { type_sp = oso_dwarf->FindDefinitionTypeForDWARFDeclContext (die_decl_ctx); - if (type_sp) - break; - } + return ((bool)type_sp); + }); return type_sp; } @@ -1201,15 +1197,14 @@ SymbolFileDWARFDebugMap::Supports_DW_AT_APPLE_objc_complete_type (SymbolFileDWAR if (m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolCalculate) { m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolNo; - SymbolFileDWARF *oso_dwarf; - for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) - { + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { if (skip_dwarf_oso != oso_dwarf && oso_dwarf->Supports_DW_AT_APPLE_objc_complete_type(NULL)) { m_supports_DW_AT_APPLE_objc_complete_type = eLazyBoolYes; - break; + return true; } - } + return false; + }); } return m_supports_DW_AT_APPLE_objc_complete_type == eLazyBoolYes; } @@ -1219,15 +1214,65 @@ SymbolFileDWARFDebugMap::FindCompleteObjCDefinitionTypeForDIE (const DWARFDebugI const ConstString &type_name, bool must_be_implementation) { + // If we have a debug map, we will have an Objective C symbol whose name is + // the type name and whose type is eSymbolTypeObjCClass. If we can find that + // symbol and find its containing parent, we can locate the .o file that will + // contain the implementation definition since it will be scoped inside the N_SO + // and we can then locate the SymbolFileDWARF that corresponds to that N_SO. + SymbolFileDWARF *oso_dwarf = NULL; TypeSP type_sp; - SymbolFileDWARF *oso_dwarf; - for (uint32_t oso_idx = 0; ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) + ObjectFile *module_objfile = m_obj_file->GetModule()->GetObjectFile(); + if (module_objfile) { - type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation); - if (type_sp) - break; + Symtab *symtab = module_objfile->GetSymtab(); + if (symtab) + { + Symbol *objc_class_symbol = symtab->FindFirstSymbolWithNameAndType(type_name, eSymbolTypeObjCClass, Symtab::eDebugAny, Symtab::eVisibilityAny); + if (objc_class_symbol) + { + // Get the N_SO symbol that contains the objective C class symbol as this + // should be the .o file that contains the real definition... + const Symbol *source_file_symbol = symtab->GetParent(objc_class_symbol); + + if (source_file_symbol && source_file_symbol->GetType() == eSymbolTypeSourceFile) + { + const uint32_t source_file_symbol_idx = symtab->GetIndexForSymbol(source_file_symbol); + if (source_file_symbol_idx != UINT32_MAX) + { + CompileUnitInfo *compile_unit_info = GetCompileUnitInfoForSymbolWithIndex (source_file_symbol_idx, NULL); + if (compile_unit_info) + { + oso_dwarf = GetSymbolFileByCompUnitInfo (compile_unit_info); + if (oso_dwarf) + { + TypeSP type_sp (oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation)); + if (type_sp) + { + return type_sp; + } + } + } + } + } + } + } } - return type_sp; + + // Only search all .o files for the definition if we don't need the implementation + // because otherwise, with a valid debug map we should have the ObjC class symbol and + // the code above should have found it. + if (must_be_implementation == false) + { + TypeSP type_sp; + + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + type_sp = oso_dwarf->FindCompleteObjCDefinitionTypeForDIE (die, type_name, must_be_implementation); + return (bool)type_sp; + }); + + return type_sp; + } + return TypeSP(); } uint32_t @@ -1255,9 +1300,10 @@ SymbolFileDWARFDebugMap::FindTypes } else { - uint32_t oso_idx = 0; - while ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx++)) != NULL) + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { oso_dwarf->FindTypes (sc, name, namespace_decl, append, max_matches, types); + return false; + }); } return types.GetSize() - initial_types_size; @@ -1290,15 +1336,11 @@ SymbolFileDWARFDebugMap::FindNamespace (const lldb_private::SymbolContext& sc, } else { - for (uint32_t oso_idx = 0; - ((oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) != NULL); - ++oso_idx) - { + ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { matching_namespace = oso_dwarf->FindNamespace (sc, name, parent_namespace_decl); - if (matching_namespace) - break; - } + return (bool)matching_namespace; + }); } return matching_namespace; @@ -1393,16 +1435,14 @@ SymbolFileDWARFDebugMap::CompleteTagDecl (void *baton, clang::TagDecl *decl) ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); if (clang_type) { - SymbolFileDWARF *oso_dwarf; - - for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) - { + symbol_file_dwarf->ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { if (oso_dwarf->HasForwardDeclForClangType (clang_type)) { oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); - return; + return true; } - } + return false; + }); } } @@ -1413,36 +1453,30 @@ SymbolFileDWARFDebugMap::CompleteObjCInterfaceDecl (void *baton, clang::ObjCInte ClangASTType clang_type = symbol_file_dwarf->GetClangASTContext().GetTypeForDecl (decl); if (clang_type) { - SymbolFileDWARF *oso_dwarf; - - for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) - { + symbol_file_dwarf->ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { if (oso_dwarf->HasForwardDeclForClangType (clang_type)) { oso_dwarf->ResolveClangOpaqueTypeDefinition (clang_type); - return; + return true; } - } + return false; + }); } } -bool -SymbolFileDWARFDebugMap::LayoutRecordType (void *baton, - const clang::RecordDecl *record_decl, - uint64_t &size, - uint64_t &alignment, - llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) +bool +SymbolFileDWARFDebugMap::LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size, + uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets) { SymbolFileDWARFDebugMap *symbol_file_dwarf = (SymbolFileDWARFDebugMap *)baton; - SymbolFileDWARF *oso_dwarf; - for (uint32_t oso_idx = 0; ((oso_dwarf = symbol_file_dwarf->GetSymbolFileByOSOIndex (oso_idx)) != NULL); ++oso_idx) - { - if (oso_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets)) - return true; - } - return false; + bool laid_out = false; + symbol_file_dwarf->ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { + return (laid_out = oso_dwarf->LayoutRecordType (record_decl, size, alignment, field_offsets, base_offsets, vbase_offsets)); + }); + return laid_out; } diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 1493292d4b9b..ce0cfd744f0b 100644 --- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -53,45 +53,46 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - SymbolFileDWARFDebugMap (lldb_private::ObjectFile* ofile); - virtual ~ SymbolFileDWARFDebugMap (); + SymbolFileDWARFDebugMap (lldb_private::ObjectFile* ofile); + ~SymbolFileDWARFDebugMap () override; - virtual uint32_t CalculateAbilities (); + uint32_t CalculateAbilities () override; - virtual void InitializeObject(); + void InitializeObject() override; //------------------------------------------------------------------ // Compile Unit function calls //------------------------------------------------------------------ - virtual uint32_t GetNumCompileUnits (); - virtual lldb::CompUnitSP ParseCompileUnitAtIndex (uint32_t index); - - virtual lldb::LanguageType ParseCompileUnitLanguage (const lldb_private::SymbolContext& sc); - virtual size_t ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc); - virtual bool ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc); - virtual bool ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files); - virtual size_t ParseFunctionBlocks (const lldb_private::SymbolContext& sc); - virtual size_t ParseTypes (const lldb_private::SymbolContext& sc); - virtual size_t ParseVariablesForContext (const lldb_private::SymbolContext& sc); - - virtual lldb_private::Type* ResolveTypeUID (lldb::user_id_t type_uid); - virtual clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid); - virtual clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid); - virtual bool ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type); - virtual uint32_t ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc); - virtual uint32_t ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list); - virtual uint32_t FindGlobalVariables (const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, lldb_private::VariableList& variables); - virtual uint32_t FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables); - virtual uint32_t FindFunctions (const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list); - virtual uint32_t FindFunctions (const lldb_private::RegularExpression& regex, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list); - virtual uint32_t FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, lldb_private::TypeList& types); - virtual lldb_private::ClangNamespaceDecl - FindNamespace (const lldb_private::SymbolContext& sc, - const lldb_private::ConstString &name, - const lldb_private::ClangNamespaceDecl *parent_namespace_decl); - virtual size_t GetTypes (lldb_private::SymbolContextScope *sc_scope, - uint32_t type_mask, - lldb_private::TypeList &type_list); + uint32_t GetNumCompileUnits () override; + lldb::CompUnitSP ParseCompileUnitAtIndex (uint32_t index) override; + + lldb::LanguageType ParseCompileUnitLanguage (const lldb_private::SymbolContext& sc) override; + size_t ParseCompileUnitFunctions (const lldb_private::SymbolContext& sc) override; + bool ParseCompileUnitLineTable (const lldb_private::SymbolContext& sc) override; + bool ParseCompileUnitSupportFiles (const lldb_private::SymbolContext& sc, lldb_private::FileSpecList &support_files) override; + bool ParseImportedModules (const lldb_private::SymbolContext &sc, std::vector<lldb_private::ConstString> &imported_modules) override; + size_t ParseFunctionBlocks (const lldb_private::SymbolContext& sc) override; + size_t ParseTypes (const lldb_private::SymbolContext& sc) override; + size_t ParseVariablesForContext (const lldb_private::SymbolContext& sc) override; + + lldb_private::Type* ResolveTypeUID (lldb::user_id_t type_uid) override; + clang::DeclContext* GetClangDeclContextContainingTypeUID (lldb::user_id_t type_uid) override; + clang::DeclContext* GetClangDeclContextForTypeUID (const lldb_private::SymbolContext &sc, lldb::user_id_t type_uid) override; + bool ResolveClangOpaqueTypeDefinition (lldb_private::ClangASTType& clang_type) override; + uint32_t ResolveSymbolContext (const lldb_private::Address& so_addr, uint32_t resolve_scope, lldb_private::SymbolContext& sc) override; + uint32_t ResolveSymbolContext (const lldb_private::FileSpec& file_spec, uint32_t line, bool check_inlines, uint32_t resolve_scope, lldb_private::SymbolContextList& sc_list) override; + uint32_t FindGlobalVariables (const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override; + uint32_t FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override; + uint32_t FindFunctions (const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, uint32_t name_type_mask, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list) override; + uint32_t FindFunctions (const lldb_private::RegularExpression& regex, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list) override; + uint32_t FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const lldb_private::ClangNamespaceDecl *namespace_decl, bool append, uint32_t max_matches, lldb_private::TypeList& types) override; + lldb_private::ClangNamespaceDecl + FindNamespace (const lldb_private::SymbolContext& sc, + const lldb_private::ConstString &name, + const lldb_private::ClangNamespaceDecl *parent_namespace_decl) override; + size_t GetTypes (lldb_private::SymbolContextScope *sc_scope, + uint32_t type_mask, + lldb_private::TypeList &type_list) override; //------------------------------------------------------------------ @@ -102,25 +103,20 @@ public: static void CompleteObjCInterfaceDecl (void *baton, clang::ObjCInterfaceDecl *); - - static bool - LayoutRecordType (void *baton, - const clang::RecordDecl *record_decl, - uint64_t &size, - uint64_t &alignment, - llvm::DenseMap <const clang::FieldDecl *, uint64_t> &field_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, - llvm::DenseMap <const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); + static bool LayoutRecordType(void *baton, const clang::RecordDecl *record_decl, uint64_t &size, uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); //------------------------------------------------------------------ // PluginInterface protocol //------------------------------------------------------------------ - virtual lldb_private::ConstString - GetPluginName(); + lldb_private::ConstString + GetPluginName() override; - virtual uint32_t - GetPluginVersion(); + uint32_t + GetPluginVersion() override; protected: enum @@ -231,6 +227,23 @@ protected: SymbolFileDWARF * GetSymbolFileByOSOIndex (uint32_t oso_idx); + + // If closure returns "false", iteration continues. If it returns + // "true", iteration terminates. + void + ForEachSymbolFile (std::function<bool (SymbolFileDWARF *)> closure) + { + for (uint32_t oso_idx = 0, num_oso_idxs = m_compile_unit_infos.size(); + oso_idx < num_oso_idxs; + ++oso_idx) + { + if (SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx)) + { + if (closure(oso_dwarf)) + return; + } + } + } CompileUnitInfo * GetCompileUnitInfoForSymbolWithIndex (uint32_t symbol_idx, uint32_t *oso_idx_ptr); |