diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile')
50 files changed, 1254 insertions, 715 deletions
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp index 9d23f1baf931..b5615c358b95 100644 --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -17,6 +17,7 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/TypeMap.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/StreamString.h" #include "llvm/ADT/StringExtras.h" @@ -228,7 +229,7 @@ FunctionSP SymbolFileBreakpad::GetOrCreateFunction(CompileUnit &comp_unit) { if (FunctionSP func_sp = comp_unit.FindFunctionByUID(id)) return func_sp; - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); FunctionSP func_sp; addr_t base = GetBaseFileAddress(); if (base == LLDB_INVALID_ADDRESS) { @@ -347,7 +348,7 @@ void SymbolFileBreakpad::ParseInlineOriginRecords() { return; m_inline_origins.emplace(); - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); for (llvm::StringRef line : lines(Record::InlineOrigin)) { auto record = InlineOriginRecord::parse(line); if (!record) { @@ -455,7 +456,7 @@ void SymbolFileBreakpad::FindTypes( llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeMap &types) {} void SymbolFileBreakpad::AddSymbols(Symtab &symtab) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); Module &module = *m_objfile_sp->GetModule(); addr_t base = GetBaseFileAddress(); if (base == LLDB_INVALID_ADDRESS) { @@ -487,8 +488,8 @@ void SymbolFileBreakpad::AddSymbols(Symtab &symtab) { /*is_global*/ true, /*is_debug*/ false, /*is_trampoline*/ false, /*is_artificial*/ false, AddressRange(section_sp, address - section_sp->GetFileAddress(), - size.getValueOr(0)), - size.hasValue(), /*contains_linker_annotations*/ false, /*flags*/ 0); + size.value_or(0)), + size.has_value(), /*contains_linker_annotations*/ false, /*flags*/ 0); }; for (llvm::StringRef line : lines(Record::Public)) { @@ -510,7 +511,7 @@ SymbolFileBreakpad::GetParameterStackSize(Symbol &symbol) { symbol.GetAddress().GetFileAddress())) { auto record = StackWinRecord::parse( *LineIterator(*m_objfile_sp, Record::StackWin, entry->data)); - assert(record.hasValue()); + assert(record); return record->ParameterSize; } return llvm::createStringError(llvm::inconvertibleErrorCode(), @@ -581,7 +582,7 @@ llvm::ArrayRef<uint8_t> SymbolFileBreakpad::SaveAsDWARF(postfix::Node &node) { bool SymbolFileBreakpad::ParseCFIUnwindRow(llvm::StringRef unwind_rules, const RegisterInfoResolver &resolver, UnwindPlan::Row &row) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); llvm::BumpPtrAllocator node_alloc; llvm::Triple triple = m_objfile_sp->GetArchitecture().GetTriple(); @@ -654,7 +655,7 @@ SymbolFileBreakpad::ParseCFIUnwindPlan(const Bookmark &bookmark, LineIterator It(*m_objfile_sp, Record::StackCFI, bookmark), End(*m_objfile_sp); llvm::Optional<StackCFIRecord> init_record = StackCFIRecord::parse(*It); - assert(init_record.hasValue() && init_record->Size.hasValue() && + assert(init_record && init_record->Size && "Record already parsed successfully in ParseUnwindData!"); auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB); @@ -673,9 +674,9 @@ SymbolFileBreakpad::ParseCFIUnwindPlan(const Bookmark &bookmark, plan_sp->AppendRow(row_sp); for (++It; It != End; ++It) { llvm::Optional<StackCFIRecord> record = StackCFIRecord::parse(*It); - if (!record.hasValue()) + if (!record) return nullptr; - if (record->Size.hasValue()) + if (record->Size) break; row_sp = std::make_shared<UnwindPlan::Row>(*row_sp); @@ -690,15 +691,14 @@ SymbolFileBreakpad::ParseCFIUnwindPlan(const Bookmark &bookmark, UnwindPlanSP SymbolFileBreakpad::ParseWinUnwindPlan(const Bookmark &bookmark, const RegisterInfoResolver &resolver) { - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); addr_t base = GetBaseFileAddress(); if (base == LLDB_INVALID_ADDRESS) return nullptr; LineIterator It(*m_objfile_sp, Record::StackWin, bookmark); llvm::Optional<StackWinRecord> record = StackWinRecord::parse(*It); - assert(record.hasValue() && - "Record already parsed successfully in ParseUnwindData!"); + assert(record && "Record already parsed successfully in ParseUnwindData!"); auto plan_sp = std::make_shared<UnwindPlan>(lldb::eRegisterKindLLDB); plan_sp->SetSourceName("breakpad STACK WIN"); @@ -794,7 +794,7 @@ void SymbolFileBreakpad::ParseFileRecords() { return; m_files.emplace(); - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); for (llvm::StringRef line : lines(Record::File)) { auto record = FileRecord::parse(line); if (!record) { @@ -805,7 +805,7 @@ void SymbolFileBreakpad::ParseFileRecords() { if (record->Number >= m_files->size()) m_files->resize(record->Number + 1); FileSpec::Style style = FileSpec::GuessPathStyle(record->Name) - .getValueOr(FileSpec::Style::native); + .value_or(FileSpec::Style::native); (*m_files)[record->Number] = FileSpec(record->Name, style); } } @@ -815,7 +815,7 @@ void SymbolFileBreakpad::ParseCUData() { return; m_cu_data.emplace(); - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); addr_t base = GetBaseFileAddress(); if (base == LLDB_INVALID_ADDRESS) { LLDB_LOG(log, "SymbolFile parsing failed: Unable to fetch the base address " @@ -894,7 +894,7 @@ void SymbolFileBreakpad::ParseUnwindData() { return; m_unwind_data.emplace(); - Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); + Log *log = GetLog(LLDBLog::Symbols); addr_t base = GetBaseFileAddress(); if (base == LLDB_INVALID_ADDRESS) { LLDB_LOG(log, "SymbolFile parsing failed: Unable to fetch the base address " diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h index bf3e25c1a63e..639d2e272adf 100644 --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -20,7 +20,7 @@ namespace lldb_private { namespace breakpad { -class SymbolFileBreakpad : public SymbolFile { +class SymbolFileBreakpad : public SymbolFileCommon { /// LLVM RTTI support. static char ID; @@ -28,7 +28,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} @@ -49,7 +49,7 @@ public: // Constructors and Destructors SymbolFileBreakpad(lldb::ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)) {} + : SymbolFileCommon(std::move(objfile_sp)) {} ~SymbolFileBreakpad() override = default; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp index ec4057efbbc5..4877169b3213 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/AppleDWARFIndex.cpp @@ -16,6 +16,7 @@ using namespace lldb_private; using namespace lldb; +using namespace lldb_private::dwarf; std::unique_ptr<AppleDWARFIndex> AppleDWARFIndex::Create( Module &module, DWARFDataExtractor apple_names, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h index 23e1eec26ec3..4370039d1a8d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DIERef.h @@ -29,7 +29,7 @@ public: DIERef(llvm::Optional<uint32_t> dwo_num, Section section, dw_offset_t die_offset) - : m_dwo_num(dwo_num.getValueOr(0)), m_dwo_num_valid(bool(dwo_num)), + : m_dwo_num(dwo_num.value_or(0)), m_dwo_num_valid(bool(dwo_num)), m_section(section), m_die_offset(die_offset) { assert(this->dwo_num() == dwo_num && "Dwo number out of range?"); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp new file mode 100644 index 000000000000..364d34c73375 --- /dev/null +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.cpp @@ -0,0 +1,115 @@ +//===-- DWARFASTParser.cpp ------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "DWARFASTParser.h" +#include "DWARFAttribute.h" +#include "DWARFDIE.h" + +#include "lldb/Core/ValueObject.h" +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Target/StackFrame.h" + +using namespace lldb; +using namespace lldb_private; +using namespace lldb_private::dwarf; + +llvm::Optional<SymbolFile::ArrayInfo> +DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, + const ExecutionContext *exe_ctx) { + SymbolFile::ArrayInfo array_info; + if (!parent_die) + return llvm::None; + + for (DWARFDIE die : parent_die.children()) { + const dw_tag_t tag = die.Tag(); + if (tag != DW_TAG_subrange_type) + continue; + + DWARFAttributes attributes; + const size_t num_child_attributes = die.GetAttributes(attributes); + if (num_child_attributes > 0) { + uint64_t num_elements = 0; + uint64_t lower_bound = 0; + uint64_t upper_bound = 0; + bool upper_bound_valid = false; + uint32_t i; + for (i = 0; i < num_child_attributes; ++i) { + const dw_attr_t attr = attributes.AttributeAtIndex(i); + DWARFFormValue form_value; + if (attributes.ExtractFormValueAtIndex(i, form_value)) { + switch (attr) { + case DW_AT_name: + break; + + case DW_AT_count: + if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { + if (var_die.Tag() == DW_TAG_variable) + if (exe_ctx) { + if (auto frame = exe_ctx->GetFrameSP()) { + Status error; + lldb::VariableSP var_sp; + auto valobj_sp = frame->GetValueForVariableExpressionPath( + var_die.GetName(), eNoDynamicValues, 0, var_sp, error); + if (valobj_sp) { + num_elements = valobj_sp->GetValueAsUnsigned(0); + break; + } + } + } + } else + num_elements = form_value.Unsigned(); + break; + + case DW_AT_bit_stride: + array_info.bit_stride = form_value.Unsigned(); + break; + + case DW_AT_byte_stride: + array_info.byte_stride = form_value.Unsigned(); + break; + + case DW_AT_lower_bound: + lower_bound = form_value.Unsigned(); + break; + + case DW_AT_upper_bound: + upper_bound_valid = true; + upper_bound = form_value.Unsigned(); + break; + + default: + break; + } + } + } + + if (num_elements == 0) { + if (upper_bound_valid && upper_bound >= lower_bound) + num_elements = upper_bound - lower_bound + 1; + } + + array_info.element_orders.push_back(num_elements); + } + } + return array_info; +} + +AccessType +DWARFASTParser::GetAccessTypeFromDWARF(uint32_t dwarf_accessibility) { + switch (dwarf_accessibility) { + case DW_ACCESS_public: + return eAccessPublic; + case DW_ACCESS_private: + return eAccessPrivate; + case DW_ACCESS_protected: + return eAccessProtected; + default: + break; + } + return eAccessNone; +} diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h index 00123a4b9216..97b0ea1874e1 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParser.h @@ -14,6 +14,7 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" +#include "lldb/lldb-enumerations.h" class DWARFDIE; namespace lldb_private { @@ -54,6 +55,8 @@ public: static llvm::Optional<lldb_private::SymbolFile::ArrayInfo> ParseChildArrayInfo(const DWARFDIE &parent_die, const lldb_private::ExecutionContext *exe_ctx = nullptr); + + static lldb::AccessType GetAccessTypeFromDWARF(uint32_t dwarf_accessibility); }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_DWARFASTPARSER_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 2daffecee58e..2aacac3692be 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -8,6 +8,7 @@ #include <cstdlib> +#include "DWARFASTParser.h" #include "DWARFASTParserClang.h" #include "DWARFDebugInfo.h" #include "DWARFDeclContext.h" @@ -57,25 +58,12 @@ using namespace lldb; using namespace lldb_private; +using namespace lldb_private::dwarf; DWARFASTParserClang::DWARFASTParserClang(TypeSystemClang &ast) : m_ast(ast), m_die_to_decl_ctx(), m_decl_ctx_to_die() {} DWARFASTParserClang::~DWARFASTParserClang() = default; -static AccessType DW_ACCESS_to_AccessType(uint32_t dwarf_accessibility) { - switch (dwarf_accessibility) { - case DW_ACCESS_public: - return eAccessPublic; - case DW_ACCESS_private: - return eAccessPrivate; - case DW_ACCESS_protected: - return eAccessProtected; - default: - break; - } - return eAccessNone; -} - static bool DeclKindIsCXXClass(clang::Decl::Kind decl_kind) { switch (decl_kind) { case clang::Decl::CXXRecord: @@ -313,7 +301,7 @@ ParsedDWARFTypeAttributes::ParsedDWARFTypeAttributes(const DWARFDIE &die) { break; case DW_AT_accessibility: - accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); break; case DW_AT_artificial: @@ -626,7 +614,7 @@ DWARFASTParserClang::ParseTypeModifier(const SymbolContext &sc, resolve_state = Type::ResolveState::Full; clang_type = m_ast.GetBuiltinTypeForDWARFEncodingAndBitSize( attrs.name.GetStringRef(), attrs.encoding, - attrs.byte_size.getValueOr(0) * 8); + attrs.byte_size.value_or(0) * 8); break; case DW_TAG_pointer_type: @@ -861,7 +849,7 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc, bool is_signed = false; enumerator_clang_type.IsIntegerType(is_signed); ParseChildEnumerators(clang_type, is_signed, - type_sp->GetByteSize(nullptr).getValueOr(0), die); + type_sp->GetByteSize(nullptr).value_or(0), die); } TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); } else { @@ -1039,10 +1027,8 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, // struct and see if this is actually a C++ method Type *class_type = dwarf->ResolveType(decl_ctx_die); if (class_type) { - bool alternate_defn = false; if (class_type->GetID() != decl_ctx_die.GetID() || IsClangModuleFwdDecl(decl_ctx_die)) { - alternate_defn = true; // We uniqued the parent class of this function to another // class so we now need to associate all dies under @@ -1111,7 +1097,7 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, CompilerType class_opaque_type = class_type->GetForwardCompilerType(); if (TypeSystemClang::IsCXXClassType(class_opaque_type)) { - if (class_opaque_type.IsBeingDefined() || alternate_defn) { + if (class_opaque_type.IsBeingDefined()) { if (!is_static && !die.HasChildren()) { // We have a C++ member function with no children (this // pointer!) and clang will get mad if we try and make @@ -1119,84 +1105,50 @@ TypeSP DWARFASTParserClang::ParseSubroutine(const DWARFDIE &die, // we will just skip it... type_handled = true; } else { - bool add_method = true; - if (alternate_defn) { - // If an alternate definition for the class exists, - // then add the method only if an equivalent is not - // already present. - clang::CXXRecordDecl *record_decl = - m_ast.GetAsCXXRecordDecl( - class_opaque_type.GetOpaqueQualType()); - if (record_decl) { - for (auto method_iter = record_decl->method_begin(); - method_iter != record_decl->method_end(); - method_iter++) { - clang::CXXMethodDecl *method_decl = *method_iter; - if (method_decl->getNameInfo().getAsString() == - attrs.name.GetStringRef()) { - if (method_decl->getType() == - ClangUtil::GetQualType(clang_type)) { - add_method = false; - LinkDeclContextToDIE(method_decl, die); - type_handled = true; - - break; - } - } - } - } - } - - if (add_method) { - llvm::PrettyStackTraceFormat stack_trace( - "SymbolFileDWARF::ParseType() is adding a method " - "%s to class %s in DIE 0x%8.8" PRIx64 " from %s", - attrs.name.GetCString(), - class_type->GetName().GetCString(), die.GetID(), - dwarf->GetObjectFile() - ->GetFileSpec() - .GetPath() - .c_str()); + llvm::PrettyStackTraceFormat stack_trace( + "SymbolFileDWARF::ParseType() is adding a method " + "%s to class %s in DIE 0x%8.8" PRIx64 " from %s", + attrs.name.GetCString(), + class_type->GetName().GetCString(), die.GetID(), + dwarf->GetObjectFile()->GetFileSpec().GetPath().c_str()); - const bool is_attr_used = false; - // Neither GCC 4.2 nor clang++ currently set a valid - // accessibility in the DWARF for C++ methods... - // Default to public for now... - if (attrs.accessibility == eAccessNone) - attrs.accessibility = eAccessPublic; + const bool is_attr_used = false; + // Neither GCC 4.2 nor clang++ currently set a valid + // accessibility in the DWARF for C++ methods... + // Default to public for now... + if (attrs.accessibility == eAccessNone) + attrs.accessibility = eAccessPublic; - clang::CXXMethodDecl *cxx_method_decl = - m_ast.AddMethodToCXXRecordType( - class_opaque_type.GetOpaqueQualType(), - attrs.name.GetCString(), attrs.mangled_name, - clang_type, attrs.accessibility, attrs.is_virtual, - is_static, attrs.is_inline, attrs.is_explicit, - is_attr_used, attrs.is_artificial); + clang::CXXMethodDecl *cxx_method_decl = + m_ast.AddMethodToCXXRecordType( + class_opaque_type.GetOpaqueQualType(), + attrs.name.GetCString(), attrs.mangled_name, + clang_type, attrs.accessibility, attrs.is_virtual, + is_static, attrs.is_inline, attrs.is_explicit, + is_attr_used, attrs.is_artificial); - type_handled = cxx_method_decl != nullptr; - // Artificial methods are always handled even when we - // don't create a new declaration for them. - type_handled |= attrs.is_artificial; + type_handled = cxx_method_decl != nullptr; + // Artificial methods are always handled even when we + // don't create a new declaration for them. + type_handled |= attrs.is_artificial; - if (cxx_method_decl) { - LinkDeclContextToDIE(cxx_method_decl, die); + if (cxx_method_decl) { + LinkDeclContextToDIE(cxx_method_decl, die); - ClangASTMetadata metadata; - metadata.SetUserID(die.GetID()); + ClangASTMetadata metadata; + metadata.SetUserID(die.GetID()); - if (!object_pointer_name.empty()) { - metadata.SetObjectPtrName( - object_pointer_name.c_str()); - LLDB_LOGF(log, - "Setting object pointer name: %s on method " - "object %p.\n", - object_pointer_name.c_str(), - static_cast<void *>(cxx_method_decl)); - } - m_ast.SetMetadata(cxx_method_decl, metadata); - } else { - ignore_containing_context = true; + if (!object_pointer_name.empty()) { + metadata.SetObjectPtrName(object_pointer_name.c_str()); + LLDB_LOGF(log, + "Setting object pointer name: %s on method " + "object %p.\n", + object_pointer_name.c_str(), + static_cast<void *>(cxx_method_decl)); } + m_ast.SetMetadata(cxx_method_decl, metadata); + } else { + ignore_containing_context = true; } } } else { @@ -1345,7 +1297,7 @@ TypeSP DWARFASTParserClang::ParseArrayType(const DWARFDIE &die, attrs.bit_stride = array_info->bit_stride; } if (attrs.byte_stride == 0 && attrs.bit_stride == 0) - attrs.byte_stride = element_type->GetByteSize(nullptr).getValueOr(0); + attrs.byte_stride = element_type->GetByteSize(nullptr).value_or(0); CompilerType array_element_type = element_type->GetForwardCompilerType(); RequireCompleteType(array_element_type); @@ -1458,7 +1410,7 @@ void DWARFASTParserClang::ParseInheritance( break; case DW_AT_accessibility: - accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); break; case DW_AT_virtuality: @@ -1580,7 +1532,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, } if (dwarf->GetUniqueDWARFASTTypeMap().Find( - unique_typename, die, unique_decl, attrs.byte_size.getValueOr(-1), + unique_typename, die, unique_decl, attrs.byte_size.value_or(-1), *unique_ast_entry_up)) { type_sp = unique_ast_entry_up->m_type_sp; if (type_sp) { @@ -1805,7 +1757,7 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc, unique_ast_entry_up->m_type_sp = type_sp; unique_ast_entry_up->m_die = die; unique_ast_entry_up->m_declaration = unique_decl; - unique_ast_entry_up->m_byte_size = attrs.byte_size.getValueOr(0); + unique_ast_entry_up->m_byte_size = attrs.byte_size.value_or(0); dwarf->GetUniqueDWARFASTTypeMap().Insert(unique_typename, *unique_ast_entry_up); @@ -2162,7 +2114,7 @@ bool DWARFASTParserClang::CompleteRecordType(const DWARFDIE &die, if (!layout_info.field_offsets.empty() || !layout_info.base_offsets.empty() || !layout_info.vbase_offsets.empty()) { if (type) - layout_info.bit_size = type->GetByteSize(nullptr).getValueOr(0) * 8; + layout_info.bit_size = type->GetByteSize(nullptr).value_or(0) * 8; if (layout_info.bit_size == 0) layout_info.bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8; @@ -2184,7 +2136,7 @@ bool DWARFASTParserClang::CompleteEnumType(const DWARFDIE &die, bool is_signed = false; clang_type.IsIntegerType(is_signed); ParseChildEnumerators(clang_type, is_signed, - type->GetByteSize(nullptr).getValueOr(0), die); + type->GetByteSize(nullptr).value_or(0), die); } TypeSystemClang::CompleteTagDeclarationDefinition(clang_type); } @@ -2443,8 +2395,6 @@ struct MemberAttributes { /// structure. uint32_t member_byte_offset; bool is_artificial = false; - /// On DW_TAG_members, this means the member is static. - bool is_external = false; }; /// Parsed form of all attributes that are relevant for parsing Objective-C @@ -2515,14 +2465,11 @@ MemberAttributes::MemberAttributes(const DWARFDIE &die, break; case DW_AT_accessibility: - accessibility = DW_ACCESS_to_AccessType(form_value.Unsigned()); + accessibility = DWARFASTParser::GetAccessTypeFromDWARF(form_value.Unsigned()); break; case DW_AT_artificial: is_artificial = form_value.Boolean(); break; - case DW_AT_external: - is_external = form_value.Boolean(); - break; default: break; } @@ -2541,7 +2488,7 @@ MemberAttributes::MemberAttributes(const DWARFDIE &die, // are not sane, remove them. If we don't do this then we will end up // with a crash if we try to use this type in an expression when clang // becomes unhappy with its recycled debug info. - if (byte_size.getValueOr(0) == 0 && bit_offset < 0) { + if (byte_size.value_or(0) == 0 && bit_offset < 0) { bit_size = 0; bit_offset = 0; } @@ -2667,8 +2614,10 @@ void DWARFASTParserClang::ParseSingleMember( if (class_is_objc_object_or_interface) attrs.accessibility = eAccessNone; - // Handle static members - if (attrs.is_external && attrs.member_byte_offset == UINT32_MAX) { + // Handle static members, which is any member that doesn't have a bit or a + // byte member offset. + if (attrs.member_byte_offset == UINT32_MAX && + attrs.data_bit_offset == UINT64_MAX) { Type *var_type = die.ResolveTypeUID(attrs.encoding_form.Reference()); if (var_type) { @@ -2720,7 +2669,7 @@ void DWARFASTParserClang::ParseSingleMember( ObjectFile *objfile = die.GetDWARF()->GetObjectFile(); if (objfile->GetByteOrder() == eByteOrderLittle) { - this_field_info.bit_offset += attrs.byte_size.getValueOr(0) * 8; + this_field_info.bit_offset += attrs.byte_size.value_or(0) * 8; this_field_info.bit_offset -= (attrs.bit_offset + attrs.bit_size); } else { this_field_info.bit_offset += attrs.bit_offset; @@ -3057,99 +3006,6 @@ size_t DWARFASTParserClang::ParseChildParameters( return arg_idx; } -llvm::Optional<SymbolFile::ArrayInfo> -DWARFASTParser::ParseChildArrayInfo(const DWARFDIE &parent_die, - const ExecutionContext *exe_ctx) { - SymbolFile::ArrayInfo array_info; - if (!parent_die) - return llvm::None; - - for (DWARFDIE die : parent_die.children()) { - const dw_tag_t tag = die.Tag(); - if (tag != DW_TAG_subrange_type) - continue; - - DWARFAttributes attributes; - const size_t num_child_attributes = die.GetAttributes(attributes); - if (num_child_attributes > 0) { - uint64_t num_elements = 0; - uint64_t lower_bound = 0; - uint64_t upper_bound = 0; - bool upper_bound_valid = false; - uint32_t i; - for (i = 0; i < num_child_attributes; ++i) { - const dw_attr_t attr = attributes.AttributeAtIndex(i); - DWARFFormValue form_value; - if (attributes.ExtractFormValueAtIndex(i, form_value)) { - switch (attr) { - case DW_AT_name: - break; - - case DW_AT_count: - if (DWARFDIE var_die = die.GetReferencedDIE(DW_AT_count)) { - if (var_die.Tag() == DW_TAG_variable) - if (exe_ctx) { - if (auto frame = exe_ctx->GetFrameSP()) { - Status error; - lldb::VariableSP var_sp; - auto valobj_sp = frame->GetValueForVariableExpressionPath( - var_die.GetName(), eNoDynamicValues, 0, var_sp, - error); - if (valobj_sp) { - num_elements = valobj_sp->GetValueAsUnsigned(0); - break; - } - } - } - } else - num_elements = form_value.Unsigned(); - break; - - case DW_AT_bit_stride: - array_info.bit_stride = form_value.Unsigned(); - break; - - case DW_AT_byte_stride: - array_info.byte_stride = form_value.Unsigned(); - break; - - case DW_AT_lower_bound: - lower_bound = form_value.Unsigned(); - break; - - case DW_AT_upper_bound: - upper_bound_valid = true; - upper_bound = form_value.Unsigned(); - break; - - default: - case DW_AT_abstract_origin: - case DW_AT_accessibility: - case DW_AT_allocated: - case DW_AT_associated: - case DW_AT_data_location: - case DW_AT_declaration: - case DW_AT_description: - case DW_AT_sibling: - case DW_AT_threads_scaled: - case DW_AT_type: - case DW_AT_visibility: - break; - } - } - } - - if (num_elements == 0) { - if (upper_bound_valid && upper_bound >= lower_bound) - num_elements = upper_bound - lower_bound + 1; - } - - array_info.element_orders.push_back(num_elements); - } - } - return array_info; -} - Type *DWARFASTParserClang::GetTypeForDIE(const DWARFDIE &die) { if (die) { SymbolFileDWARF *dwarf = die.GetDWARF(); @@ -3498,49 +3354,37 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( // in "dst_cu" and "dst_class_die" class_type->GetFullCompilerType(); - DWARFDIE src_die; - DWARFDIE dst_die; + auto gather = [](DWARFDIE die, UniqueCStringMap<DWARFDIE> &map, + UniqueCStringMap<DWARFDIE> &map_artificial) { + if (die.Tag() != DW_TAG_subprogram) + return; + // Make sure this is a declaration and not a concrete instance by looking + // for DW_AT_declaration set to 1. Sometimes concrete function instances are + // placed inside the class definitions and shouldn't be included in the list + // of things are are tracking here. + if (die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) != 1) + return; + + if (const char *name = die.GetMangledName()) { + ConstString const_name(name); + if (die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) + map_artificial.Append(const_name, die); + else + map.Append(const_name, die); + } + }; + UniqueCStringMap<DWARFDIE> src_name_to_die; UniqueCStringMap<DWARFDIE> dst_name_to_die; UniqueCStringMap<DWARFDIE> src_name_to_die_artificial; UniqueCStringMap<DWARFDIE> dst_name_to_die_artificial; - for (src_die = src_class_die.GetFirstChild(); src_die.IsValid(); + for (DWARFDIE src_die = src_class_die.GetFirstChild(); src_die.IsValid(); src_die = src_die.GetSibling()) { - if (src_die.Tag() == DW_TAG_subprogram) { - // Make sure this is a declaration and not a concrete instance by looking - // for DW_AT_declaration set to 1. Sometimes concrete function instances - // are placed inside the class definitions and shouldn't be included in - // the list of things are are tracking here. - if (src_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) { - const char *src_name = src_die.GetMangledName(); - if (src_name) { - ConstString src_const_name(src_name); - if (src_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) - src_name_to_die_artificial.Append(src_const_name, src_die); - else - src_name_to_die.Append(src_const_name, src_die); - } - } - } + gather(src_die, src_name_to_die, src_name_to_die_artificial); } - for (dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); + for (DWARFDIE dst_die = dst_class_die.GetFirstChild(); dst_die.IsValid(); dst_die = dst_die.GetSibling()) { - if (dst_die.Tag() == DW_TAG_subprogram) { - // Make sure this is a declaration and not a concrete instance by looking - // for DW_AT_declaration set to 1. Sometimes concrete function instances - // are placed inside the class definitions and shouldn't be included in - // the list of things are are tracking here. - if (dst_die.GetAttributeValueAsUnsigned(DW_AT_declaration, 0) == 1) { - const char *dst_name = dst_die.GetMangledName(); - if (dst_name) { - ConstString dst_const_name(dst_name); - if (dst_die.GetAttributeValueAsUnsigned(DW_AT_artificial, 0)) - dst_name_to_die_artificial.Append(dst_const_name, dst_die); - else - dst_name_to_die.Append(dst_const_name, dst_die); - } - } - } + gather(dst_die, dst_name_to_die, dst_name_to_die_artificial); } const uint32_t src_size = src_name_to_die.GetSize(); const uint32_t dst_size = dst_name_to_die.GetSize(); @@ -3555,8 +3399,8 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( if (fast_path) { for (idx = 0; idx < src_size; ++idx) { - src_die = src_name_to_die.GetValueAtIndexUnchecked(idx); - dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); + DWARFDIE src_die = src_name_to_die.GetValueAtIndexUnchecked(idx); + DWARFDIE dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); if (src_die.Tag() != dst_die.Tag()) fast_path = false; @@ -3574,28 +3418,29 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( DWARFASTParserClang *src_dwarf_ast_parser = static_cast<DWARFASTParserClang *>( - SymbolFileDWARF::GetDWARFParser(*src_die.GetCU())); + SymbolFileDWARF::GetDWARFParser(*src_class_die.GetCU())); DWARFASTParserClang *dst_dwarf_ast_parser = static_cast<DWARFASTParserClang *>( - SymbolFileDWARF::GetDWARFParser(*dst_die.GetCU())); + SymbolFileDWARF::GetDWARFParser(*dst_class_die.GetCU())); + auto link = [&](DWARFDIE src, DWARFDIE dst) { + SymbolFileDWARF::DIEToTypePtr &die_to_type = + dst_class_die.GetDWARF()->GetDIEToType(); + clang::DeclContext *dst_decl_ctx = + dst_dwarf_ast_parser->m_die_to_decl_ctx[dst.GetDIE()]; + if (dst_decl_ctx) + src_dwarf_ast_parser->LinkDeclContextToDIE(dst_decl_ctx, src); + + if (Type *src_child_type = die_to_type[src.GetDIE()]) + die_to_type[dst.GetDIE()] = src_child_type; + }; // Now do the work of linking the DeclContexts and Types. if (fast_path) { // We can do this quickly. Just run across the tables index-for-index // since we know each node has matching names and tags. for (idx = 0; idx < src_size; ++idx) { - src_die = src_name_to_die.GetValueAtIndexUnchecked(idx); - dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); - - clang::DeclContext *src_decl_ctx = - src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; - if (src_decl_ctx) - dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); - - Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; - if (src_child_type) - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; + link(src_name_to_die.GetValueAtIndexUnchecked(idx), + dst_name_to_die.GetValueAtIndexUnchecked(idx)); } } else { // We must do this slowly. For each member of the destination, look up a @@ -3607,24 +3452,13 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( for (idx = 0; idx < dst_size; ++idx) { ConstString dst_name = dst_name_to_die.GetCStringAtIndex(idx); - dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); - src_die = src_name_to_die.Find(dst_name, DWARFDIE()); - - if (src_die && (src_die.Tag() == dst_die.Tag())) { - clang::DeclContext *src_decl_ctx = - src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; - if (src_decl_ctx) - dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); + DWARFDIE dst_die = dst_name_to_die.GetValueAtIndexUnchecked(idx); + DWARFDIE src_die = src_name_to_die.Find(dst_name, DWARFDIE()); - Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; - if (src_child_type) { - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = - src_child_type; - } - } else { + if (src_die && (src_die.Tag() == dst_die.Tag())) + link(src_die, dst_die); + else failures.push_back(dst_die); - } } } } @@ -3638,29 +3472,21 @@ bool DWARFASTParserClang::CopyUniqueClassMethodTypes( for (idx = 0; idx < src_size_artificial; ++idx) { ConstString src_name_artificial = src_name_to_die_artificial.GetCStringAtIndex(idx); - src_die = src_name_to_die_artificial.GetValueAtIndexUnchecked(idx); - dst_die = + DWARFDIE src_die = + src_name_to_die_artificial.GetValueAtIndexUnchecked(idx); + DWARFDIE dst_die = dst_name_to_die_artificial.Find(src_name_artificial, DWARFDIE()); - if (dst_die) { - // Both classes have the artificial types, link them - clang::DeclContext *src_decl_ctx = - src_dwarf_ast_parser->m_die_to_decl_ctx[src_die.GetDIE()]; - if (src_decl_ctx) - dst_dwarf_ast_parser->LinkDeclContextToDIE(src_decl_ctx, dst_die); - - Type *src_child_type = - dst_die.GetDWARF()->GetDIEToType()[src_die.GetDIE()]; - if (src_child_type) - dst_die.GetDWARF()->GetDIEToType()[dst_die.GetDIE()] = src_child_type; - } + // Both classes have the artificial types, link them + if (dst_die) + link(src_die, dst_die); } } if (dst_size_artificial) { for (idx = 0; idx < dst_size_artificial; ++idx) { - dst_die = dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx); - failures.push_back(dst_die); + failures.push_back( + dst_name_to_die_artificial.GetValueAtIndexUnchecked(idx)); } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp index 2f6b36c79b80..62d75c69afa8 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp @@ -16,13 +16,13 @@ #include "DWARFFormValue.h" using namespace lldb_private; +using namespace lldb_private::dwarf; DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration() : m_attributes() {} DWARFAbbreviationDeclaration::DWARFAbbreviationDeclaration(dw_tag_t tag, uint8_t has_children) - : m_code(InvalidCode), m_tag(tag), m_has_children(has_children), - m_attributes() {} + : m_tag(tag), m_has_children(has_children), m_attributes() {} llvm::Expected<DWARFEnumState> DWARFAbbreviationDeclaration::extract(const DWARFDataExtractor &data, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp index 134f6b2bd114..00b56537ae2b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFAttribute.cpp @@ -10,6 +10,8 @@ #include "DWARFUnit.h" #include "DWARFDebugInfo.h" +using namespace lldb_private::dwarf; + DWARFAttributes::DWARFAttributes() : m_infos() {} DWARFAttributes::~DWARFAttributes() = default; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp index 529007e31b9e..ec074be581b5 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDIE.cpp @@ -15,6 +15,7 @@ #include "DWARFUnit.h" using namespace lldb_private; +using namespace lldb_private::dwarf; namespace { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp index 0f0f50a645db..d890288cdf56 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugAbbrev.cpp @@ -12,7 +12,6 @@ using namespace lldb; using namespace lldb_private; -using namespace std; // DWARFAbbreviationDeclarationSet::Clear() void DWARFAbbreviationDeclarationSet::Clear() { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp index b72c7406ece1..8933b0804a01 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfo.cpp @@ -27,7 +27,6 @@ using namespace lldb; using namespace lldb_private; -using namespace std; // Constructor DWARFDebugInfo::DWARFDebugInfo(SymbolFileDWARF &dwarf, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp index 39915aa889ff..95c0cb6472c5 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugInfoEntry.cpp @@ -31,7 +31,7 @@ #include "SymbolFileDWARFDwo.h" using namespace lldb_private; -using namespace std; +using namespace lldb_private::dwarf; extern int g_verbose; // Extract a debug info entry for a given DWARFUnit from the data diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp index 278950a9f336..19c6448c4e74 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.cpp @@ -14,6 +14,7 @@ #include "DWARFDataExtractor.h" using namespace lldb_private; +using namespace lldb_private::dwarf; DWARFDebugMacroHeader DWARFDebugMacroHeader::ParseHeader(const DWARFDataExtractor &debug_macro_data, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h index 5c0338e950eb..cbf762458331 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDebugMacro.h @@ -43,9 +43,9 @@ private: SkipOperandTable(const lldb_private::DWARFDataExtractor &debug_macro_data, lldb::offset_t *offset); - uint16_t m_version; - bool m_offset_is_64_bit; - uint64_t m_debug_line_offset; + uint16_t m_version = 0; + bool m_offset_is_64_bit = false; + uint64_t m_debug_line_offset = 0; }; class DWARFDebugMacroEntry { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp index f4c8c14cc8af..393de0038e65 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFDeclContext.cpp @@ -8,6 +8,8 @@ #include "DWARFDeclContext.h" +using namespace lldb_private::dwarf; + const char *DWARFDeclContext::GetQualifiedName() const { if (m_qualified_name.empty()) { // The declaration context array for a class named "foo" in namespace diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp index 4c498705da45..08b241683776 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFFormValue.cpp @@ -20,6 +20,7 @@ class DWARFUnit; using namespace lldb_private; +using namespace lldb_private::dwarf; void DWARFFormValue::Clear() { m_unit = nullptr; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp index 6707d471e09b..5131584f5522 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFIndex.cpp @@ -68,7 +68,8 @@ DWARFIndex::DIERefCallbackImpl::DIERefCallbackImpl( const DWARFIndex &index, llvm::function_ref<bool(DWARFDIE die)> callback, llvm::StringRef name) : m_index(index), - m_dwarf(*llvm::cast<SymbolFileDWARF>(index.m_module.GetSymbolFile())), + m_dwarf(*llvm::cast<SymbolFileDWARF>( + index.m_module.GetSymbolFile()->GetBackingSymbolFile())), m_callback(callback), m_name(name) {} bool DWARFIndex::DIERefCallbackImpl::operator()(DIERef ref) const { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp index 5487f709d223..903cd2e38f76 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.cpp @@ -13,6 +13,7 @@ #include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/StreamString.h" #include "lldb/Utility/Timer.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h" #include "llvm/Object/Error.h" #include "DWARFCompileUnit.h" @@ -24,7 +25,7 @@ using namespace lldb; using namespace lldb_private; -using namespace std; +using namespace lldb_private::dwarf; extern int g_verbose; @@ -447,7 +448,7 @@ ParseListTableHeader(const llvm::DWARFDataExtractor &data, uint64_t offset, uint64_t HeaderSize = llvm::DWARFListTableHeader::getHeaderSize(format); if (offset < HeaderSize) - return llvm::createStringError(errc::invalid_argument, + return llvm::createStringError(std::errc::invalid_argument, "did not detect a valid" " list table with base = 0x%" PRIx64 "\n", offset); @@ -557,10 +558,10 @@ DWARFUnit::GetRnglistTable() { // This function is called only for DW_FORM_rnglistx. llvm::Expected<uint64_t> DWARFUnit::GetRnglistOffset(uint32_t Index) { if (!GetRnglistTable()) - return llvm::createStringError(errc::invalid_argument, + return llvm::createStringError(std::errc::invalid_argument, "missing or invalid range list table"); if (!m_ranges_base) - return llvm::createStringError(errc::invalid_argument, + return llvm::createStringError(std::errc::invalid_argument, "DW_FORM_rnglistx cannot be used without " "DW_AT_rnglists_base for CU at 0x%8.8x", GetOffset()); @@ -568,7 +569,7 @@ llvm::Expected<uint64_t> DWARFUnit::GetRnglistOffset(uint32_t Index) { GetRnglistData().GetAsLLVM(), Index)) return *off + m_ranges_base; return llvm::createStringError( - errc::invalid_argument, + std::errc::invalid_argument, "invalid range list table index %u; OffsetEntryCount is %u, " "DW_AT_rnglists_base is %" PRIu64, Index, GetRnglistTable()->getOffsetEntryCount(), m_ranges_base); @@ -771,7 +772,8 @@ removeHostnameFromPathname(llvm::StringRef path_from_dwarf) { // check whether we have a windows path, and so the first character is a // drive-letter not a hostname. - if (host.size() == 1 && llvm::isAlpha(host[0]) && path.startswith("\\")) + if (host.size() == 1 && llvm::isAlpha(host[0]) && + (path.startswith("\\") || path.startswith("/"))) return path_from_dwarf; return path; @@ -787,7 +789,7 @@ void DWARFUnit::ComputeCompDirAndGuessPathStyle() { die->GetAttributeValueAsString(this, DW_AT_comp_dir, nullptr)); if (!comp_dir.empty()) { FileSpec::Style comp_dir_style = - FileSpec::GuessPathStyle(comp_dir).getValueOr(FileSpec::Style::native); + FileSpec::GuessPathStyle(comp_dir).value_or(FileSpec::Style::native); m_comp_dir = FileSpec(comp_dir, comp_dir_style); } else { // Try to detect the style based on the DW_AT_name attribute, but just store @@ -795,7 +797,7 @@ void DWARFUnit::ComputeCompDirAndGuessPathStyle() { const char *name = die->GetAttributeValueAsString(this, DW_AT_name, nullptr); m_comp_dir = FileSpec( - "", FileSpec::GuessPathStyle(name).getValueOr(FileSpec::Style::native)); + "", FileSpec::GuessPathStyle(name).value_or(FileSpec::Style::native)); } } @@ -863,14 +865,24 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, section == DIERef::Section::DebugTypes ? DW_UT_type : DW_UT_compile; } + if (header.IsTypeUnit()) { + header.m_type_hash = data.GetU64(offset_ptr); + header.m_type_offset = data.GetDWARFOffset(offset_ptr); + } + if (context.isDwo()) { + const llvm::DWARFUnitIndex *Index; if (header.IsTypeUnit()) { - header.m_index_entry = - context.GetAsLLVM().getTUIndex().getFromOffset(header.m_offset); + Index = &context.GetAsLLVM().getTUIndex(); + if (*Index) + header.m_index_entry = Index->getFromHash(header.m_type_hash); } else { - header.m_index_entry = - context.GetAsLLVM().getCUIndex().getFromOffset(header.m_offset); + Index = &context.GetAsLLVM().getCUIndex(); + if (*Index && header.m_version >= 5) + header.m_index_entry = Index->getFromHash(header.m_dwo_id); } + if (!header.m_index_entry) + header.m_index_entry = Index->getFromOffset(header.m_offset); } if (header.m_index_entry) { @@ -893,10 +905,6 @@ DWARFUnitHeader::extract(const DWARFDataExtractor &data, } header.m_abbr_offset = abbr_entry->Offset; } - if (header.IsTypeUnit()) { - header.m_type_hash = data.GetU64(offset_ptr); - header.m_type_offset = data.GetDWARFOffset(offset_ptr); - } bool length_OK = data.ValidOffset(header.GetNextUnitOffset() - 1); bool version_OK = SymbolFileDWARF::SupportedVersion(header.m_version); @@ -997,7 +1005,7 @@ DWARFUnit::FindRnglistFromOffset(dw_offset_t offset) { } if (!GetRnglistTable()) - return llvm::createStringError(errc::invalid_argument, + return llvm::createStringError(std::errc::invalid_argument, "missing or invalid range list table"); llvm::DWARFDataExtractor data = GetRnglistData().GetAsLLVM(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index 2457e8276e20..265e28b51c99 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -11,8 +11,9 @@ #include "DWARFDIE.h" #include "DWARFDebugInfoEntry.h" -#include "lldb/lldb-enumerations.h" #include "lldb/Utility/XcodeSDK.h" +#include "lldb/lldb-enumerations.h" +#include "llvm/DebugInfo/DWARF/DWARFDebugRnglists.h" #include "llvm/Support/RWMutex.h" #include <atomic> @@ -68,7 +69,8 @@ public: dw_offset_t GetTypeOffset() const { return m_type_offset; } uint64_t GetDWOId() const { return m_dwo_id; } bool IsTypeUnit() const { - return m_unit_type == DW_UT_type || m_unit_type == DW_UT_split_type; + return m_unit_type == llvm::dwarf::DW_UT_type || + m_unit_type == llvm::dwarf::DW_UT_split_type; } uint32_t GetNextUnitOffset() const { return m_offset + m_length + 4; } @@ -153,7 +155,7 @@ public: const DWARFAbbreviationDeclarationSet *GetAbbreviations() const; dw_offset_t GetAbbrevOffset() const; uint8_t GetAddressByteSize() const { return m_header.GetAddressByteSize(); } - dw_addr_t GetAddrBase() const { return m_addr_base.getValueOr(0); } + dw_addr_t GetAddrBase() const { return m_addr_base.value_or(0); } dw_addr_t GetBaseAddress() const { return m_base_addr; } dw_offset_t GetLineTableOffset(); dw_addr_t GetRangesBase() const { return m_ranges_base; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp index 2350c8fc3d5b..ad22078ffa3e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DebugNamesDWARFIndex.cpp @@ -16,6 +16,7 @@ using namespace lldb_private; using namespace lldb; +using namespace lldb_private::dwarf; llvm::Expected<std::unique_ptr<DebugNamesDWARFIndex>> DebugNamesDWARFIndex::Create(Module &module, DWARFDataExtractor debug_names, @@ -64,8 +65,8 @@ bool DebugNamesDWARFIndex::ProcessEntry( llvm::Optional<DIERef> ref = ToDIERef(entry); if (!ref) return true; - SymbolFileDWARF &dwarf = - *llvm::cast<SymbolFileDWARF>(m_module.GetSymbolFile()); + SymbolFileDWARF &dwarf = *llvm::cast<SymbolFileDWARF>( + m_module.GetSymbolFile()->GetBackingSymbolFile()); DWARFDIE die = dwarf.GetDIE(*ref); if (!die) return true; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp index ce71281db8bd..fdc24e23d16b 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/HashedNameToDIE.cpp @@ -9,6 +9,8 @@ #include "HashedNameToDIE.h" #include "llvm/ADT/StringRef.h" +using namespace lldb_private::dwarf; + bool DWARFMappedHash::ExtractDIEArray( const DIEInfoArray &die_info_array, llvm::function_ref<bool(DIERef ref)> callback) { diff --git a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h index aa3ed4afed25..662aa6757e2f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.h @@ -10,6 +10,7 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_LOGCHANNELDWARF_H #include "lldb/Utility/Log.h" +#include "llvm/ADT/BitmaskEnum.h" namespace lldb_private { @@ -21,6 +22,7 @@ enum class DWARFLog : Log::MaskType { TypeCompletion = Log::ChannelFlag<4>, LLVM_MARK_AS_BITMASK_ENUM(TypeCompletion) }; +LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); class LogChannelDWARF { public: diff --git a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp index e8fbd5dd664b..b743c84c10e0 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/ManualDWARFIndex.cpp @@ -13,6 +13,7 @@ #include "Plugins/SymbolFile/DWARF/LogChannelDWARF.h" #include "Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h" #include "lldb/Core/DataFileCache.h" +#include "lldb/Core/Debugger.h" #include "lldb/Core/Module.h" #include "lldb/Core/Progress.h" #include "lldb/Symbol/ObjectFile.h" @@ -25,6 +26,7 @@ using namespace lldb_private; using namespace lldb; +using namespace lldb_private::dwarf; void ManualDWARFIndex::Index() { if (m_indexed) @@ -93,7 +95,7 @@ void ManualDWARFIndex::Index() { // Share one thread pool across operations to avoid the overhead of // recreating the threads. - llvm::ThreadPool pool(llvm::optimal_concurrency(units_to_index.size())); + llvm::ThreadPoolTaskGroup task_group(Debugger::GetThreadPool()); // Create a task runner that extracts dies for each DWARF unit in a // separate thread. @@ -104,14 +106,14 @@ void ManualDWARFIndex::Index() { // to wait until all units have been indexed in case a DIE in one // unit refers to another and the indexes accesses those DIEs. for (size_t i = 0; i < units_to_index.size(); ++i) - pool.async(extract_fn, i); - pool.wait(); + task_group.async(extract_fn, i); + task_group.wait(); // Now create a task runner that can index each DWARF unit in a // separate thread so we can index quickly. for (size_t i = 0; i < units_to_index.size(); ++i) - pool.async(parser_fn, i); - pool.wait(); + task_group.async(parser_fn, i); + task_group.wait(); auto finalize_fn = [this, &sets, &progress](NameToDIE(IndexSet::*index)) { NameToDIE &result = m_set.*index; @@ -121,15 +123,15 @@ void ManualDWARFIndex::Index() { progress.Increment(); }; - pool.async(finalize_fn, &IndexSet::function_basenames); - pool.async(finalize_fn, &IndexSet::function_fullnames); - pool.async(finalize_fn, &IndexSet::function_methods); - pool.async(finalize_fn, &IndexSet::function_selectors); - pool.async(finalize_fn, &IndexSet::objc_class_selectors); - pool.async(finalize_fn, &IndexSet::globals); - pool.async(finalize_fn, &IndexSet::types); - pool.async(finalize_fn, &IndexSet::namespaces); - pool.wait(); + task_group.async(finalize_fn, &IndexSet::function_basenames); + task_group.async(finalize_fn, &IndexSet::function_fullnames); + task_group.async(finalize_fn, &IndexSet::function_methods); + task_group.async(finalize_fn, &IndexSet::function_selectors); + task_group.async(finalize_fn, &IndexSet::objc_class_selectors); + task_group.async(finalize_fn, &IndexSet::globals); + task_group.async(finalize_fn, &IndexSet::types); + task_group.async(finalize_fn, &IndexSet::namespaces); + task_group.wait(); SaveToCache(); } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp index 413920f33619..de98403421e0 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/NameToDIE.cpp @@ -100,16 +100,27 @@ bool NameToDIE::Decode(const DataExtractor &data, lldb::offset_t *offset_ptr, if (identifier != kIdentifierNameToDIE) return false; const uint32_t count = data.GetU32(offset_ptr); + m_map.Reserve(count); for (uint32_t i = 0; i < count; ++i) { llvm::StringRef str(strtab.Get(data.GetU32(offset_ptr))); // No empty strings allowed in the name to DIE maps. if (str.empty()) return false; if (llvm::Optional<DIERef> die_ref = DIERef::Decode(data, offset_ptr)) - m_map.Append(ConstString(str), die_ref.getValue()); + m_map.Append(ConstString(str), *die_ref); else return false; } + // We must sort the UniqueCStringMap after decoding it since it is a vector + // of UniqueCStringMap::Entry objects which contain a ConstString and type T. + // ConstString objects are sorted by "const char *" and then type T and + // the "const char *" are point values that will depend on the order in which + // ConstString objects are created and in which of the 256 string pools they + // are created in. So after we decode all of the entries, we must sort the + // name map to ensure name lookups succeed. If we encode and decode within + // the same process we wouldn't need to sort, so unit testing didn't catch + // this issue when first checked in. + m_map.Sort(std::less<DIERef>()); return true; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 027a4caf5555..c0bf13e0281d 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -21,6 +21,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" @@ -95,6 +96,7 @@ using namespace lldb; using namespace lldb_private; +using namespace lldb_private::dwarf; LLDB_PLUGIN_DEFINE(SymbolFileDWARF) @@ -272,7 +274,7 @@ TypeList &SymbolFileDWARF::GetTypeList() { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile()) return debug_map_symfile->GetTypeList(); - return SymbolFile::GetTypeList(); + return SymbolFileCommon::GetTypeList(); } void SymbolFileDWARF::GetTypes(const DWARFDIE &die, dw_offset_t min_die_offset, dw_offset_t max_die_offset, uint32_t type_mask, @@ -405,7 +407,7 @@ SymbolFileDWARF::GetParentSymbolContextDIE(const DWARFDIE &child_die) { SymbolFileDWARF::SymbolFileDWARF(ObjectFileSP objfile_sp, SectionList *dwo_section_list) - : SymbolFile(std::move(objfile_sp)), + : SymbolFileCommon(std::move(objfile_sp)), UserID(0x7fffffff00000000), // Used by SymbolFileDWARFDebugMap to // when this class parses .o files to // contain the .o file index/ID @@ -564,23 +566,21 @@ uint32_t SymbolFileDWARF::CalculateAbilities() { if (section) debug_line_file_size = section->GetFileSize(); } else { - const char *symfile_dir_cstr = - m_objfile_sp->GetFileSpec().GetDirectory().GetCString(); - if (symfile_dir_cstr) { - if (strcasestr(symfile_dir_cstr, ".dsym")) { - if (m_objfile_sp->GetType() == ObjectFile::eTypeDebugInfo) { - // We have a dSYM file that didn't have a any debug info. If the - // string table has a size of 1, then it was made from an - // executable with no debug info, or from an executable that was - // stripped. - section = - section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true) - .get(); - if (section && section->GetFileSize() == 1) { - m_objfile_sp->GetModule()->ReportWarning( - "empty dSYM file detected, dSYM was created with an " - "executable with no debug info."); - } + llvm::StringRef symfile_dir = + m_objfile_sp->GetFileSpec().GetDirectory().GetStringRef(); + if (symfile_dir.contains_insensitive(".dsym")) { + if (m_objfile_sp->GetType() == ObjectFile::eTypeDebugInfo) { + // We have a dSYM file that didn't have a any debug info. If the + // string table has a size of 1, then it was made from an + // executable with no debug info, or from an executable that was + // stripped. + section = + section_list->FindSectionByType(eSectionTypeDWARFDebugStr, true) + .get(); + if (section && section->GetFileSize() == 1) { + m_objfile_sp->GetModule()->ReportWarning( + "empty dSYM file detected, dSYM was created with an " + "executable with no debug info."); } } } @@ -825,8 +825,8 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit, auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to parse function"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to parse function"); return nullptr; } DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser(); @@ -1371,9 +1371,9 @@ user_id_t SymbolFileDWARF::GetUID(DIERef ref) { if (GetDebugMapSymfile()) return GetID() | ref.die_offset(); - lldbassert(GetDwoNum().getValueOr(0) <= 0x3fffffff); - return user_id_t(GetDwoNum().getValueOr(0)) << 32 | ref.die_offset() | - lldb::user_id_t(GetDwoNum().hasValue()) << 62 | + lldbassert(GetDwoNum().value_or(0) <= 0x3fffffff); + return user_id_t(GetDwoNum().value_or(0)) << 32 | ref.die_offset() | + lldb::user_id_t(GetDwoNum().has_value()) << 62 | lldb::user_id_t(ref.section() == DIERef::Section::DebugTypes) << 63; } @@ -1744,8 +1744,14 @@ SymbolFileDWARF::GetDwoSymbolFileForCompileUnit( dwo_file.AppendPathComponent(dwo_name); } - if (!FileSystem::Instance().Exists(dwo_file)) + if (!FileSystem::Instance().Exists(dwo_file)) { + if (m_dwo_warning_issued.test_and_set(std::memory_order_relaxed) == false) { + GetObjectFile()->GetModule()->ReportWarning( + "unable to locate separate debug file (dwo, dwp). Debugging will be " + "degraded."); + } return nullptr; + } const lldb::offset_t file_offset = 0; DataBufferSP dwo_file_data_sp; @@ -1891,7 +1897,7 @@ SymbolFileDWARF::GlobalVariableMap &SymbolFileDWARF::GetGlobalAranges() { lldb::addr_t byte_size = 1; if (var_sp->GetType()) byte_size = - var_sp->GetType()->GetByteSize(nullptr).getValueOr(0); + var_sp->GetType()->GetByteSize(nullptr).value_or(0); m_global_aranges_up->Append(GlobalVariableMap::Entry( file_addr, byte_size, var_sp.get())); } @@ -2098,8 +2104,7 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile( auto type_system_or_err = GetTypeSystemForLanguage( decl_ctx_type_system->GetMinimumLanguage(nullptr)); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), "Unable to match namespace decl using TypeSystem"); return false; } @@ -2868,10 +2873,9 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext( if (language != eLanguageTypeUnknown) { auto type_system_or_err = GetTypeSystemForLanguage(language); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR( - lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Cannot get TypeSystem for language {}", - Language::GetNameForLanguageType(language)); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Cannot get TypeSystem for language {}", + Language::GetNameForLanguageType(language)); } else { type_system = &type_system_or_err.get(); } @@ -2967,8 +2971,8 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die, auto type_system_or_err = GetTypeSystemForLanguage(GetLanguage(*die.GetCU())); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to parse type"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to parse type"); return {}; } @@ -3240,7 +3244,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, DataExtractor data = die.GetCU()->GetLocationData(); dw_offset_t offset = location_form.Unsigned(); if (location_form.Form() == DW_FORM_loclistx) - offset = die.GetCU()->GetLoclistOffset(offset).getValueOr(-1); + offset = die.GetCU()->GetLoclistOffset(offset).value_or(-1); if (data.ValidOffset(offset)) { data = DataExtractor(data, offset, data.GetByteSize() - offset); location = DWARFExpression(module, data, die.GetCU()); @@ -3461,7 +3465,7 @@ VariableSP SymbolFileDWARF::ParseVariableDIE(const SymbolContext &sc, if (use_type_size_for_value && type_sp->GetType()) location.UpdateValue(const_value_form.Unsigned(), - type_sp->GetType()->GetByteSize(nullptr).getValueOr(0), + type_sp->GetType()->GetByteSize(nullptr).value_or(0), die.GetCU()->GetAddressByteSize()); return std::make_shared<Variable>( @@ -3801,7 +3805,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) { if (!has_call_edges) return {}; - Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP)); + Log *log = GetLog(LLDBLog::Step); LLDB_LOG(log, "CollectCallEdges: Found call site info in {0}", function_die.GetPubname()); @@ -3924,7 +3928,7 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) { if (log) { StreamString call_target_desc; call_target->GetDescription(&call_target_desc, eDescriptionLevelBrief, - LLDB_INVALID_ADDRESS, nullptr); + nullptr); LLDB_LOG(log, "CollectCallEdges: Found indirect call target: {0}", call_target_desc.GetString()); } @@ -3937,11 +3941,9 @@ SymbolFileDWARF::CollectCallEdges(ModuleSP module, DWARFDIE function_die) { for (const CallSiteParameter ¶m : parameters) { StreamString callee_loc_desc, caller_loc_desc; param.LocationInCallee.GetDescription(&callee_loc_desc, - eDescriptionLevelBrief, - LLDB_INVALID_ADDRESS, nullptr); + eDescriptionLevelBrief, nullptr); param.LocationInCaller.GetDescription(&caller_loc_desc, - eDescriptionLevelBrief, - LLDB_INVALID_ADDRESS, nullptr); + eDescriptionLevelBrief, nullptr); LLDB_LOG(log, "CollectCallEdges: \tparam: {0} => {1}", callee_loc_desc.GetString(), caller_loc_desc.GetString()); } @@ -3966,7 +3968,7 @@ SymbolFileDWARF::ParseCallEdgesInFunction(UserID func_id) { } void SymbolFileDWARF::Dump(lldb_private::Stream &s) { - SymbolFile::Dump(s); + SymbolFileCommon::Dump(s); m_index->Dump(s); } @@ -3985,8 +3987,8 @@ SymbolFileDWARFDebugMap *SymbolFileDWARF::GetDebugMapSymfile() { if (m_debug_map_symfile == nullptr) { lldb::ModuleSP module_sp(m_debug_map_module_wp.lock()); if (module_sp) { - m_debug_map_symfile = - static_cast<SymbolFileDWARFDebugMap *>(module_sp->GetSymbolFile()); + m_debug_map_symfile = llvm::cast<SymbolFileDWARFDebugMap>( + module_sp->GetSymbolFile()->GetBackingSymbolFile()); } } return m_debug_map_symfile; @@ -4025,8 +4027,8 @@ llvm::Expected<TypeSystem &> SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) { DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DWARFUnit &unit) { auto type_system_or_err = GetTypeSystem(unit); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get DWARFASTParser"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get DWARFASTParser"); return nullptr; } return type_system_or_err->GetDWARFParser(); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index f84a78620e17..2403ee2624ea 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -56,7 +56,7 @@ class SymbolFileDWARFDwp; #define DIE_IS_BEING_PARSED ((lldb_private::Type *)1) -class SymbolFileDWARF : public lldb_private::SymbolFile, +class SymbolFileDWARF : public lldb_private::SymbolFileCommon, public lldb_private::UserID { /// LLVM RTTI support. static char ID; @@ -65,7 +65,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} @@ -560,6 +560,7 @@ protected: /// address in the module. lldb::addr_t m_first_code_address = LLDB_INVALID_ADDRESS; lldb_private::StatsDuration m_parse_time; + std::atomic_flag m_dwo_warning_issued = ATOMIC_FLAG_INIT; }; #endif // LLDB_SOURCE_PLUGINS_SYMBOLFILE_DWARF_SYMBOLFILEDWARF_H diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp index 08bfe37fd92f..7637726892a0 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -237,7 +237,7 @@ SymbolFile *SymbolFileDWARFDebugMap::CreateInstance(ObjectFileSP objfile_sp) { } SymbolFileDWARFDebugMap::SymbolFileDWARFDebugMap(ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(), + : SymbolFileCommon(std::move(objfile_sp)), m_flags(), m_compile_unit_infos(), m_func_indexes(), m_glob_indexes(), m_supports_DW_AT_APPLE_objc_complete_type(eLazyBoolCalculate) {} @@ -409,7 +409,6 @@ Module *SymbolFileDWARFDebugMap::GetModuleByCompUnitInfo( FileSpec oso_file(oso_path); ConstString oso_object; if (FileSystem::Instance().Exists(oso_file)) { - FileSystem::Instance().Collect(oso_file); // The modification time returned by the FS can have a higher precision // than the one from the CU. auto oso_mod_time = std::chrono::time_point_cast<std::chrono::seconds>( @@ -1185,25 +1184,13 @@ void SymbolFileDWARFDebugMap::FindTypes( llvm::ArrayRef<CompilerContext> context, LanguageSet languages, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap &types) { + LLDB_SCOPED_TIMER(); ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { oso_dwarf->FindTypes(context, languages, searched_symbol_files, types); return false; }); } -// -// uint32_t -// SymbolFileDWARFDebugMap::FindTypes (const SymbolContext& sc, const -// RegularExpression& regex, bool append, uint32_t max_matches, Type::Encoding -// encoding, lldb::user_id_t udt_uid, TypeList& types) -//{ -// SymbolFileDWARF *oso_dwarf = GetSymbolFile (sc); -// if (oso_dwarf) -// return oso_dwarf->FindTypes (sc, regex, append, max_matches, encoding, -// udt_uid, types); -// return 0; -//} - CompilerDeclContext SymbolFileDWARFDebugMap::FindNamespace( lldb_private::ConstString name, const CompilerDeclContext &parent_decl_ctx) { @@ -1430,53 +1417,16 @@ SymbolFileDWARFDebugMap::AddOSOARanges(SymbolFileDWARF *dwarf2Data, return num_line_entries_added; } -uint64_t SymbolFileDWARFDebugMap::GetDebugInfoSize() { - uint64_t debug_info_size = 0; - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); - if (!oso_objfile) - return false; // Keep iterating - ModuleSP module_sp = oso_objfile->GetModule(); - if (!module_sp) - return false; // Keep iterating - SectionList *section_list = module_sp->GetSectionList(); - if (section_list) - debug_info_size += section_list->GetDebugInfoSize(); - return false; // Keep iterating - }); - return debug_info_size; -} - -StatsDuration::Duration SymbolFileDWARFDebugMap::GetDebugInfoParseTime() { - StatsDuration::Duration elapsed(0.0); +ModuleList SymbolFileDWARFDebugMap::GetDebugInfoModules() { + ModuleList oso_modules; ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); if (oso_objfile) { ModuleSP module_sp = oso_objfile->GetModule(); - if (module_sp) { - SymbolFile *symfile = module_sp->GetSymbolFile(); - if (symfile) - elapsed += symfile->GetDebugInfoParseTime(); - } - } - return false; // Keep iterating - }); - return elapsed; -} - -StatsDuration::Duration SymbolFileDWARFDebugMap::GetDebugInfoIndexTime() { - StatsDuration::Duration elapsed(0.0); - ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - ObjectFile *oso_objfile = oso_dwarf->GetObjectFile(); - if (oso_objfile) { - ModuleSP module_sp = oso_objfile->GetModule(); - if (module_sp) { - SymbolFile *symfile = module_sp->GetSymbolFile(); - if (symfile) - elapsed += symfile->GetDebugInfoIndexTime(); - } + if (module_sp) + oso_modules.Append(module_sp); } return false; // Keep iterating }); - return elapsed; + return oso_modules; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h index 2a6232a501b4..52c4d77a10b6 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -22,7 +22,7 @@ class SymbolFileDWARF; class DWARFDebugAranges; class DWARFDeclContext; -class SymbolFileDWARFDebugMap : public lldb_private::SymbolFile { +class SymbolFileDWARFDebugMap : public lldb_private::SymbolFileCommon { /// LLVM RTTI support. static char ID; @@ -30,7 +30,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} @@ -142,9 +142,8 @@ public: // PluginInterface protocol llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } - uint64_t GetDebugInfoSize() override; - lldb_private::StatsDuration::Duration GetDebugInfoParseTime() override; - lldb_private::StatsDuration::Duration GetDebugInfoIndexTime() override; + // Statistics overrides. + lldb_private::ModuleList GetDebugInfoModules() override; protected: enum { kHaveInitializedOSOs = (1 << 0), kNumFlags }; diff --git a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp index 34ff23667465..22a921cf6138 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/UniqueDWARFASTType.cpp @@ -10,6 +10,8 @@ #include "lldb/Core/Declaration.h" +using namespace lldb_private::dwarf; + bool UniqueDWARFASTTypeList::Find(const DWARFDIE &die, const lldb_private::Declaration &decl, const int32_t byte_size, diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp index ca9ddcec287f..3d8030916c84 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CodeViewRegisterMapping.cpp @@ -10,10 +10,196 @@ #include "lldb/lldb-defines.h" +#include "Plugins/Process/Utility/lldb-arm64-register-enums.h" #include "Plugins/Process/Utility/lldb-x86-register-enums.h" using namespace lldb_private; +static const uint32_t g_code_view_to_lldb_registers_arm64[] = { + LLDB_INVALID_REGNUM, // NONE + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_w0_arm64, // ARM64_W0, 10) + gpr_w1_arm64, // ARM64_W1, 11) + gpr_w2_arm64, // ARM64_W2, 12) + gpr_w3_arm64, // ARM64_W3, 13) + gpr_w4_arm64, // ARM64_W4, 14) + gpr_w5_arm64, // ARM64_W5, 15) + gpr_w6_arm64, // ARM64_W6, 16) + gpr_w7_arm64, // ARM64_W7, 17) + gpr_w8_arm64, // ARM64_W8, 18) + gpr_w9_arm64, // ARM64_W9, 19) + gpr_w10_arm64, // ARM64_W10, 20) + gpr_w11_arm64, // ARM64_W11, 21) + gpr_w12_arm64, // ARM64_W12, 22) + gpr_w13_arm64, // ARM64_W13, 23) + gpr_w14_arm64, // ARM64_W14, 24) + gpr_w15_arm64, // ARM64_W15, 25) + gpr_w16_arm64, // ARM64_W16, 26) + gpr_w17_arm64, // ARM64_W17, 27) + gpr_w18_arm64, // ARM64_W18, 28) + gpr_w19_arm64, // ARM64_W19, 29) + gpr_w20_arm64, // ARM64_W20, 30) + gpr_w21_arm64, // ARM64_W21, 31) + gpr_w22_arm64, // ARM64_W22, 32) + gpr_w23_arm64, // ARM64_W23, 33) + gpr_w24_arm64, // ARM64_W24, 34) + gpr_w25_arm64, // ARM64_W25, 35) + gpr_w26_arm64, // ARM64_W26, 36) + gpr_w27_arm64, // ARM64_W27, 37) + gpr_w28_arm64, // ARM64_W28, 38) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_x0_arm64, // ARM64_X0, 50) + gpr_x1_arm64, // ARM64_X1, 51) + gpr_x2_arm64, // ARM64_X2, 52) + gpr_x3_arm64, // ARM64_X3, 53) + gpr_x4_arm64, // ARM64_X4, 54) + gpr_x5_arm64, // ARM64_X5, 55) + gpr_x6_arm64, // ARM64_X6, 56) + gpr_x7_arm64, // ARM64_X7, 57) + gpr_x8_arm64, // ARM64_X8, 58) + gpr_x9_arm64, // ARM64_X9, 59) + gpr_x10_arm64, // ARM64_X10, 60) + gpr_x11_arm64, // ARM64_X11, 61) + gpr_x12_arm64, // ARM64_X12, 62) + gpr_x13_arm64, // ARM64_X13, 63) + gpr_x14_arm64, // ARM64_X14, 64) + gpr_x15_arm64, // ARM64_X15, 65) + gpr_x16_arm64, // ARM64_X16, 66) + gpr_x17_arm64, // ARM64_X17, 67) + gpr_x18_arm64, // ARM64_X18, 68) + gpr_x19_arm64, // ARM64_X19, 69) + gpr_x20_arm64, // ARM64_X20, 70) + gpr_x21_arm64, // ARM64_X21, 71) + gpr_x22_arm64, // ARM64_X22, 72) + gpr_x23_arm64, // ARM64_X23, 73) + gpr_x24_arm64, // ARM64_X24, 74) + gpr_x25_arm64, // ARM64_X25, 75) + gpr_x26_arm64, // ARM64_X26, 76) + gpr_x27_arm64, // ARM64_X27, 77) + gpr_x28_arm64, // ARM64_X28, 78) + gpr_fp_arm64, // ARM64_FP, 79) + gpr_lr_arm64, // ARM64_LR, 80) + gpr_sp_arm64, // ARM64_SP, 81) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + gpr_cpsr_arm64, // ARM64_NZCV, 90) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_s0_arm64, // (ARM64_S0, 100) + fpu_s1_arm64, // (ARM64_S1, 101) + fpu_s2_arm64, // (ARM64_S2, 102) + fpu_s3_arm64, // (ARM64_S3, 103) + fpu_s4_arm64, // (ARM64_S4, 104) + fpu_s5_arm64, // (ARM64_S5, 105) + fpu_s6_arm64, // (ARM64_S6, 106) + fpu_s7_arm64, // (ARM64_S7, 107) + fpu_s8_arm64, // (ARM64_S8, 108) + fpu_s9_arm64, // (ARM64_S9, 109) + fpu_s10_arm64, // (ARM64_S10, 110) + fpu_s11_arm64, // (ARM64_S11, 111) + fpu_s12_arm64, // (ARM64_S12, 112) + fpu_s13_arm64, // (ARM64_S13, 113) + fpu_s14_arm64, // (ARM64_S14, 114) + fpu_s15_arm64, // (ARM64_S15, 115) + fpu_s16_arm64, // (ARM64_S16, 116) + fpu_s17_arm64, // (ARM64_S17, 117) + fpu_s18_arm64, // (ARM64_S18, 118) + fpu_s19_arm64, // (ARM64_S19, 119) + fpu_s20_arm64, // (ARM64_S20, 120) + fpu_s21_arm64, // (ARM64_S21, 121) + fpu_s22_arm64, // (ARM64_S22, 122) + fpu_s23_arm64, // (ARM64_S23, 123) + fpu_s24_arm64, // (ARM64_S24, 124) + fpu_s25_arm64, // (ARM64_S25, 125) + fpu_s26_arm64, // (ARM64_S26, 126) + fpu_s27_arm64, // (ARM64_S27, 127) + fpu_s28_arm64, // (ARM64_S28, 128) + fpu_s29_arm64, // (ARM64_S29, 129) + fpu_s30_arm64, // (ARM64_S30, 130) + fpu_s31_arm64, // (ARM64_S31, 131) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_d0_arm64, // (ARM64_D0, 140) + fpu_d1_arm64, // (ARM64_D1, 141) + fpu_d2_arm64, // (ARM64_D2, 142) + fpu_d3_arm64, // (ARM64_D3, 143) + fpu_d4_arm64, // (ARM64_D4, 144) + fpu_d5_arm64, // (ARM64_D5, 145) + fpu_d6_arm64, // (ARM64_D6, 146) + fpu_d7_arm64, // (ARM64_D7, 147) + fpu_d8_arm64, // (ARM64_D8, 148) + fpu_d9_arm64, // (ARM64_D9, 149) + fpu_d10_arm64, // (ARM64_D10, 150) + fpu_d11_arm64, // (ARM64_D11, 151) + fpu_d12_arm64, // (ARM64_D12, 152) + fpu_d13_arm64, // (ARM64_D13, 153) + fpu_d14_arm64, // (ARM64_D14, 154) + fpu_d15_arm64, // (ARM64_D15, 155) + fpu_d16_arm64, // (ARM64_D16, 156) + fpu_d17_arm64, // (ARM64_D17, 157) + fpu_d18_arm64, // (ARM64_D18, 158) + fpu_d19_arm64, // (ARM64_D19, 159) + fpu_d20_arm64, // (ARM64_D20, 160) + fpu_d21_arm64, // (ARM64_D21, 161) + fpu_d22_arm64, // (ARM64_D22, 162) + fpu_d23_arm64, // (ARM64_D23, 163) + fpu_d24_arm64, // (ARM64_D24, 164) + fpu_d25_arm64, // (ARM64_D25, 165) + fpu_d26_arm64, // (ARM64_D26, 166) + fpu_d27_arm64, // (ARM64_D27, 167) + fpu_d28_arm64, // (ARM64_D28, 168) + fpu_d29_arm64, // (ARM64_D29, 169) + fpu_d30_arm64, // (ARM64_D30, 170) + fpu_d31_arm64, // (ARM64_D31, 171) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_v0_arm64, // (ARM64_Q0, 180) + fpu_v1_arm64, // (ARM64_Q1, 181) + fpu_v2_arm64, // (ARM64_Q2, 182) + fpu_v3_arm64, // (ARM64_Q3, 183) + fpu_v4_arm64, // (ARM64_Q4, 184) + fpu_v5_arm64, // (ARM64_Q5, 185) + fpu_v6_arm64, // (ARM64_Q6, 186) + fpu_v7_arm64, // (ARM64_Q7, 187) + fpu_v8_arm64, // (ARM64_Q8, 188) + fpu_v9_arm64, // (ARM64_Q9, 189) + fpu_v10_arm64, // (ARM64_Q10, 190) + fpu_v11_arm64, // (ARM64_Q11, 191) + fpu_v12_arm64, // (ARM64_Q12, 192) + fpu_v13_arm64, // (ARM64_Q13, 193) + fpu_v14_arm64, // (ARM64_Q14, 194) + fpu_v15_arm64, // (ARM64_Q15, 195) + fpu_v16_arm64, // (ARM64_Q16, 196) + fpu_v17_arm64, // (ARM64_Q17, 197) + fpu_v18_arm64, // (ARM64_Q18, 198) + fpu_v19_arm64, // (ARM64_Q19, 199) + fpu_v20_arm64, // (ARM64_Q20, 200) + fpu_v21_arm64, // (ARM64_Q21, 201) + fpu_v22_arm64, // (ARM64_Q22, 202) + fpu_v23_arm64, // (ARM64_Q23, 203) + fpu_v24_arm64, // (ARM64_Q24, 204) + fpu_v25_arm64, // (ARM64_Q25, 205) + fpu_v26_arm64, // (ARM64_Q26, 206) + fpu_v27_arm64, // (ARM64_Q27, 207) + fpu_v28_arm64, // (ARM64_Q28, 208) + fpu_v29_arm64, // (ARM64_Q29, 209) + fpu_v30_arm64, // (ARM64_Q30, 210) + fpu_v31_arm64, // (ARM64_Q31, 211) + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, + fpu_fpsr_arm64 // ARM64_FPSR, 220) +}; + static const uint32_t g_code_view_to_lldb_registers_x86[] = { LLDB_INVALID_REGNUM, // NONE lldb_al_i386, // AL @@ -424,6 +610,14 @@ static const uint32_t g_code_view_to_lldb_registers_x86_64[] = { uint32_t lldb_private::npdb::GetLLDBRegisterNumber( llvm::Triple::ArchType arch_type, llvm::codeview::RegisterId register_id) { switch (arch_type) { + case llvm::Triple::aarch64: + if (static_cast<uint16_t>(register_id) < + sizeof(g_code_view_to_lldb_registers_arm64) / + sizeof(g_code_view_to_lldb_registers_arm64[0])) + return g_code_view_to_lldb_registers_arm64[static_cast<uint16_t>( + register_id)]; + + return LLDB_INVALID_REGNUM; case llvm::Triple::x86: if (static_cast<uint16_t>(register_id) < sizeof(g_code_view_to_lldb_registers_x86) / diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp index d8f737612c25..d15c0ee99f96 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/CompileUnitIndex.cpp @@ -162,7 +162,7 @@ CompilandIndexItem &CompileUnitIndex::GetOrCreateCompiland(uint16_t modi) { ParseExtendedInfo(m_index, *cci); ParseInlineeLineTableForCompileUnit(*cci); - cci->m_strings.initialize(debug_stream.getSubsectionsArray()); + cci->m_strings.initialize(cci->m_debug_stream.getSubsectionsArray()); PDBStringTable &strings = cantFail(m_index.pdb().getStringTable()); cci->m_strings.setStrings(strings.getStringTable()); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp index d0672352a58f..3ba0079c96e6 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.cpp @@ -250,3 +250,30 @@ DWARFExpression lldb_private::npdb::MakeConstantLocationExpression( DWARFExpression result(nullptr, extractor, nullptr); return result; } + +DWARFExpression lldb_private::npdb::MakeEnregisteredLocationExpressionForClass( + std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info, + lldb::ModuleSP module) { + return MakeLocationExpressionInternal( + module, [&](Stream &stream, RegisterKind ®ister_kind) -> bool { + for (auto pair : members_info) { + std::pair<RegisterId, uint32_t> member_info = pair.second; + if (member_info.first != llvm::codeview::RegisterId::NONE) { + uint32_t reg_num = + GetRegisterNumber(module->GetArchitecture().GetMachine(), + member_info.first, register_kind); + if (reg_num == LLDB_INVALID_REGNUM) + return false; + if (reg_num > 31) { + stream.PutHex8(llvm::dwarf::DW_OP_regx); + stream.PutULEB128(reg_num); + } else { + stream.PutHex8(llvm::dwarf::DW_OP_reg0 + reg_num); + } + } + stream.PutHex8(llvm::dwarf::DW_OP_piece); + stream.PutULEB128(member_info.second); + } + return true; + }); +} diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h index 99da09b70fe1..1ed6c55fea74 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/DWARFLocationExpression.h @@ -10,7 +10,9 @@ #define LLDB_SOURCE_PLUGINS_SYMBOLFILE_NATIVEPDB_DWARFLOCATIONEXPRESSION_H #include "lldb/lldb-forward.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/DebugInfo/CodeView/CodeView.h" +#include <map> namespace llvm { class APSInt; @@ -39,6 +41,10 @@ DWARFExpression MakeGlobalLocationExpression(uint16_t section, uint32_t offset, DWARFExpression MakeConstantLocationExpression( llvm::codeview::TypeIndex underlying_ti, llvm::pdb::TpiStream &tpi, const llvm::APSInt &constant, lldb::ModuleSP module); +DWARFExpression MakeEnregisteredLocationExpressionForClass( + std::map<uint64_t, std::pair<llvm::codeview::RegisterId, uint32_t>> + &members_info, + lldb::ModuleSP module); } // namespace npdb } // namespace lldb_private diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index dc0969a0ce7c..6dcce738b79f 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -118,12 +118,6 @@ static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index, std::vector<PdbCompilandSymId> scope_stack; while (begin != end) { - if (id.offset == begin.offset()) { - // We have a match! Return the top of the stack - if (scope_stack.empty()) - return llvm::None; - return scope_stack.back(); - } if (begin.offset() > id.offset) { // We passed it. We couldn't even find this symbol record. lldbassert(false && "Invalid compiland symbol id!"); @@ -136,7 +130,7 @@ static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index, // We can use the end offset of the scope to determine whether or not // we can just outright skip this entire scope. uint32_t scope_end = getScopeEndOffset(*begin); - if (scope_end < id.modi) { + if (scope_end < id.offset) { begin = syms.at(scope_end); } else { // The symbol we're looking for is somewhere in this scope. @@ -147,8 +141,10 @@ static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index, } ++begin; } - - return llvm::None; + if (scope_stack.empty()) + return llvm::None; + // We have a match! Return the top of the stack + return scope_stack.back(); } static clang::TagTypeKind TranslateUdtKind(const TagRecord &cr) { @@ -327,6 +323,8 @@ PdbAstBuilder::CreateDeclInfoForType(const TagRecord &record, TypeIndex ti) { // LLDB TypeSP for the parent. This will cause the AST to automatically get // the right DeclContext created for any parent. clang::QualType parent_qt = GetOrCreateType(parent_iter->second); + if (parent_qt.isNull()) + return {nullptr, ""}; context = clang::TagDecl::castToDeclContext(parent_qt->getAsTagDecl()); return {context, uname}; @@ -403,10 +401,13 @@ void PdbAstBuilder::BuildParentMap() { } }; - CVType field_list = m_index.tpi().getType(tag.asTag().FieldList); + CVType field_list_cvt = m_index.tpi().getType(tag.asTag().FieldList); ProcessTpiStream process(m_index, *ti, tag, m_parent_types); - llvm::Error error = visitMemberRecordStream(field_list.data(), process); - if (error) + FieldListRecord field_list; + if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); + if (llvm::Error error = visitMemberRecordStream(field_list.Data, process)) llvm::consumeError(std::move(error)); } @@ -501,7 +502,8 @@ clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) { if (isLocalVariableType(cvs.kind())) { clang::DeclContext *scope = GetParentDeclContext(id); clang::Decl *scope_decl = clang::Decl::castFromDeclContext(scope); - PdbCompilandSymId scope_id(id.modi, m_decl_to_status[scope_decl].uid); + PdbCompilandSymId scope_id = + PdbSymUid(m_decl_to_status[scope_decl].uid).asCompilandSym(); return GetOrCreateVariableDecl(scope_id, id); } @@ -517,6 +519,8 @@ clang::Decl *PdbAstBuilder::GetOrCreateSymbolForId(PdbCompilandSymId id) { return nullptr; case S_BLOCK32: return GetOrCreateBlockDecl(id); + case S_INLINESITE: + return GetOrCreateInlinedFunctionDecl(id); default: return nullptr; } @@ -533,6 +537,8 @@ llvm::Optional<CompilerDecl> PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) break; case PdbSymUidKind::Type: { clang::QualType qt = GetOrCreateType(uid.asTypeSym()); + if (qt.isNull()) + return llvm::None; if (auto *tag = qt->getAsTagDecl()) { result = tag; break; @@ -542,6 +548,9 @@ llvm::Optional<CompilerDecl> PdbAstBuilder::GetOrCreateDeclForUid(PdbSymUid uid) default: return llvm::None; } + + if (!result) + return llvm::None; m_uid_to_decl[toOpaqueUid(uid)] = result; return ToCompilerDecl(*result); } @@ -554,7 +563,7 @@ clang::DeclContext *PdbAstBuilder::GetOrCreateDeclContextForUid(PdbSymUid uid) { auto option = GetOrCreateDeclForUid(uid); if (!option) return nullptr; - clang::Decl *decl = FromCompilerDecl(option.getValue()); + clang::Decl *decl = FromCompilerDecl(*option); if (!decl) return nullptr; @@ -579,6 +588,8 @@ PdbAstBuilder::CreateDeclInfoForUndecoratedName(llvm::StringRef name) { std::vector<TypeIndex> types = m_index.tpi().findRecordsByName(scope_name); while (!types.empty()) { clang::QualType qt = GetOrCreateType(types.back()); + if (qt.isNull()) + continue; clang::TagDecl *tag = qt->getAsTagDecl(); if (tag) return {clang::TagDecl::castToDeclContext(tag), std::string(uname)}; @@ -620,6 +631,8 @@ PdbAstBuilder::GetParentDeclContextForSymbol(const CVSymbol &sym) { std::vector<TypeIndex> matches = m_index.tpi().findRecordsByName(qname); while (!matches.empty()) { clang::QualType qt = GetOrCreateType(matches.back()); + if (qt.isNull()) + continue; clang::TagDecl *tag = qt->getAsTagDecl(); if (tag) return clang::TagDecl::castToDeclContext(tag); @@ -698,7 +711,13 @@ clang::DeclContext *PdbAstBuilder::GetParentDeclContext(PdbSymUid uid) { } bool PdbAstBuilder::CompleteType(clang::QualType qt) { + if (qt.isNull()) + return false; clang::TagDecl *tag = qt->getAsTagDecl(); + if (qt->isArrayType()) { + const clang::Type *element_type = qt->getArrayElementTypeNoTypeQual(); + tag = element_type->getAsTagDecl(); + } if (!tag) return false; @@ -741,22 +760,26 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) { CVType field_list_cvt = m_index.tpi().getType(field_list_ti); if (field_list_cvt.kind() != LF_FIELDLIST) return false; + FieldListRecord field_list; + if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); // Visit all members of this class, then perform any finalization necessary // to complete the class. CompilerType ct = ToCompilerType(tag_qt); UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index, m_cxx_record_map); - auto error = - llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer); + llvm::Error error = + llvm::codeview::visitMemberRecordStream(field_list.Data, completer); completer.complete(); status.resolved = true; - if (!error) - return true; - - llvm::consumeError(std::move(error)); - return false; + if (error) { + llvm::consumeError(std::move(error)); + return false; + } + return true; } clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) { @@ -765,6 +788,8 @@ clang::QualType PdbAstBuilder::CreateSimpleType(TypeIndex ti) { if (ti.getSimpleMode() != SimpleTypeMode::Direct) { clang::QualType direct_type = GetOrCreateType(ti.makeDirect()); + if (direct_type.isNull()) + return {}; return m_clang.getASTContext().getPointerType(direct_type); } @@ -789,7 +814,8 @@ clang::QualType PdbAstBuilder::CreatePointerType(const PointerRecord &pointer) { if (pointer.isPointerToMember()) { MemberPointerInfo mpi = pointer.getMemberInfo(); clang::QualType class_type = GetOrCreateType(mpi.ContainingType); - + if (class_type.isNull()) + return {}; return m_clang.getASTContext().getMemberPointerType( pointee_type, class_type.getTypePtr()); } @@ -833,6 +859,9 @@ clang::QualType PdbAstBuilder::CreateRecordType(PdbTypeSymId id, clang::DeclContext *context = nullptr; std::string uname; std::tie(context, uname) = CreateDeclInfoForType(record, id.index); + if (!context) + return {}; + clang::TagTypeKind ttk = TranslateUdtKind(record); lldb::AccessType access = (ttk == clang::TTK_Class) ? lldb::eAccessPrivate : lldb::eAccessPublic; @@ -897,6 +926,8 @@ clang::VarDecl *PdbAstBuilder::CreateVariableDecl(PdbSymUid uid, CVSymbol sym, clang::DeclContext &scope) { VariableInfo var_info = GetVariableNameInfo(sym); clang::QualType qt = GetOrCreateType(var_info.type); + if (qt.isNull()) + return nullptr; clang::VarDecl *var_decl = m_clang.CreateVariableDeclaration( &scope, OptionalClangModuleID(), var_info.name.str().c_str(), qt); @@ -916,6 +947,8 @@ PdbAstBuilder::GetOrCreateVariableDecl(PdbCompilandSymId scope_id, return llvm::dyn_cast<clang::VarDecl>(decl); clang::DeclContext *scope = GetOrCreateDeclContextForUid(scope_id); + if (!scope) + return nullptr; CVSymbol sym = m_index.ReadSymbolRecord(var_id); return CreateVariableDecl(PdbSymUid(var_id), sym, *scope); @@ -943,6 +976,8 @@ PdbAstBuilder::GetOrCreateTypedefDecl(PdbGlobalSymId id) { PdbTypeSymId real_type_id{udt.Type, false}; clang::QualType qt = GetOrCreateType(real_type_id); + if (qt.isNull()) + return nullptr; std::string uname = std::string(DropNameScope(udt.Name)); @@ -1013,6 +1048,9 @@ clang::QualType PdbAstBuilder::CreateType(PdbTypeSymId type) { } clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) { + if (type.index.isNoneType()) + return {}; + lldb::user_id_t uid = toOpaqueUid(type); auto iter = m_uid_to_type.find(uid); if (iter != m_uid_to_type.end()) @@ -1025,6 +1063,8 @@ clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) { // This is a forward decl. Call GetOrCreate on the full decl, then map the // forward decl id to the full decl QualType. clang::QualType qt = GetOrCreateType(best_type); + if (qt.isNull()) + return {}; m_uid_to_type[toOpaqueUid(type)] = qt; return qt; } @@ -1032,6 +1072,9 @@ clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) { // This is either a full decl, or a forward decl with no matching full decl // in the debug info. qt = CreateType(type); + if (qt.isNull()) + return {}; + m_uid_to_type[toOpaqueUid(type)] = qt; if (IsTagRecord(type, m_index.tpi())) { clang::TagDecl *tag = qt->getAsTagDecl(); @@ -1045,40 +1088,11 @@ clang::QualType PdbAstBuilder::GetOrCreateType(PdbTypeSymId type) { } clang::FunctionDecl * -PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { - if (clang::Decl *decl = TryGetDecl(func_id)) - return llvm::dyn_cast<clang::FunctionDecl>(decl); - - clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id)); - std::string context_name; - if (clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(parent)) { - context_name = ns->getQualifiedNameAsString(); - } else if (clang::TagDecl *tag = llvm::dyn_cast<clang::TagDecl>(parent)) { - context_name = tag->getQualifiedNameAsString(); - } - - CVSymbol cvs = m_index.ReadSymbolRecord(func_id); - ProcSym proc(static_cast<SymbolRecordKind>(cvs.kind())); - llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(cvs, proc)); - - PdbTypeSymId type_id(proc.FunctionType); - clang::QualType qt = GetOrCreateType(type_id); - if (qt.isNull()) - return nullptr; - - clang::StorageClass storage = clang::SC_None; - if (proc.Kind == SymbolRecordKind::ProcSym) - storage = clang::SC_Static; - - const clang::FunctionProtoType *func_type = - llvm::dyn_cast<clang::FunctionProtoType>(qt); - - CompilerType func_ct = ToCompilerType(qt); - - llvm::StringRef proc_name = proc.Name; - proc_name.consume_front(context_name); - proc_name.consume_front("::"); - +PdbAstBuilder::CreateFunctionDecl(PdbCompilandSymId func_id, + llvm::StringRef func_name, TypeIndex func_ti, + CompilerType func_ct, uint32_t param_count, + clang::StorageClass func_storage, + bool is_inline, clang::DeclContext *parent) { clang::FunctionDecl *function_decl = nullptr; if (parent->isRecord()) { clang::QualType parent_qt = llvm::cast<clang::TypeDecl>(parent) @@ -1086,55 +1100,186 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { ->getCanonicalTypeInternal(); lldb::opaque_compiler_type_t parent_opaque_ty = ToCompilerType(parent_qt).GetOpaqueQualType(); - + // FIXME: Remove this workaround. auto iter = m_cxx_record_map.find(parent_opaque_ty); if (iter != m_cxx_record_map.end()) { - if (iter->getSecond().contains({proc_name, func_ct})) { + if (iter->getSecond().contains({func_name, func_ct})) { return nullptr; } } - CVType cvt = m_index.tpi().getType(type_id.index); + CVType cvt = m_index.tpi().getType(func_ti); MemberFunctionRecord func_record(static_cast<TypeRecordKind>(cvt.kind())); llvm::cantFail(TypeDeserializer::deserializeAs<MemberFunctionRecord>( cvt, func_record)); TypeIndex class_index = func_record.getClassType(); + CVType parent_cvt = m_index.tpi().getType(class_index); - ClassRecord class_record = CVTagRecord::create(parent_cvt).asClass(); + TagRecord tag_record = CVTagRecord::create(parent_cvt).asTag(); // If it's a forward reference, try to get the real TypeIndex. - if (class_record.isForwardRef()) { + if (tag_record.isForwardRef()) { llvm::Expected<TypeIndex> eti = m_index.tpi().findFullDeclForForwardRef(class_index); if (eti) { - class_record = - CVTagRecord::create(m_index.tpi().getType(*eti)).asClass(); + tag_record = CVTagRecord::create(m_index.tpi().getType(*eti)).asTag(); } } - if (!class_record.FieldList.isSimple()) { - CVType field_list = m_index.tpi().getType(class_record.FieldList); - CreateMethodDecl process(m_index, m_clang, type_id.index, function_decl, - parent_opaque_ty, proc_name, func_ct); - if (llvm::Error err = visitMemberRecordStream(field_list.data(), process)) + if (!tag_record.FieldList.isSimple()) { + CVType field_list_cvt = m_index.tpi().getType(tag_record.FieldList); + FieldListRecord field_list; + if (llvm::Error error = TypeDeserializer::deserializeAs<FieldListRecord>( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); + CreateMethodDecl process(m_index, m_clang, func_ti, function_decl, + parent_opaque_ty, func_name, func_ct); + if (llvm::Error err = visitMemberRecordStream(field_list.Data, process)) llvm::consumeError(std::move(err)); } if (!function_decl) { function_decl = m_clang.AddMethodToCXXRecordType( - parent_opaque_ty, proc_name, + parent_opaque_ty, func_name, /*mangled_name=*/nullptr, func_ct, /*access=*/lldb::AccessType::eAccessPublic, /*is_virtual=*/false, /*is_static=*/false, /*is_inline=*/false, /*is_explicit=*/false, /*is_attr_used=*/false, /*is_artificial=*/false); } - - m_cxx_record_map[parent_opaque_ty].insert({proc_name, func_ct}); + m_cxx_record_map[parent_opaque_ty].insert({func_name, func_ct}); } else { function_decl = m_clang.CreateFunctionDeclaration( - parent, OptionalClangModuleID(), proc_name, func_ct, storage, false); - CreateFunctionParameters(func_id, *function_decl, - func_type->getNumParams()); + parent, OptionalClangModuleID(), func_name, func_ct, func_storage, + is_inline); + CreateFunctionParameters(func_id, *function_decl, param_count); + } + return function_decl; +} + +clang::FunctionDecl * +PdbAstBuilder::GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id) { + CompilandIndexItem *cii = + m_index.compilands().GetCompiland(inlinesite_id.modi); + CVSymbol sym = cii->m_debug_stream.readSymbolAtOffset(inlinesite_id.offset); + InlineSiteSym inline_site(static_cast<SymbolRecordKind>(sym.kind())); + cantFail(SymbolDeserializer::deserializeAs<InlineSiteSym>(sym, inline_site)); + + // Inlinee is the id index to the function id record that is inlined. + PdbTypeSymId func_id(inline_site.Inlinee, true); + // Look up the function decl by the id index to see if we have created a + // function decl for a different inlinesite that refers the same function. + if (clang::Decl *decl = TryGetDecl(func_id)) + return llvm::dyn_cast<clang::FunctionDecl>(decl); + clang::FunctionDecl *function_decl = + CreateFunctionDeclFromId(func_id, inlinesite_id); + if (function_decl == nullptr) + return nullptr; + + // Use inline site id in m_decl_to_status because it's expected to be a + // PdbCompilandSymId so that we can parse local variables info after it. + uint64_t inlinesite_uid = toOpaqueUid(inlinesite_id); + DeclStatus status; + status.resolved = true; + status.uid = inlinesite_uid; + m_decl_to_status.insert({function_decl, status}); + // Use the index in IPI stream as uid in m_uid_to_decl, because index in IPI + // stream are unique and there could be multiple inline sites (different ids) + // referring the same inline function. This avoid creating multiple same + // inline function delcs. + uint64_t func_uid = toOpaqueUid(func_id); + lldbassert(m_uid_to_decl.count(func_uid) == 0); + m_uid_to_decl[func_uid] = function_decl; + return function_decl; +} + +clang::FunctionDecl * +PdbAstBuilder::CreateFunctionDeclFromId(PdbTypeSymId func_tid, + PdbCompilandSymId func_sid) { + lldbassert(func_tid.is_ipi); + CVType func_cvt = m_index.ipi().getType(func_tid.index); + llvm::StringRef func_name; + TypeIndex func_ti; + clang::DeclContext *parent = nullptr; + switch (func_cvt.kind()) { + case LF_MFUNC_ID: { + MemberFuncIdRecord mfr; + cantFail( + TypeDeserializer::deserializeAs<MemberFuncIdRecord>(func_cvt, mfr)); + func_name = mfr.getName(); + func_ti = mfr.getFunctionType(); + PdbTypeSymId class_type_id(mfr.ClassType, false); + parent = GetOrCreateDeclContextForUid(class_type_id); + break; } + case LF_FUNC_ID: { + FuncIdRecord fir; + cantFail(TypeDeserializer::deserializeAs<FuncIdRecord>(func_cvt, fir)); + func_name = fir.getName(); + func_ti = fir.getFunctionType(); + parent = FromCompilerDeclContext(GetTranslationUnitDecl()); + if (!fir.ParentScope.isNoneType()) { + CVType parent_cvt = m_index.ipi().getType(fir.ParentScope); + if (parent_cvt.kind() == LF_STRING_ID) { + StringIdRecord sir; + cantFail( + TypeDeserializer::deserializeAs<StringIdRecord>(parent_cvt, sir)); + parent = GetOrCreateNamespaceDecl(sir.String.data(), *parent); + } + } + break; + } + default: + lldbassert(false && "Invalid function id type!"); + } + clang::QualType func_qt = GetOrCreateType(func_ti); + if (func_qt.isNull()) + return nullptr; + CompilerType func_ct = ToCompilerType(func_qt); + uint32_t param_count = + llvm::cast<clang::FunctionProtoType>(func_qt)->getNumParams(); + return CreateFunctionDecl(func_sid, func_name, func_ti, func_ct, param_count, + clang::SC_None, true, parent); +} + +clang::FunctionDecl * +PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { + if (clang::Decl *decl = TryGetDecl(func_id)) + return llvm::dyn_cast<clang::FunctionDecl>(decl); + + clang::DeclContext *parent = GetParentDeclContext(PdbSymUid(func_id)); + std::string context_name; + if (clang::NamespaceDecl *ns = llvm::dyn_cast<clang::NamespaceDecl>(parent)) { + context_name = ns->getQualifiedNameAsString(); + } else if (clang::TagDecl *tag = llvm::dyn_cast<clang::TagDecl>(parent)) { + context_name = tag->getQualifiedNameAsString(); + } + + CVSymbol cvs = m_index.ReadSymbolRecord(func_id); + ProcSym proc(static_cast<SymbolRecordKind>(cvs.kind())); + llvm::cantFail(SymbolDeserializer::deserializeAs<ProcSym>(cvs, proc)); + + PdbTypeSymId type_id(proc.FunctionType); + clang::QualType qt = GetOrCreateType(type_id); + if (qt.isNull()) + return nullptr; + + clang::StorageClass storage = clang::SC_None; + if (proc.Kind == SymbolRecordKind::ProcSym) + storage = clang::SC_Static; + + const clang::FunctionProtoType *func_type = + llvm::dyn_cast<clang::FunctionProtoType>(qt); + + CompilerType func_ct = ToCompilerType(qt); + + llvm::StringRef proc_name = proc.Name; + proc_name.consume_front(context_name); + proc_name.consume_front("::"); + + clang::FunctionDecl *function_decl = + CreateFunctionDecl(func_id, proc_name, proc.FunctionType, func_ct, + func_type->getNumParams(), storage, false, parent); + if (function_decl == nullptr) + return nullptr; lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0); m_uid_to_decl[toOpaqueUid(func_id)] = function_decl; @@ -1153,10 +1298,11 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, CVSymbolArray scope = cii->m_debug_stream.getSymbolArrayForScope(func_id.offset); + scope.drop_front(); auto begin = scope.begin(); auto end = scope.end(); std::vector<clang::ParmVarDecl *> params; - while (begin != end && param_count > 0) { + for (uint32_t i = 0; i < param_count && begin != end;) { uint32_t record_offset = begin.offset(); CVSymbol sym = *begin++; @@ -1187,9 +1333,11 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, break; } case S_BLOCK32: - // All parameters should come before the first block. If that isn't the - // case, then perhaps this is bad debug info that doesn't contain - // information about all parameters. + case S_INLINESITE: + case S_INLINESITE2: + // All parameters should come before the first block/inlinesite. If that + // isn't the case, then perhaps this is bad debug info that doesn't + // contain information about all parameters. return; default: continue; @@ -1197,6 +1345,8 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, PdbCompilandSymId param_uid(func_id.modi, record_offset); clang::QualType qt = GetOrCreateType(param_type); + if (qt.isNull()) + return; CompilerType param_type_ct = m_clang.GetType(qt); clang::ParmVarDecl *param = m_clang.CreateParameterDeclaration( @@ -1206,10 +1356,10 @@ void PdbAstBuilder::CreateFunctionParameters(PdbCompilandSymId func_id, m_uid_to_decl[toOpaqueUid(param_uid)] = param; params.push_back(param); - --param_count; + ++i; } - if (!params.empty()) + if (!params.empty() && params.size() == param_count) m_clang.SetFunctionParameters(&function_decl, params); } @@ -1218,7 +1368,12 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id, clang::DeclContext *decl_context = nullptr; std::string uname; std::tie(decl_context, uname) = CreateDeclInfoForType(er, id.index); + if (!decl_context) + return {}; + clang::QualType underlying_type = GetOrCreateType(er.UnderlyingType); + if (underlying_type.isNull()) + return {}; Declaration declaration; CompilerType enum_ct = m_clang.CreateEnumerationType( @@ -1234,8 +1389,10 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id, clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) { clang::QualType element_type = GetOrCreateType(ar.ElementType); - uint64_t element_count = - ar.Size / GetSizeOfType({ar.ElementType}, m_index.tpi()); + uint64_t element_size = GetSizeOfType({ar.ElementType}, m_index.tpi()); + if (element_type.isNull() || element_size == 0) + return {}; + uint64_t element_count = ar.Size / element_size; CompilerType array_ct = m_clang.CreateArrayType(ToCompilerType(element_type), element_count, false); @@ -1261,10 +1418,14 @@ clang::QualType PdbAstBuilder::CreateFunctionType( for (TypeIndex arg_index : arg_indices) { clang::QualType arg_type = GetOrCreateType(arg_index); + if (arg_type.isNull()) + continue; arg_types.push_back(ToCompilerType(arg_type)); } clang::QualType return_type = GetOrCreateType(return_type_idx); + if (return_type.isNull()) + return {}; llvm::Optional<clang::CallingConv> cc = TranslateCallingConvention(calling_convention); @@ -1303,7 +1464,7 @@ void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf( CVTagRecord tag = CVTagRecord::create(cvt); - if (!parent.hasValue()) { + if (!parent) { clang::QualType qt = GetOrCreateType(tid); CompleteType(qt); continue; @@ -1315,7 +1476,7 @@ void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf( clang::DeclContext *context = nullptr; std::string uname; std::tie(context, uname) = CreateDeclInfoForType(tag.asTag(), tid.index); - if (!context->isNamespace()) + if (!context || !context->isNamespace()) continue; clang::NamespaceDecl *ns = llvm::cast<clang::NamespaceDecl>(context); @@ -1385,7 +1546,7 @@ static CVSymbolArray skipFunctionParameters(clang::Decl &decl, void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) { CVSymbol sym = m_index.ReadSymbolRecord(block_id); lldbassert(sym.kind() == S_GPROC32 || sym.kind() == S_LPROC32 || - sym.kind() == S_BLOCK32); + sym.kind() == S_BLOCK32 || sym.kind() == S_INLINESITE); CompilandIndexItem &cii = m_index.compilands().GetOrCreateCompiland(block_id.modi); CVSymbolArray symbols = @@ -1397,11 +1558,12 @@ void PdbAstBuilder::ParseBlockChildren(PdbCompilandSymId block_id) { symbols = skipFunctionParameters(*m_uid_to_decl[toOpaqueUid(block_id)], symbols); + symbols.drop_front(); auto begin = symbols.begin(); while (begin != symbols.end()) { PdbCompilandSymId child_sym_id(block_id.modi, begin.offset()); GetOrCreateSymbolForId(child_sym_id); - if (begin->kind() == S_BLOCK32) { + if (begin->kind() == S_BLOCK32 || begin->kind() == S_INLINESITE) { ParseBlockChildren(child_sym_id); begin = symbols.at(getScopeEndOffset(*begin)); } diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h index 73accf5e5e68..40425dd4c6e7 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h @@ -61,6 +61,8 @@ public: clang::DeclContext *GetParentDeclContext(PdbSymUid uid); clang::FunctionDecl *GetOrCreateFunctionDecl(PdbCompilandSymId func_id); + clang::FunctionDecl * + GetOrCreateInlinedFunctionDecl(PdbCompilandSymId inlinesite_id); clang::BlockDecl *GetOrCreateBlockDecl(PdbCompilandSymId block_id); clang::VarDecl *GetOrCreateVariableDecl(PdbCompilandSymId scope_id, PdbCompilandSymId var_id); @@ -116,7 +118,13 @@ private: clang::NamespaceDecl *GetOrCreateNamespaceDecl(const char *name, clang::DeclContext &context); - + clang::FunctionDecl *CreateFunctionDeclFromId(PdbTypeSymId func_tid, + PdbCompilandSymId func_sid); + clang::FunctionDecl * + CreateFunctionDecl(PdbCompilandSymId func_id, llvm::StringRef func_name, + TypeIndex func_ti, CompilerType func_ct, + uint32_t param_count, clang::StorageClass func_storage, + bool is_inline, clang::DeclContext *parent); void ParseAllNamespacesPlusChildrenOf(llvm::Optional<llvm::StringRef> parent); void ParseDeclsForSimpleContext(clang::DeclContext &context); void ParseBlockChildren(PdbCompilandSymId block_id); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp index 4f570d5e6788..c45db174e534 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbFPOProgramToDWARFExpression.cpp @@ -18,6 +18,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/DebugInfo/CodeView/CodeView.h" #include "llvm/DebugInfo/CodeView/EnumTables.h" +#include "llvm/Support/ScopedPrinter.h" using namespace lldb; using namespace lldb_private; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp index dc964f64a915..3a76f8bff316 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.cpp @@ -60,15 +60,11 @@ PdbIndex::create(llvm::pdb::PDBFile *file) { lldb::addr_t PdbIndex::MakeVirtualAddress(uint16_t segment, uint32_t offset) const { - // Segment indices are 1-based. - lldbassert(segment > 0); - uint32_t max_section = dbi().getSectionHeaders().size(); - lldbassert(segment <= max_section + 1); - + // Segment indices are 1-based. // If this is an absolute symbol, it's indicated by the magic section index // |max_section+1|. In this case, the offset is meaningless, so just return. - if (segment == max_section + 1) + if (segment == 0 || segment > max_section) return LLDB_INVALID_ADDRESS; const llvm::object::coff_section &cs = dbi().getSectionHeaders()[segment - 1]; @@ -76,10 +72,6 @@ lldb::addr_t PdbIndex::MakeVirtualAddress(uint16_t segment, static_cast<lldb::addr_t>(offset); } -lldb::addr_t PdbIndex::MakeVirtualAddress(const SegmentOffset &so) const { - return MakeVirtualAddress(so.segment, so.offset); -} - llvm::Optional<uint16_t> PdbIndex::GetModuleIndexForAddr(uint16_t segment, uint32_t offset) const { return GetModuleIndexForVa(MakeVirtualAddress(segment, offset)); @@ -107,6 +99,8 @@ void PdbIndex::ParseSectionContribs() { return; uint64_t va = m_ctx.MakeVirtualAddress(C.ISect, C.Off); + if (va == LLDB_INVALID_ADDRESS) + return; uint64_t end = va + C.Size; // IntervalMap's start and end represent a closed range, not a half-open // range, so we have to subtract 1. @@ -128,7 +122,9 @@ void PdbIndex::BuildAddrToSymbolMap(CompilandIndexItem &cci) { continue; SegmentOffset so = GetSegmentAndOffset(*iter); - lldb::addr_t va = MakeVirtualAddress(so); + lldb::addr_t va = MakeVirtualAddress(so.segment, so.offset); + if (va == LLDB_INVALID_ADDRESS) + continue; PdbCompilandSymId cu_sym_id(modi, iter.offset()); @@ -175,7 +171,10 @@ std::vector<SymbolAndUid> PdbIndex::FindSymbolsByVa(lldb::addr_t va) { else sol.so = GetSegmentAndOffset(sym); - lldb::addr_t start = MakeVirtualAddress(sol.so); + lldb::addr_t start = MakeVirtualAddress(sol.so.segment, sol.so.offset); + if (start == LLDB_INVALID_ADDRESS) + continue; + lldb::addr_t end = start + sol.length; if (va >= start && va < end) result.push_back({std::move(sym), iter->second}); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h index edbdd9ee290b..138c63d79a59 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbIndex.h @@ -143,7 +143,6 @@ public: const CompileUnitIndex &compilands() const { return m_cus; } lldb::addr_t MakeVirtualAddress(uint16_t segment, uint32_t offset) const; - lldb::addr_t MakeVirtualAddress(const SegmentOffset &so) const; std::vector<SymbolAndUid> FindSymbolsByVa(lldb::addr_t va); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp index b5a16447d9cf..7bb7c69eece7 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.cpp @@ -12,6 +12,7 @@ #include "PdbIndex.h" #include "PdbSymUid.h" +#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h" #include "llvm/DebugInfo/CodeView/SymbolDeserializer.h" #include "llvm/DebugInfo/CodeView/TypeDeserializer.h" #include "llvm/DebugInfo/PDB/Native/DbiStream.h" @@ -20,6 +21,7 @@ #include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" #include "lldb/Symbol/Block.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/lldb-enumerations.h" using namespace lldb_private; @@ -32,15 +34,16 @@ MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range, llvm::ArrayRef<LocalVariableAddrGap> gaps) { lldb::addr_t start = index.MakeVirtualAddress(range.ISectStart, range.OffsetStart); + if (start == LLDB_INVALID_ADDRESS) + return {}; lldb::addr_t end = start + range.Range; Variable::RangeList result; while (!gaps.empty()) { const LocalVariableAddrGap &gap = gaps.front(); - - lldb::addr_t size = gap.GapStartOffset - start; - result.Append(start, size); - start += gap.Range; + lldb::addr_t gap_start = start + gap.GapStartOffset; + result.Append(start, gap_start - start); + start = gap_start + gap.Range; gaps = gaps.drop_front(); } @@ -48,6 +51,24 @@ MakeRangeList(const PdbIndex &index, const LocalVariableAddrRange &range, return result; } +namespace { +struct FindMembersSize : public TypeVisitorCallbacks { + FindMembersSize( + std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info, + TpiStream &tpi) + : members_info(members_info), tpi(tpi) {} + std::map<uint64_t, std::pair<RegisterId, uint32_t>> &members_info; + TpiStream &tpi; + llvm::Error visitKnownMember(CVMemberRecord &cvr, + DataMemberRecord &member) override { + members_info.insert( + {member.getFieldOffset(), + {llvm::codeview::RegisterId::NONE, GetSizeOfType(member.Type, tpi)}}); + return llvm::Error::success(); + } +}; +} // namespace + CVTagRecord CVTagRecord::create(CVType type) { assert(IsTagRecord(type) && "type is not a tag record!"); switch (type.kind()) { @@ -477,6 +498,8 @@ VariableInfo lldb_private::npdb::GetVariableNameInfo(CVSymbol sym) { cantFail(SymbolDeserializer::deserializeAs<LocalSym>(sym, local)); result.type = local.Type; result.name = local.Name; + result.is_param = + ((local.Flags & LocalSymFlags::IsParameter) != LocalSymFlags::None); return result; } @@ -563,7 +586,8 @@ static RegisterId GetBaseFrameRegister(PdbIndex &index, PdbCompilandSymId frame_proc_id, bool is_parameter) { CVSymbol frame_proc_cvs = index.ReadSymbolRecord(frame_proc_id); - lldbassert(frame_proc_cvs.kind() == S_FRAMEPROC); + if (frame_proc_cvs.kind() != S_FRAMEPROC) + return RegisterId::NONE; FrameProcSym frame_proc(SymbolRecordKind::FrameProcSym); cantFail(SymbolDeserializer::deserializeAs<FrameProcSym>(frame_proc_cvs, @@ -609,7 +633,8 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo( PdbCompilandSymId loc_specifier_id(var_id.modi, var_id.offset + sym.RecordData.size()); CVSymbol loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id); - if (loc_specifier_cvs.kind() == S_DEFRANGE_FRAMEPOINTER_REL) { + switch(loc_specifier_cvs.kind()) { + case S_DEFRANGE_FRAMEPOINTER_REL: { DefRangeFramePointerRelSym loc( SymbolRecordKind::DefRangeFramePointerRelSym); cantFail(SymbolDeserializer::deserializeAs<DefRangeFramePointerRelSym>( @@ -632,11 +657,10 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo( PdbCompilandSymId frame_proc_id( func_scope_id.modi, func_scope_id.offset + func_block_cvs.length()); - bool is_parameter = - ((local.Flags & LocalSymFlags::IsParameter) != LocalSymFlags::None); RegisterId base_reg = - GetBaseFrameRegister(index, frame_proc_id, is_parameter); - + GetBaseFrameRegister(index, frame_proc_id, result.is_param); + if (base_reg == RegisterId::NONE) + break; if (base_reg == RegisterId::VFRAME) { llvm::StringRef program; if (GetFrameDataProgram(index, ranges, program)) { @@ -651,7 +675,9 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo( MakeRegRelLocationExpression(base_reg, loc.Hdr.Offset, module); result.ranges = std::move(ranges); } - } else if (loc_specifier_cvs.kind() == S_DEFRANGE_REGISTER_REL) { + break; + } + case S_DEFRANGE_REGISTER_REL: { DefRangeRegisterRelSym loc(SymbolRecordKind::DefRangeRegisterRelSym); cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterRelSym>( loc_specifier_cvs, loc)); @@ -674,9 +700,126 @@ VariableInfo lldb_private::npdb::GetVariableLocationInfo( base_reg, loc.Hdr.BasePointerOffset, module); result.ranges = std::move(ranges); } + break; + } + case S_DEFRANGE_REGISTER: { + DefRangeRegisterSym loc(SymbolRecordKind::DefRangeRegisterSym); + cantFail(SymbolDeserializer::deserializeAs<DefRangeRegisterSym>( + loc_specifier_cvs, loc)); + + RegisterId base_reg = (RegisterId)(uint16_t)loc.Hdr.Register; + result.ranges = MakeRangeList(index, loc.Range, loc.Gaps); + result.location = MakeEnregisteredLocationExpression(base_reg, module); + break; } + case S_DEFRANGE_SUBFIELD_REGISTER: { + // A map from offset in parent to pair of register id and size. If the + // variable is a simple type, then we don't know the number of subfields. + // Otherwise, the size of the map should be greater than or equal to the + // number of sub field record. + std::map<uint64_t, std::pair<RegisterId, uint32_t>> members_info; + bool is_simple_type = result.type.isSimple(); + if (!is_simple_type) { + CVType class_cvt = index.tpi().getType(result.type); + TypeIndex class_id = result.type; + if (class_cvt.kind() == LF_MODIFIER) + class_id = LookThroughModifierRecord(class_cvt); + if (IsForwardRefUdt(class_id, index.tpi())) { + auto expected_full_ti = + index.tpi().findFullDeclForForwardRef(class_id); + if (!expected_full_ti) { + llvm::consumeError(expected_full_ti.takeError()); + break; + } + class_cvt = index.tpi().getType(*expected_full_ti); + } + if (IsTagRecord(class_cvt)) { + TagRecord tag_record = CVTagRecord::create(class_cvt).asTag(); + CVType field_list_cvt = index.tpi().getType(tag_record.FieldList); + FieldListRecord field_list; + if (llvm::Error error = + TypeDeserializer::deserializeAs<FieldListRecord>( + field_list_cvt, field_list)) + llvm::consumeError(std::move(error)); + FindMembersSize find_members_size(members_info, index.tpi()); + if (llvm::Error err = visitMemberRecordStream(field_list.Data, + find_members_size)) { + llvm::consumeError(std::move(err)); + break; + } + } else { + // TODO: Handle poiner type. + break; + } + } - // FIXME: Handle other kinds + size_t member_idx = 0; + // Assuming S_DEFRANGE_SUBFIELD_REGISTER is followed only by + // S_DEFRANGE_SUBFIELD_REGISTER, need to verify. + while (loc_specifier_cvs.kind() == S_DEFRANGE_SUBFIELD_REGISTER) { + if (!is_simple_type && member_idx >= members_info.size()) + break; + + DefRangeSubfieldRegisterSym loc( + SymbolRecordKind::DefRangeSubfieldRegisterSym); + cantFail(SymbolDeserializer::deserializeAs<DefRangeSubfieldRegisterSym>( + loc_specifier_cvs, loc)); + + if (result.ranges) { + result.ranges = Variable::RangeList::GetOverlaps( + *result.ranges, MakeRangeList(index, loc.Range, loc.Gaps)); + } else { + result.ranges = MakeRangeList(index, loc.Range, loc.Gaps); + result.ranges->Sort(); + } + + if (is_simple_type) { + if (members_info.count(loc.Hdr.OffsetInParent)) { + // Malformed record. + result.ranges->Clear(); + return result; + } + members_info[loc.Hdr.OffsetInParent] = { + (RegisterId)(uint16_t)loc.Hdr.Register, 0}; + } else { + if (!members_info.count(loc.Hdr.OffsetInParent)) { + // Malformed record. + result.ranges->Clear(); + return result; + } + members_info[loc.Hdr.OffsetInParent].first = + (RegisterId)(uint16_t)loc.Hdr.Register; + } + // Go to next S_DEFRANGE_SUBFIELD_REGISTER. + loc_specifier_id = PdbCompilandSymId( + loc_specifier_id.modi, + loc_specifier_id.offset + loc_specifier_cvs.RecordData.size()); + loc_specifier_cvs = index.ReadSymbolRecord(loc_specifier_id); + } + // Fix size for simple type. + if (is_simple_type) { + auto cur = members_info.begin(); + auto end = members_info.end(); + auto next = cur; + ++next; + uint32_t size = 0; + while (next != end) { + cur->second.second = next->first - cur->first; + size += cur->second.second; + cur = next++; + } + cur->second.second = + GetTypeSizeForSimpleKind(result.type.getSimpleKind()) - size; + } + result.location = + MakeEnregisteredLocationExpressionForClass(members_info, module); + break; + } + default: + // FIXME: Handle other kinds. LLVM only generates the 4 types of records + // above. + break; + } return result; } llvm_unreachable("Symbol is not a local variable!"); @@ -704,6 +847,8 @@ lldb_private::npdb::GetCompilerTypeForSimpleKind(SimpleTypeKind kind) { return lldb::eBasicTypeChar16; case SimpleTypeKind::Character32: return lldb::eBasicTypeChar32; + case SimpleTypeKind::Character8: + return lldb::eBasicTypeChar8; case SimpleTypeKind::Complex80: return lldb::eBasicTypeLongDoubleComplex; case SimpleTypeKind::Complex64: @@ -796,6 +941,7 @@ size_t lldb_private::npdb::GetTypeSizeForSimpleKind(SimpleTypeKind kind) { case SimpleTypeKind::NarrowCharacter: case SimpleTypeKind::SignedCharacter: case SimpleTypeKind::SByte: + case SimpleTypeKind::Character8: return 1; case SimpleTypeKind::Void: default: diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h index c309c5c8ea1c..138c11aaeb43 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbUtil.h @@ -105,6 +105,7 @@ struct VariableInfo { llvm::codeview::TypeIndex type; llvm::Optional<DWARFExpression> location; llvm::Optional<Variable::RangeList> ranges; + bool is_param; }; llvm::pdb::PDB_SymType CVSymToPDBSym(llvm::codeview::SymbolKind kind); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index a035a791f868..7dc99818c244 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -29,6 +29,7 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/Variable.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "llvm/DebugInfo/CodeView/CVRecord.h" @@ -79,6 +80,8 @@ static lldb::LanguageType TranslateLanguage(PDB_Lang lang) { return lldb::LanguageType::eLanguageTypeC; case PDB_Lang::Swift: return lldb::LanguageType::eLanguageTypeSwift; + case PDB_Lang::Rust: + return lldb::LanguageType::eLanguageTypeRust; default: return lldb::LanguageType::eLanguageTypeUnknown; } @@ -170,6 +173,8 @@ static llvm::StringRef GetSimpleTypeName(SimpleTypeKind kind) { return "char16_t"; case SimpleTypeKind::Character32: return "char32_t"; + case SimpleTypeKind::Character8: + return "char8_t"; case SimpleTypeKind::Complex80: case SimpleTypeKind::Complex64: case SimpleTypeKind::Complex32: @@ -249,7 +254,7 @@ SymbolFile *SymbolFileNativePDB::CreateInstance(ObjectFileSP objfile_sp) { } SymbolFileNativePDB::SymbolFileNativePDB(ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)) {} + : SymbolFileCommon(std::move(objfile_sp)) {} SymbolFileNativePDB::~SymbolFileNativePDB() = default; @@ -302,8 +307,8 @@ void SymbolFileNativePDB::InitializeObject() { auto ts_or_err = m_objfile_sp->GetModule()->GetTypeSystemForLanguage( lldb::eLanguageTypeC_plus_plus); if (auto err = ts_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Failed to initialize"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Failed to initialize"); } else { ts_or_err->SetSymbolFile(this); auto *clang = llvm::cast_or_null<TypeSystemClang>(&ts_or_err.get()); @@ -367,7 +372,7 @@ Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) { std::shared_ptr<InlineSite> inline_site = m_inline_sites[opaque_block_uid]; Block &parent_block = GetOrCreateBlock(inline_site->parent_id); parent_block.AddChild(child_block); - + m_ast->GetOrCreateInlinedFunctionDecl(block_id); // Copy ranges from InlineSite to Block. for (size_t i = 0; i < inline_site->ranges.GetSize(); ++i) { auto *entry = inline_site->ranges.GetEntryAtIndex(i); @@ -402,7 +407,8 @@ lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id, lldbassert(sym_record.kind() == S_LPROC32 || sym_record.kind() == S_GPROC32); SegmentOffsetLength sol = GetSegmentOffsetAndLength(sym_record); - auto file_vm_addr = m_index->MakeVirtualAddress(sol.so); + auto file_vm_addr = + m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset); if (file_vm_addr == LLDB_INVALID_ADDRESS || file_vm_addr == 0) return nullptr; @@ -444,7 +450,8 @@ SymbolFileNativePDB::CreateCompileUnit(const CompilandIndexItem &cci) { llvm::SmallString<64> source_file_name = m_index->compilands().GetMainSourceFile(cci); - FileSpec fs(source_file_name); + FileSpec fs(llvm::sys::path::convert_to_slash( + source_file_name, llvm::sys::path::Style::windows_backslash)); CompUnitSP cu_sp = std::make_shared<CompileUnit>(m_objfile_sp->GetModule(), nullptr, fs, @@ -721,6 +728,8 @@ TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) { PdbTypeSymId best_decl_id = full_decl_uid ? *full_decl_uid : type_id; clang::QualType qt = m_ast->GetOrCreateType(best_decl_id); + if (qt.isNull()) + return nullptr; TypeSP result = CreateType(best_decl_id, m_ast->ToCompilerType(qt)); if (!result) @@ -799,11 +808,13 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) { CompUnitSP comp_unit; llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(addr); - if (modi) { - CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi); - comp_unit = GetOrCreateCompileUnit(cci); + if (!modi) { + return nullptr; } + CompilandIndexItem &cci = m_index->compilands().GetOrCreateCompiland(*modi); + comp_unit = GetOrCreateCompileUnit(cci); + Declaration decl; PdbTypeSymId tid(ti, false); SymbolFileTypeSP type_sp = @@ -861,8 +872,12 @@ SymbolFileNativePDB::CreateConstantSymbol(PdbGlobalSymId var_id, VariableSP SymbolFileNativePDB::GetOrCreateGlobalVariable(PdbGlobalSymId var_id) { auto emplace_result = m_global_vars.try_emplace(toOpaqueUid(var_id), nullptr); - if (emplace_result.second) - emplace_result.first->second = CreateGlobalVariable(var_id); + if (emplace_result.second) { + if (VariableSP var_sp = CreateGlobalVariable(var_id)) + emplace_result.first->second = var_sp; + else + return nullptr; + } return emplace_result.first->second; } @@ -979,7 +994,7 @@ uint32_t SymbolFileNativePDB::ResolveSymbolContext( llvm::Optional<uint16_t> modi = m_index->GetModuleIndexForVa(file_addr); if (!modi) return 0; - CompUnitSP cu_sp = GetCompileUnitAtIndex(modi.getValue()); + CompUnitSP cu_sp = GetCompileUnitAtIndex(*modi); if (!cu_sp) return 0; @@ -1094,6 +1109,8 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { const LineFragmentHeader *lfh = lines.header(); uint64_t virtual_addr = m_index->MakeVirtualAddress(lfh->RelocSegment, lfh->RelocOffset); + if (virtual_addr == LLDB_INVALID_ADDRESS) + continue; for (const LineColumnEntry &group : lines) { llvm::Expected<uint32_t> file_index_or_err = @@ -1118,8 +1135,13 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { uint32_t lno = cur_info.getStartLine(); - line_set.emplace(addr, lno, 0, file_index, is_statement, false, - is_prologue, is_epilogue, false); + LineTable::Entry new_entry(addr, lno, 0, file_index, is_statement, false, + is_prologue, is_epilogue, false); + // Terminal entry has lower precedence than new entry. + auto iter = line_set.find(new_entry); + if (iter != line_set.end() && iter->is_terminal_entry) + line_set.erase(iter); + line_set.insert(new_entry); if (line_entry.GetRangeBase() != LLDB_INVALID_ADDRESS) { line_entry.SetRangeEnd(addr); @@ -1153,7 +1175,11 @@ bool SymbolFileNativePDB::ParseLineTable(CompileUnit &comp_unit) { CVSymbol func_record = cii->m_debug_stream.readSymbolAtOffset(record_offset); SegmentOffsetLength sol = GetSegmentOffsetAndLength(func_record); - addr_t file_vm_addr = m_index->MakeVirtualAddress(sol.so); + addr_t file_vm_addr = + m_index->MakeVirtualAddress(sol.so.segment, sol.so.offset); + if (file_vm_addr == LLDB_INVALID_ADDRESS) + continue; + AddressRange func_range(file_vm_addr, sol.length, comp_unit.GetModule()->GetSectionList()); Address func_base = func_range.GetBaseAddress(); @@ -1215,9 +1241,6 @@ bool SymbolFileNativePDB::ParseDebugMacros(CompileUnit &comp_unit) { llvm::Expected<uint32_t> SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii, uint32_t file_id) { - auto index_iter = m_file_indexes.find(file_id); - if (index_iter != m_file_indexes.end()) - return index_iter->getSecond(); const auto &checksums = cii.m_strings.checksums().getArray(); const auto &strings = cii.m_strings.strings(); // Indices in this structure are actually offsets of records in the @@ -1234,9 +1257,9 @@ SymbolFileNativePDB::GetFileIndex(const CompilandIndexItem &cii, // LLDB wants the index of the file in the list of support files. auto fn_iter = llvm::find(cii.m_file_list, *efn); - lldbassert(fn_iter != cii.m_file_list.end()); - m_file_indexes[file_id] = std::distance(cii.m_file_list.begin(), fn_iter); - return m_file_indexes[file_id]; + if (fn_iter != cii.m_file_list.end()) + return std::distance(cii.m_file_list.begin(), fn_iter); + return llvm::make_error<RawError>(raw_error_code::no_entry); } bool SymbolFileNativePDB::ParseSupportFiles(CompileUnit &comp_unit, @@ -1293,8 +1316,8 @@ void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id, GetFileIndex(*cii, inlinee_line.Header->FileID); if (!file_index_or_err) return; - uint32_t decl_file_idx = file_index_or_err.get(); - decl_file = files.GetFileSpecAtIndex(decl_file_idx); + uint32_t file_offset = file_index_or_err.get(); + decl_file = files.GetFileSpecAtIndex(file_offset); uint32_t decl_line = inlinee_line.Header->SourceLineNum; std::unique_ptr<Declaration> decl_up = std::make_unique<Declaration>(decl_file, decl_line); @@ -1302,54 +1325,36 @@ void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id, // Parse range and line info. uint32_t code_offset = 0; int32_t line_offset = 0; - bool has_base = false; - bool is_new_line_offset = false; + llvm::Optional<uint32_t> code_offset_base; + llvm::Optional<uint32_t> code_offset_end; + llvm::Optional<int32_t> cur_line_offset; + llvm::Optional<int32_t> next_line_offset; + llvm::Optional<uint32_t> next_file_offset; - bool is_start_of_statement = false; + bool is_terminal_entry = false; + bool is_start_of_statement = true; // The first instruction is the prologue end. bool is_prologue_end = true; - auto change_code_offset = [&](uint32_t code_delta) { - if (has_base) { - inline_site_sp->ranges.Append(RangeSourceLineVector::Entry( - code_offset, code_delta, decl_line + line_offset)); - is_prologue_end = false; - is_start_of_statement = false; - } else { - is_start_of_statement = true; - } - has_base = true; - code_offset += code_delta; - - if (is_new_line_offset) { - LineTable::Entry line_entry(func_base + code_offset, - decl_line + line_offset, 0, decl_file_idx, - true, false, is_prologue_end, false, false); - inline_site_sp->line_entries.push_back(line_entry); - is_new_line_offset = false; - } - }; - auto change_code_length = [&](uint32_t length) { - inline_site_sp->ranges.Append(RangeSourceLineVector::Entry( - code_offset, length, decl_line + line_offset)); - has_base = false; - - LineTable::Entry end_line_entry(func_base + code_offset + length, - decl_line + line_offset, 0, decl_file_idx, - false, false, false, false, true); - inline_site_sp->line_entries.push_back(end_line_entry); + auto update_code_offset = [&](uint32_t code_delta) { + if (!code_offset_base) + code_offset_base = code_offset; + else if (!code_offset_end) + code_offset_end = *code_offset_base + code_delta; }; - auto change_line_offset = [&](int32_t line_delta) { + auto update_line_offset = [&](int32_t line_delta) { line_offset += line_delta; - if (has_base) { - LineTable::Entry line_entry( - func_base + code_offset, decl_line + line_offset, 0, decl_file_idx, - is_start_of_statement, false, is_prologue_end, false, false); - inline_site_sp->line_entries.push_back(line_entry); - } else { - // Add line entry in next call to change_code_offset. - is_new_line_offset = true; - } + if (!code_offset_base || !cur_line_offset) + cur_line_offset = line_offset; + else + next_line_offset = line_offset; + ; + }; + auto update_file_offset = [&](uint32_t offset) { + if (!code_offset_base) + file_offset = offset; + else + next_file_offset = offset; }; for (auto &annot : inline_site.annotations()) { @@ -1357,30 +1362,73 @@ void SymbolFileNativePDB::ParseInlineSite(PdbCompilandSymId id, case BinaryAnnotationsOpCode::CodeOffset: case BinaryAnnotationsOpCode::ChangeCodeOffset: case BinaryAnnotationsOpCode::ChangeCodeOffsetBase: - change_code_offset(annot.U1); + code_offset += annot.U1; + update_code_offset(annot.U1); break; case BinaryAnnotationsOpCode::ChangeLineOffset: - change_line_offset(annot.S1); + update_line_offset(annot.S1); break; case BinaryAnnotationsOpCode::ChangeCodeLength: - change_code_length(annot.U1); + update_code_offset(annot.U1); code_offset += annot.U1; + is_terminal_entry = true; break; case BinaryAnnotationsOpCode::ChangeCodeOffsetAndLineOffset: - change_code_offset(annot.U1); - change_line_offset(annot.S1); + code_offset += annot.U1; + update_code_offset(annot.U1); + update_line_offset(annot.S1); break; case BinaryAnnotationsOpCode::ChangeCodeLengthAndCodeOffset: - change_code_offset(annot.U2); - change_code_length(annot.U1); + code_offset += annot.U2; + update_code_offset(annot.U2); + update_code_offset(annot.U1); + code_offset += annot.U1; + is_terminal_entry = true; + break; + case BinaryAnnotationsOpCode::ChangeFile: + update_file_offset(annot.U1); break; default: break; } + + // Add range if current range is finished. + if (code_offset_base && code_offset_end && cur_line_offset) { + inline_site_sp->ranges.Append(RangeSourceLineVector::Entry( + *code_offset_base, *code_offset_end - *code_offset_base, + decl_line + *cur_line_offset)); + // Set base, end, file offset and line offset for next range. + if (next_file_offset) + file_offset = *next_file_offset; + if (next_line_offset) { + cur_line_offset = next_line_offset; + next_line_offset = llvm::None; + } + code_offset_base = is_terminal_entry ? llvm::None : code_offset_end; + code_offset_end = next_file_offset = llvm::None; + } + if (code_offset_base && cur_line_offset) { + if (is_terminal_entry) { + LineTable::Entry line_entry( + func_base + *code_offset_base, decl_line + *cur_line_offset, 0, + file_offset, false, false, false, false, true); + inline_site_sp->line_entries.push_back(line_entry); + } else { + LineTable::Entry line_entry(func_base + *code_offset_base, + decl_line + *cur_line_offset, 0, + file_offset, is_start_of_statement, false, + is_prologue_end, false, false); + inline_site_sp->line_entries.push_back(line_entry); + is_prologue_end = false; + is_start_of_statement = false; + } + } + if (is_terminal_entry) + is_start_of_statement = true; + is_terminal_entry = false; } inline_site_sp->ranges.Sort(); - inline_site_sp->ranges.CombineConsecutiveEntriesWithEqualData(); // Get the inlined function callsite info. std::unique_ptr<Declaration> callsite_up; @@ -1493,7 +1541,6 @@ void SymbolFileNativePDB::FindGlobalVariables( std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName( name.GetStringRef(), m_index->symrecords()); for (const SymbolAndOffset &result : results) { - VariableSP var; switch (result.second.kind()) { case SymbolKind::S_GDATA32: case SymbolKind::S_LDATA32: @@ -1501,8 +1548,8 @@ void SymbolFileNativePDB::FindGlobalVariables( case SymbolKind::S_LTHREAD32: case SymbolKind::S_CONSTANT: { PdbGlobalSymId global(result.first, false); - var = GetOrCreateGlobalVariable(global); - variables.AddVariable(var); + if (VariableSP var = GetOrCreateGlobalVariable(global)) + variables.AddVariable(var); break; } default: @@ -1655,6 +1702,7 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, SymbolFileTypeSP sftype = std::make_shared<SymbolFileType>(*this, type_sp->GetID()); + is_param |= var_info.is_param; ValueType var_scope = is_param ? eValueTypeVariableArgument : eValueTypeVariableLocal; bool external = false; @@ -1663,7 +1711,7 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, bool static_member = false; VariableSP var_sp = std::make_shared<Variable>( toOpaqueUid(var_id), name.c_str(), name.c_str(), sftype, var_scope, - comp_unit_sp.get(), *var_info.ranges, &decl, *var_info.location, external, + &block, *var_info.ranges, &decl, *var_info.location, external, artificial, location_is_constant_data, static_member); if (!is_param) @@ -1731,8 +1779,7 @@ size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { case S_BLOCK32: break; case S_INLINESITE: - // TODO: Handle inline site case. - return 0; + break; default: lldbassert(false && "Symbol is not a block!"); return 0; @@ -1759,8 +1806,10 @@ size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { PdbCompilandSymId child_sym_id(block_id.modi, record_offset); ++iter; - // If this is a block, recurse into its children and then skip it. - if (variable_cvs.kind() == S_BLOCK32) { + // If this is a block or inline site, recurse into its children and then + // skip it. + if (variable_cvs.kind() == S_BLOCK32 || + variable_cvs.kind() == S_INLINESITE) { uint32_t block_end = getScopeEndOffset(variable_cvs); count += ParseVariablesForBlock(child_sym_id); iter = syms.at(block_end); @@ -1824,7 +1873,7 @@ size_t SymbolFileNativePDB::ParseVariablesForContext(const SymbolContext &sc) { CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) { if (auto decl = m_ast->GetOrCreateDeclForUid(uid)) - return decl.getValue(); + return *decl; else return CompilerDecl(); } @@ -1904,4 +1953,3 @@ uint64_t SymbolFileNativePDB::GetDebugInfoSize() { // PDB files are a separate file that contains all debug info. return m_index->pdb().getFileSize(); } - diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index f1b6e34ca346..187791b0fd01 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -39,7 +39,7 @@ namespace lldb_private { namespace npdb { class PdbAstBuilder; -class SymbolFileNativePDB : public SymbolFile { +class SymbolFileNativePDB : public SymbolFileCommon { friend class UdtRecordCompleter; /// LLVM RTTI support. @@ -49,7 +49,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} @@ -272,8 +272,6 @@ private: llvm::DenseMap<lldb::user_id_t, lldb::CompUnitSP> m_compilands; llvm::DenseMap<lldb::user_id_t, lldb::TypeSP> m_types; llvm::DenseMap<lldb::user_id_t, std::shared_ptr<InlineSite>> m_inline_sites; - // A map from file id in records to file index in support files. - llvm::DenseMap<uint32_t, uint32_t> m_file_indexes; }; } // namespace npdb diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp index d0b27bc5bf79..c0308196c760 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -10,6 +10,7 @@ #include "Plugins/TypeSystem/Clang/TypeSystemClang.h" #include "lldb/Symbol/Type.h" #include "lldb/Utility/LLDBAssert.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/lldb-enumerations.h" #include "lldb/lldb-forward.h" @@ -65,11 +66,12 @@ clang::QualType UdtRecordCompleter::AddBaseClassForTypeIndex( std::unique_ptr<clang::CXXBaseSpecifier> base_spec = m_ast_builder.clang().CreateBaseClassSpecifier( qt.getAsOpaquePtr(), TranslateMemberAccess(access), - vtable_idx.hasValue(), udt_cvt.kind() == LF_CLASS); - lldbassert(base_spec); + vtable_idx.has_value(), udt_cvt.kind() == LF_CLASS); + if (!base_spec) + return {}; m_bases.push_back( - std::make_pair(vtable_idx.getValueOr(0), std::move(base_spec))); + std::make_pair(vtable_idx.value_or(0), std::move(base_spec))); return qt; } @@ -79,6 +81,8 @@ void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx, MemberAttributes attrs) { clang::QualType method_qt = m_ast_builder.GetOrCreateType(PdbTypeSymId(type_idx)); + if (method_qt.isNull()) + return; m_ast_builder.CompleteType(method_qt); CompilerType method_ct = m_ast_builder.ToCompilerType(method_qt); lldb::opaque_compiler_type_t derived_opaque_ty = m_derived_ct.GetOpaqueQualType(); @@ -105,6 +109,8 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, clang::QualType base_qt = AddBaseClassForTypeIndex(base.Type, base.getAccess()); + if (base_qt.isNull()) + return llvm::Error::success(); auto decl = m_ast_builder.clang().GetAsCXXRecordDecl(base_qt.getAsOpaquePtr()); lldbassert(decl); @@ -136,8 +142,8 @@ Error UdtRecordCompleter::visitKnownMember( CVMemberRecord &cvr, StaticDataMemberRecord &static_data_member) { clang::QualType member_type = m_ast_builder.GetOrCreateType(PdbTypeSymId(static_data_member.Type)); - - m_ast_builder.CompleteType(member_type); + if (member_type.isNull()) + return llvm::Error::success(); CompilerType member_ct = m_ast_builder.ToCompilerType(member_type); @@ -148,7 +154,7 @@ Error UdtRecordCompleter::visitKnownMember( // Static constant members may be a const[expr] declaration. // Query the symbol's value as the variable initializer if valid. - if (member_ct.IsConst()) { + if (member_ct.IsConst() && member_ct.IsCompleteType()) { std::string qual_name = decl->getQualifiedNameAsString(); auto results = @@ -169,7 +175,7 @@ Error UdtRecordCompleter::visitKnownMember( TypeSystemClang::SetIntegerInitializerForVariable( decl, constant.Value.extOrTrunc(type_width)); } else { - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + LLDB_LOG(GetLog(LLDBLog::AST), "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a wider constant value ({4} bits). " "Ignoring constant.", @@ -190,7 +196,7 @@ Error UdtRecordCompleter::visitKnownMember( decl->setConstexpr(true); } else { LLDB_LOG( - GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + GetLog(LLDBLog::AST), "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a constant value of mismatched width " "({4} bits). Ignoring constant.", @@ -236,6 +242,8 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, } clang::QualType member_qt = m_ast_builder.GetOrCreateType(PdbTypeSymId(ti)); + if (member_qt.isNull()) + return Error::success(); m_ast_builder.CompleteType(member_qt); lldb::AccessType access = TranslateMemberAccess(data_member.getAccess()); @@ -289,10 +297,7 @@ Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, void UdtRecordCompleter::complete() { // Ensure the correct order for virtual bases. - std::stable_sort(m_bases.begin(), m_bases.end(), - [](const IndexedBase &lhs, const IndexedBase &rhs) { - return lhs.first < rhs.first; - }); + llvm::stable_sort(m_bases, llvm::less_first()); std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> bases; bases.reserve(m_bases.size()); diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp index f45287fd0fff..c3f424d06c54 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp @@ -22,13 +22,15 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/TypeSystem.h" - +#include "lldb/Utility/LLDBLog.h" +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" #include "llvm/DebugInfo/PDB/IPDBLineNumber.h" #include "llvm/DebugInfo/PDB/IPDBSourceFile.h" #include "llvm/DebugInfo/PDB/PDBSymbol.h" #include "llvm/DebugInfo/PDB/PDBSymbolData.h" #include "llvm/DebugInfo/PDB/PDBSymbolFunc.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeArray.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBaseClass.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionArg.h" @@ -709,7 +711,7 @@ lldb::TypeSP PDBASTParser::CreateLLDBTypeFromPDBType(const PDBSymbol &type) { bytes = size; Encoding encoding = TranslateBuiltinEncoding(builtin_kind); CompilerType builtin_ast_type = GetBuiltinTypeForPDBEncodingAndBitSize( - m_ast, *builtin_type, encoding, bytes.getValueOr(0) * 8); + m_ast, *builtin_type, encoding, bytes.value_or(0) * 8); if (builtin_type->isConstType()) builtin_ast_type = builtin_ast_type.AddConstModifier(); @@ -799,7 +801,8 @@ bool PDBASTParser::CompleteTypeFromPDB( if (uid_it == m_forward_decl_to_uid.end()) return true; - auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); + auto symbol_file = static_cast<SymbolFilePDB *>( + m_ast.GetSymbolFile()->GetBackingSymbolFile()); if (!symbol_file) return false; @@ -833,7 +836,8 @@ PDBASTParser::GetDeclForSymbol(const llvm::pdb::PDBSymbol &symbol) { if (it != m_uid_to_decl.end()) return it->second; - auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); + auto symbol_file = static_cast<SymbolFilePDB *>( + m_ast.GetSymbolFile()->GetBackingSymbolFile()); if (!symbol_file) return nullptr; @@ -999,7 +1003,8 @@ PDBASTParser::GetDeclContextForSymbol(const llvm::pdb::PDBSymbol &symbol) { return result; } - auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); + auto symbol_file = static_cast<SymbolFilePDB *>( + m_ast.GetSymbolFile()->GetBackingSymbolFile()); if (!symbol_file) return nullptr; @@ -1039,7 +1044,8 @@ clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol( if (specs.empty()) return m_ast.GetTranslationUnitDecl(); - auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); + auto symbol_file = static_cast<SymbolFilePDB *>( + m_ast.GetSymbolFile()->GetBackingSymbolFile()); if (!symbol_file) return m_ast.GetTranslationUnitDecl(); @@ -1092,7 +1098,8 @@ clang::DeclContext *PDBASTParser::GetDeclContextContainingSymbol( void PDBASTParser::ParseDeclsForDeclContext( const clang::DeclContext *decl_context) { - auto symbol_file = static_cast<SymbolFilePDB *>(m_ast.GetSymbolFile()); + auto symbol_file = static_cast<SymbolFilePDB *>( + m_ast.GetSymbolFile()->GetBackingSymbolFile()); if (!symbol_file) return; @@ -1298,7 +1305,7 @@ void PDBASTParser::AddRecordMembers( TypeSystemClang::SetIntegerInitializerForVariable( decl, value.toAPSInt().extOrTrunc(type_width)); } else { - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + LLDB_LOG(GetLog(LLDBLog::AST), "Class '{0}' has a member '{1}' of type '{2}' ({3} bits) " "which resolves to a wider constant value ({4} bits). " "Ignoring constant.", @@ -1316,7 +1323,7 @@ void PDBASTParser::AddRecordMembers( decl, value.toAPFloat()); decl->setConstexpr(true); } else { - LLDB_LOG(GetLogIfAllCategoriesSet(LIBLLDB_LOG_AST), + LLDB_LOG(GetLog(LLDBLog::AST), "Class '{0}' has a member '{1}' of type '{2}' ({3} " "bits) which resolves to a constant value of mismatched " "width ({4} bits). Ignoring constant.", diff --git a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp index 330188e29f00..96e9de704e41 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/PDBLocationToDWARFExpression.cpp @@ -25,6 +25,7 @@ using namespace lldb; using namespace lldb_private; using namespace lldb_private::npdb; +using namespace lldb_private::dwarf; using namespace llvm::pdb; static std::unique_ptr<IPDBFrameData> diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index a40b6ec9a635..bd3d16aad6c2 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -24,9 +24,11 @@ #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/Variable.h" +#include "lldb/Utility/LLDBLog.h" #include "lldb/Utility/Log.h" #include "lldb/Utility/RegularExpression.h" +#include "llvm/DebugInfo/PDB/ConcreteSymbolEnumerator.h" #include "llvm/DebugInfo/PDB/GenericError.h" #include "llvm/DebugInfo/PDB/IPDBDataStream.h" #include "llvm/DebugInfo/PDB/IPDBEnumChildren.h" @@ -44,7 +46,9 @@ #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugEnd.h" #include "llvm/DebugInfo/PDB/PDBSymbolFuncDebugStart.h" #include "llvm/DebugInfo/PDB/PDBSymbolPublicSymbol.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeBuiltin.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeEnum.h" +#include "llvm/DebugInfo/PDB/PDBSymbolTypeFunctionSig.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeTypedef.h" #include "llvm/DebugInfo/PDB/PDBSymbolTypeUDT.h" @@ -53,7 +57,7 @@ #include "Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h" #if defined(_WIN32) -#include "llvm/Config/config.h" +#include "llvm/Config/llvm-config.h" #endif using namespace lldb; @@ -73,6 +77,8 @@ lldb::LanguageType TranslateLanguage(PDB_Lang lang) { return lldb::LanguageType::eLanguageTypeC; case PDB_Lang::Swift: return lldb::LanguageType::eLanguageTypeSwift; + case PDB_Lang::Rust: + return lldb::LanguageType::eLanguageTypeRust; default: return lldb::LanguageType::eLanguageTypeUnknown; } @@ -129,7 +135,7 @@ SymbolFilePDB::CreateInstance(ObjectFileSP objfile_sp) { } SymbolFilePDB::SymbolFilePDB(lldb::ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {} + : SymbolFileCommon(std::move(objfile_sp)), m_session_up(), m_global_scope_up() {} SymbolFilePDB::~SymbolFilePDB() = default; @@ -307,8 +313,8 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func, LanguageType lang = ParseLanguage(comp_unit); auto type_system_or_err = GetTypeSystemForLanguage(lang); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to parse PDBFunc"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to parse PDBFunc"); return nullptr; } @@ -557,8 +563,8 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to ResolveTypeUID"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to ResolveTypeUID"); return nullptr; } @@ -594,8 +600,8 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get dynamic array info for UID"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get dynamic array info for UID"); return false; } @@ -616,8 +622,8 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get decl for UID"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get decl for UID"); return CompilerDecl(); } @@ -646,8 +652,8 @@ SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get DeclContext for UID"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get DeclContext for UID"); return CompilerDeclContext(); } @@ -676,8 +682,8 @@ SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get DeclContext containing UID"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get DeclContext containing UID"); return CompilerDeclContext(); } @@ -705,8 +711,8 @@ void SymbolFilePDB::ParseDeclsForContext( auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to parse decls for context"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to parse decls for context"); return; } @@ -791,7 +797,7 @@ uint32_t SymbolFilePDB::ResolveSymbolContext( std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); const size_t old_size = sc_list.GetSize(); const FileSpec &file_spec = src_location_spec.GetFileSpec(); - const uint32_t line = src_location_spec.GetLine().getValueOr(0); + const uint32_t line = src_location_spec.GetLine().value_or(0); if (resolve_scope & lldb::eSymbolContextCompUnit) { // Locate all compilation units with line numbers referencing the specified // file. For example, if `file_spec` is <vector>, then this should return @@ -1445,8 +1451,8 @@ void SymbolFilePDB::DumpClangAST(Stream &s) { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to dump ClangAST"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to dump ClangAST"); return; } @@ -1658,8 +1664,8 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() { auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to get PDB AST parser"); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to get PDB AST parser"); return nullptr; } @@ -1678,9 +1684,8 @@ SymbolFilePDB::FindNamespace(lldb_private::ConstString name, auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus); if (auto err = type_system_or_err.takeError()) { - LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), "Unable to find namespace {}", - name.AsCString()); + LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err), + "Unable to find namespace {}", name.AsCString()); return CompilerDeclContext(); } @@ -1974,8 +1979,7 @@ bool SymbolFilePDB::DeclContextMatchesThisSymbolFile( decl_ctx_type_system->GetMinimumLanguage(nullptr)); if (auto err = type_system_or_err.takeError()) { LLDB_LOG_ERROR( - lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_SYMBOLS), - std::move(err), + GetLog(LLDBLog::Symbols), std::move(err), "Unable to determine if DeclContext matches this symbol file"); return false; } diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h index 69f1d268edfd..5d4b51ba2e19 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -21,7 +21,7 @@ class PDBASTParser; -class SymbolFilePDB : public lldb_private::SymbolFile { +class SymbolFilePDB : public lldb_private::SymbolFileCommon { /// LLVM RTTI support. static char ID; @@ -29,7 +29,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp index d95cfea5e872..cc22eaeef779 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp @@ -51,8 +51,8 @@ void SymbolFileSymtab::GetTypes(SymbolContextScope *sc_scope, lldb_private::TypeList &type_list) {} SymbolFileSymtab::SymbolFileSymtab(ObjectFileSP objfile_sp) - : SymbolFile(std::move(objfile_sp)), m_source_indexes(), m_func_indexes(), - m_code_indexes(), m_objc_class_name_to_index() {} + : SymbolFileCommon(std::move(objfile_sp)), m_source_indexes(), + m_func_indexes(), m_code_indexes(), m_objc_class_name_to_index() {} uint32_t SymbolFileSymtab::CalculateAbilities() { uint32_t abilities = 0; diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h index 2dad12baac6f..0a9fa5fce1b0 100644 --- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h +++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.h @@ -15,7 +15,7 @@ #include "lldb/Symbol/SymbolFile.h" #include "lldb/Symbol/Symtab.h" -class SymbolFileSymtab : public lldb_private::SymbolFile { +class SymbolFileSymtab : public lldb_private::SymbolFileCommon { /// LLVM RTTI support. static char ID; @@ -23,7 +23,7 @@ public: /// LLVM RTTI support. /// \{ bool isA(const void *ClassID) const override { - return ClassID == &ID || SymbolFile::isA(ClassID); + return ClassID == &ID || SymbolFileCommon::isA(ClassID); } static bool classof(const SymbolFile *obj) { return obj->isA(&ID); } /// \} |
