diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2021-12-25 22:30:44 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2021-12-25 22:30:44 +0000 |
| commit | 77fc4c146f0870ffb09c1afb823ccbe742c5e6ff (patch) | |
| tree | 5c0eb39553003b9c75a901af6bc4ddabd6f2f28c /lldb/source/Plugins/SymbolFile | |
| parent | f65dcba83ce5035ab88a85fe17628b447eb56e1b (diff) | |
Diffstat (limited to 'lldb/source/Plugins/SymbolFile')
10 files changed, 176 insertions, 40 deletions
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp index 4ac6e165dda3..b90f104c4d21 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -1530,7 +1530,6 @@ TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType( return type_sp; SymbolFileDWARF *dwarf = die.GetDWARF(); - TypeList &type_list = dwarf->GetTypeList(); DWARFDIE sc_parent_die = SymbolFileDWARF::GetParentSymbolContextDIE(die); dw_tag_t sc_parent_tag = sc_parent_die.Tag(); @@ -1550,10 +1549,6 @@ TypeSP DWARFASTParserClang::UpdateSymbolContextScopeForType( if (symbol_context_scope != nullptr) type_sp->SetSymbolContextScope(symbol_context_scope); - // We are ready to put this type into the uniqued list up at the module - // level. - type_list.Insert(type_sp); - dwarf->GetDIEToType()[die.GetDIE()] = type_sp.get(); return type_sp; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h index cece29dcf9ac..71d4c1e6c52f 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFUnit.h @@ -153,7 +153,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 ? *m_addr_base : 0; } + dw_addr_t GetAddrBase() const { return m_addr_base.getValueOr(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/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp index 8c20244a6c44..8c995ef2eb2a 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -1097,7 +1097,8 @@ bool SymbolFileDWARF::ParseImportedModules( if (const char *include_path = module_die.GetAttributeValueAsString( DW_AT_LLVM_include_path, nullptr)) { FileSpec include_spec(include_path, dwarf_cu->GetPathStyle()); - MakeAbsoluteAndRemap(include_spec, *dwarf_cu, m_objfile_sp->GetModule()); + MakeAbsoluteAndRemap(include_spec, *dwarf_cu, + m_objfile_sp->GetModule()); module.search_path = ConstString(include_spec.GetPath()); } if (const char *sysroot = dwarf_cu->DIE().GetAttributeValueAsString( @@ -1924,7 +1925,7 @@ void SymbolFileDWARF::ResolveFunctionAndBlock(lldb::addr_t file_vm_addr, block_die = function_die.LookupDeepestBlock(file_vm_addr); } - if (!sc.function || ! lookup_block) + if (!sc.function || !lookup_block) return; Block &block = sc.function->GetBlock(true); @@ -2319,7 +2320,8 @@ void SymbolFileDWARF::FindFunctions(ConstString name, if (log) { GetObjectFile()->GetModule()->LogMessage( log, - "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, sc_list)", + "SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, " + "sc_list)", name.GetCString(), name_type_mask); } @@ -2352,8 +2354,7 @@ void SymbolFileDWARF::FindFunctions(ConstString name, log, "SymbolFileDWARF::FindFunctions (name=\"%s\", " "name_type_mask=0x%x, include_inlines=%d, sc_list) => %u", - name.GetCString(), name_type_mask, include_inlines, - num_matches); + name.GetCString(), name_type_mask, include_inlines, num_matches); } } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h index 271ce7be1eea..e81ce28cb86e 100644 --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -253,8 +253,8 @@ public: ExternalTypeModuleMap; /// Return the list of Clang modules imported by this SymbolFile. - const ExternalTypeModuleMap& getExternalTypeModules() const { - return m_external_type_modules; + const ExternalTypeModuleMap &getExternalTypeModules() const { + return m_external_type_modules; } virtual DWARFDIE GetDIE(const DIERef &die_ref); @@ -328,7 +328,6 @@ public: return m_parse_time; } - protected: typedef llvm::DenseMap<const DWARFDebugInfoEntry *, lldb_private::Type *> DIEToTypePtr; @@ -428,9 +427,10 @@ protected: virtual lldb::TypeSP FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext &die_decl_ctx); - virtual lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE( - const DWARFDIE &die, lldb_private::ConstString type_name, - bool must_be_implementation); + virtual lldb::TypeSP + FindCompleteObjCDefinitionTypeForDIE(const DWARFDIE &die, + lldb_private::ConstString type_name, + bool must_be_implementation); lldb_private::Symbol * GetObjCClassSymbol(lldb_private::ConstString objc_class_name); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index c29fc2230a67..9473befa6cc3 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -30,6 +30,70 @@ using namespace lldb_private::npdb; using namespace llvm::codeview; using namespace llvm::pdb; +namespace { +struct CreateMethodDecl : public TypeVisitorCallbacks { + CreateMethodDecl(PdbIndex &m_index, TypeSystemClang &m_clang, + TypeIndex func_type_index, + clang::FunctionDecl *&function_decl, + lldb::opaque_compiler_type_t parent_ty, + llvm::StringRef proc_name, CompilerType func_ct) + : m_index(m_index), m_clang(m_clang), func_type_index(func_type_index), + function_decl(function_decl), parent_ty(parent_ty), + proc_name(proc_name), func_ct(func_ct) {} + PdbIndex &m_index; + TypeSystemClang &m_clang; + TypeIndex func_type_index; + clang::FunctionDecl *&function_decl; + lldb::opaque_compiler_type_t parent_ty; + llvm::StringRef proc_name; + CompilerType func_ct; + + llvm::Error visitKnownMember(CVMemberRecord &cvr, + OverloadedMethodRecord &overloaded) override { + TypeIndex method_list_idx = overloaded.MethodList; + + CVType method_list_type = m_index.tpi().getType(method_list_idx); + assert(method_list_type.kind() == LF_METHODLIST); + + MethodOverloadListRecord method_list; + llvm::cantFail(TypeDeserializer::deserializeAs<MethodOverloadListRecord>( + method_list_type, method_list)); + + for (const OneMethodRecord &method : method_list.Methods) { + if (method.getType().getIndex() == func_type_index.getIndex()) + AddMethod(overloaded.Name, method.getAccess(), method.getOptions(), + method.Attrs); + } + + return llvm::Error::success(); + } + + llvm::Error visitKnownMember(CVMemberRecord &cvr, + OneMethodRecord &record) override { + AddMethod(record.getName(), record.getAccess(), record.getOptions(), + record.Attrs); + return llvm::Error::success(); + } + + void AddMethod(llvm::StringRef name, MemberAccess access, + MethodOptions options, MemberAttributes attrs) { + if (name != proc_name || function_decl) + return; + lldb::AccessType access_type = TranslateMemberAccess(access); + bool is_virtual = attrs.isVirtual(); + bool is_static = attrs.isStatic(); + bool is_artificial = (options & MethodOptions::CompilerGenerated) == + MethodOptions::CompilerGenerated; + function_decl = m_clang.AddMethodToCXXRecordType( + parent_ty, proc_name, + /*mangled_name=*/nullptr, func_ct, /*access=*/access_type, + /*is_virtual=*/is_virtual, /*is_static=*/is_static, + /*is_inline=*/false, /*is_explicit=*/false, + /*is_attr_used=*/false, /*is_artificial=*/is_artificial); + } +}; +} // namespace + static llvm::Optional<PdbCompilandSymId> FindSymbolScope(PdbIndex &index, PdbCompilandSymId id) { CVSymbol sym = index.ReadSymbolRecord(id); @@ -681,7 +745,8 @@ bool PdbAstBuilder::CompleteTagDecl(clang::TagDecl &tag) { // 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); + UdtRecordCompleter completer(best_ti, ct, tag, *this, m_index, + m_cxx_record_map); auto error = llvm::codeview::visitMemberRecordStream(field_list_cvt.data(), completer); completer.complete(); @@ -1014,8 +1079,62 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { proc_name.consume_front(context_name); proc_name.consume_front("::"); - clang::FunctionDecl *function_decl = m_clang.CreateFunctionDeclaration( - parent, OptionalClangModuleID(), proc_name, func_ct, storage, false); + clang::FunctionDecl *function_decl = nullptr; + if (parent->isRecord()) { + clang::QualType parent_qt = llvm::dyn_cast<clang::TypeDecl>(parent) + ->getTypeForDecl() + ->getCanonicalTypeInternal(); + lldb::opaque_compiler_type_t parent_opaque_ty = + ToCompilerType(parent_qt).GetOpaqueQualType(); + + 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})) { + return nullptr; + } + } + + CVType cvt = m_index.tpi().getType(type_id.index); + 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(); + // If it's a forward reference, try to get the real TypeIndex. + if (class_record.isForwardRef()) { + llvm::Expected<TypeIndex> eti = + m_index.tpi().findFullDeclForForwardRef(class_index); + if (eti) { + class_record = + CVTagRecord::create(m_index.tpi().getType(*eti)).asClass(); + } + } + 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)) + llvm::consumeError(std::move(err)); + } + + if (!function_decl) { + function_decl = m_clang.AddMethodToCXXRecordType( + parent_opaque_ty, proc_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}); + } else { + function_decl = m_clang.CreateFunctionDeclaration( + parent, OptionalClangModuleID(), proc_name, func_ct, storage, false); + CreateFunctionParameters(func_id, *function_decl, + func_type->getNumParams()); + } lldbassert(m_uid_to_decl.count(toOpaqueUid(func_id)) == 0); m_uid_to_decl[toOpaqueUid(func_id)] = function_decl; @@ -1024,8 +1143,6 @@ PdbAstBuilder::GetOrCreateFunctionDecl(PdbCompilandSymId func_id) { status.uid = toOpaqueUid(func_id); m_decl_to_status.insert({function_decl, status}); - CreateFunctionParameters(func_id, *function_decl, func_type->getNumParams()); - return function_decl; } @@ -1163,15 +1280,15 @@ clang::QualType PdbAstBuilder::CreateFunctionType( } static bool isTagDecl(clang::DeclContext &context) { - return !!llvm::dyn_cast<clang::TagDecl>(&context); + return llvm::isa<clang::TagDecl>(&context); } static bool isFunctionDecl(clang::DeclContext &context) { - return !!llvm::dyn_cast<clang::FunctionDecl>(&context); + return llvm::isa<clang::FunctionDecl>(&context); } static bool isBlockDecl(clang::DeclContext &context) { - return !!llvm::dyn_cast<clang::BlockDecl>(&context); + return llvm::isa<clang::BlockDecl>(&context); } void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf( diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h index 7bb2584d19a3..73accf5e5e68 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h @@ -137,6 +137,12 @@ private: llvm::DenseMap<clang::Decl *, DeclStatus> m_decl_to_status; llvm::DenseMap<lldb::user_id_t, clang::Decl *> m_uid_to_decl; llvm::DenseMap<lldb::user_id_t, clang::QualType> m_uid_to_type; + + // From class/struct's opaque_compiler_type_t to a set containing the pairs of + // method's name and CompilerType. + llvm::DenseMap<lldb::opaque_compiler_type_t, + llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>> + m_cxx_record_map; }; } // namespace npdb diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index bf101ac1acf1..e859b1d5a86c 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -900,7 +900,7 @@ lldb::LanguageType SymbolFileNativePDB::ParseLanguage(CompileUnit &comp_unit) { return TranslateLanguage(item->m_compile_opts->getLanguage()); } -void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; } +void SymbolFileNativePDB::AddSymbols(Symtab &symtab) {} size_t SymbolFileNativePDB::ParseFunctions(CompileUnit &comp_unit) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp index c8fb46c75034..d0b27bc5bf79 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.cpp @@ -28,13 +28,15 @@ using namespace lldb_private::npdb; using Error = llvm::Error; -UdtRecordCompleter::UdtRecordCompleter(PdbTypeSymId id, - CompilerType &derived_ct, - clang::TagDecl &tag_decl, - PdbAstBuilder &ast_builder, - PdbIndex &index) +UdtRecordCompleter::UdtRecordCompleter( + PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl, + PdbAstBuilder &ast_builder, PdbIndex &index, + llvm::DenseMap<lldb::opaque_compiler_type_t, + llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>> + &cxx_record_map) : m_id(id), m_derived_ct(derived_ct), m_tag_decl(tag_decl), - m_ast_builder(ast_builder), m_index(index) { + m_ast_builder(ast_builder), m_index(index), + m_cxx_record_map(cxx_record_map) { CVType cvt = m_index.tpi().getType(m_id.index); switch (cvt.kind()) { case LF_ENUM: @@ -78,14 +80,24 @@ void UdtRecordCompleter::AddMethod(llvm::StringRef name, TypeIndex type_idx, clang::QualType method_qt = m_ast_builder.GetOrCreateType(PdbTypeSymId(type_idx)); 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(); + auto iter = m_cxx_record_map.find(derived_opaque_ty); + if (iter != m_cxx_record_map.end()) { + if (iter->getSecond().contains({name, method_ct})) { + return; + } + } lldb::AccessType access_type = TranslateMemberAccess(access); bool is_artificial = (options & MethodOptions::CompilerGenerated) == MethodOptions::CompilerGenerated; m_ast_builder.clang().AddMethodToCXXRecordType( - m_derived_ct.GetOpaqueQualType(), name.data(), nullptr, - m_ast_builder.ToCompilerType(method_qt), access_type, attrs.isVirtual(), - attrs.isStatic(), false, false, false, is_artificial); + derived_opaque_ty, name.data(), nullptr, method_ct, + access_type, attrs.isVirtual(), attrs.isStatic(), false, false, false, + is_artificial); + + m_cxx_record_map[derived_opaque_ty].insert({name, method_ct}); } Error UdtRecordCompleter::visitKnownMember(CVMemberRecord &cvr, diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h index ae7e47c82fe5..9c6b5ed28bc2 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/UdtRecordCompleter.h @@ -54,11 +54,17 @@ class UdtRecordCompleter : public llvm::codeview::TypeVisitorCallbacks { PdbIndex &m_index; std::vector<IndexedBase> m_bases; ClangASTImporter::LayoutInfo m_layout; + llvm::DenseMap<lldb::opaque_compiler_type_t, + llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, 8>> + &m_cxx_record_map; public: - UdtRecordCompleter(PdbTypeSymId id, CompilerType &derived_ct, - clang::TagDecl &tag_decl, PdbAstBuilder &ast_builder, - PdbIndex &index); + UdtRecordCompleter( + PdbTypeSymId id, CompilerType &derived_ct, clang::TagDecl &tag_decl, + PdbAstBuilder &ast_builder, PdbIndex &index, + llvm::DenseMap<lldb::opaque_compiler_type_t, + llvm::SmallSet<std::pair<llvm::StringRef, CompilerType>, + 8>> &cxx_record_map); #define MEMBER_RECORD(EnumName, EnumVal, Name) \ llvm::Error visitKnownMember(llvm::codeview::CVMemberRecord &CVR, \ diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp index db0ae241be7e..a40b6ec9a635 100644 --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -239,7 +239,6 @@ void SymbolFilePDB::GetCompileUnitIndex( } } index = UINT32_MAX; - return; } std::unique_ptr<llvm::pdb::PDBSymbolCompiland> @@ -402,7 +401,7 @@ static size_t ParseFunctionBlocksForPDBSymbol( block = parent_block; else break; - } else if (llvm::dyn_cast<PDBSymbolBlock>(pdb_symbol)) { + } else if (llvm::isa<PDBSymbolBlock>(pdb_symbol)) { auto uid = pdb_symbol->getSymIndexId(); if (parent_block->FindBlockByID(uid)) break; |
