diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp')
-rw-r--r-- | lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp | 115 |
1 files changed, 110 insertions, 5 deletions
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 9868a3283e0..2ac0b985a6a 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -15,6 +15,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/Type.h" +#include "Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h" #include "lldb/Core/Module.h" #include "lldb/Core/PluginManager.h" #include "lldb/Core/StreamBuffer.h" @@ -394,7 +395,11 @@ lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id, ProcSym proc(static_cast<SymbolRecordKind>(sym_record.kind())); cantFail(SymbolDeserializer::deserializeAs<ProcSym>(sym_record, proc)); + if (proc.FunctionType == TypeIndex::None()) + return nullptr; TypeSP func_type = GetOrCreateType(proc.FunctionType); + if (!func_type) + return nullptr; PdbTypeSymId sig_id(proc.FunctionType, false); Mangled mangled(proc.Name); @@ -515,9 +520,19 @@ lldb::TypeSP SymbolFileNativePDB::CreateSimpleType(TypeIndex ti, } static std::string GetUnqualifiedTypeName(const TagRecord &record) { + if (!record.hasUniqueName()) { + MSVCUndecoratedNameParser parser(record.Name); + llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers(); + + return specs.back().GetBaseName(); + } + llvm::ms_demangle::Demangler demangler; StringView sv(record.UniqueName.begin(), record.UniqueName.size()); llvm::ms_demangle::TagTypeNode *ttn = demangler.parseTagUniqueName(sv); + if (demangler.Error) + return record.Name; + llvm::ms_demangle::IdentifierNode *idn = ttn->QualifiedName->getUnqualifiedIdentifier(); return idn->toString(); @@ -696,7 +711,10 @@ TypeSP SymbolFileNativePDB::GetOrCreateType(PdbTypeSymId type_id) { if (iter != m_types.end()) return iter->second; - return CreateAndCacheType(type_id); + TypeSP type = CreateAndCacheType(type_id); + if (type) + m_obj_file->GetModule()->GetTypeList()->Insert(type); + return type; } VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) { @@ -821,7 +839,6 @@ FunctionSP SymbolFileNativePDB::GetOrCreateFunction(PdbCompilandSymId func_id, if (emplace_result.second) emplace_result.first->second = CreateFunction(func_id, comp_unit); - lldbassert(emplace_result.first->second); return emplace_result.first->second; } @@ -887,7 +904,26 @@ void SymbolFileNativePDB::AddSymbols(Symtab &symtab) { return; } size_t SymbolFileNativePDB::ParseCompileUnitFunctions(const SymbolContext &sc) { lldbassert(sc.comp_unit); - return false; + + PdbSymUid uid{sc.comp_unit->GetID()}; + lldbassert(uid.kind() == PdbSymUidKind::Compiland); + uint16_t modi = uid.asCompiland().modi; + CompilandIndexItem &cii = m_index->compilands().GetOrCreateCompiland(modi); + + size_t count = sc.comp_unit->GetNumFunctions(); + const CVSymbolArray &syms = cii.m_debug_stream.getSymbolArray(); + for (auto iter = syms.begin(); iter != syms.end(); ++iter) { + if (iter->kind() != S_LPROC32 && iter->kind() != S_GPROC32) + continue; + + PdbCompilandSymId sym_id{modi, iter.offset()}; + + FunctionSP func = GetOrCreateFunction(sym_id, *sc.comp_unit); + } + + size_t new_count = sc.comp_unit->GetNumFunctions(); + lldbassert(new_count >= count); + return new_count - count; } static bool NeedsResolvedCompileUnit(uint32_t resolve_scope) { @@ -1238,7 +1274,47 @@ size_t SymbolFileNativePDB::FindTypesByName(llvm::StringRef name, return match_count; } -size_t SymbolFileNativePDB::ParseTypes(const SymbolContext &sc) { return 0; } +size_t SymbolFileNativePDB::ParseTypes(const SymbolContext &sc) { + // Only do the full type scan the first time. + if (m_done_full_type_scan) + return 0; + + size_t old_count = m_obj_file->GetModule()->GetTypeList()->GetSize(); + LazyRandomTypeCollection &types = m_index->tpi().typeCollection(); + + // First process the entire TPI stream. + for (auto ti = types.getFirst(); ti; ti = types.getNext(*ti)) { + TypeSP type = GetOrCreateType(*ti); + if (type) + (void)type->GetFullCompilerType(); + } + + // Next look for S_UDT records in the globals stream. + for (const uint32_t gid : m_index->globals().getGlobalsTable()) { + PdbGlobalSymId global{gid, false}; + CVSymbol sym = m_index->ReadSymbolRecord(global); + if (sym.kind() != S_UDT) + continue; + + UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym)); + bool is_typedef = true; + if (IsTagRecord(PdbTypeSymId{udt.Type, false}, m_index->tpi())) { + CVType cvt = m_index->tpi().getType(udt.Type); + llvm::StringRef name = CVTagRecord::create(cvt).name(); + if (name == udt.Name) + is_typedef = false; + } + + if (is_typedef) + GetOrCreateTypedef(global); + } + + size_t new_count = m_obj_file->GetModule()->GetTypeList()->GetSize(); + + m_done_full_type_scan = true; + + return new_count - old_count; +} size_t SymbolFileNativePDB::ParseVariablesForCompileUnit(CompileUnit &comp_unit, @@ -1253,6 +1329,8 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id, bool is_param) { ModuleSP module = GetObjectFile()->GetModule(); VariableInfo var_info = GetVariableLocationInfo(*m_index, var_id, module); + if (!var_info.location || !var_info.ranges) + return nullptr; CompilandIndexItem *cii = m_index->compilands().GetCompiland(var_id.modi); CompUnitSP comp_unit_sp = GetOrCreateCompileUnit(*cii); @@ -1285,6 +1363,32 @@ VariableSP SymbolFileNativePDB::GetOrCreateLocalVariable( return CreateLocalVariable(scope_id, var_id, is_param); } +TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) { + CVSymbol sym = m_index->ReadSymbolRecord(id); + lldbassert(sym.kind() == SymbolKind::S_UDT); + + UDTSym udt = llvm::cantFail(SymbolDeserializer::deserializeAs<UDTSym>(sym)); + + TypeSP target_type = GetOrCreateType(udt.Type); + + (void)m_ast->GetOrCreateTypedefDecl(id); + + Declaration decl; + return std::make_shared<lldb_private::Type>( + toOpaqueUid(id), this, ConstString(udt.Name), target_type->GetByteSize(), + nullptr, target_type->GetID(), lldb_private::Type::eEncodingIsTypedefUID, + decl, target_type->GetForwardCompilerType(), + lldb_private::Type::eResolveStateForward); +} + +TypeSP SymbolFileNativePDB::GetOrCreateTypedef(PdbGlobalSymId id) { + auto iter = m_types.find(toOpaqueUid(id)); + if (iter != m_types.end()) + return iter->second; + + return CreateTypedef(id); +} + size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { Block &block = GetOrCreateBlock(block_id); @@ -1349,7 +1453,8 @@ size_t SymbolFileNativePDB::ParseVariablesForBlock(PdbCompilandSymId block_id) { variable = GetOrCreateLocalVariable(block_id, child_sym_id, is_param); if (is_param) --params_remaining; - variables->AddVariableIfUnique(variable); + if (variable) + variables->AddVariableIfUnique(variable); break; default: break; |