diff options
Diffstat (limited to 'lldb/source/Plugins/SymbolFile/NativePDB')
3 files changed, 86 insertions, 33 deletions
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp index 709281cb3270..933c4361d93d 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -1169,6 +1169,7 @@ clang::QualType PdbAstBuilder::CreateEnumType(PdbTypeSymId id, clang::QualType PdbAstBuilder::CreateArrayType(const ArrayRecord &ar) { clang::QualType element_type = GetOrCreateType(ar.ElementType); + TypeSystemClang::RequireCompleteType(ToCompilerType(element_type)); SymbolFileNativePDB *pdb = static_cast<SymbolFileNativePDB *>( m_clang.GetSymbolFile()->GetBackingSymbolFile()); diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp index 112eb06e462f..e99c585d7eb1 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1624,6 +1624,8 @@ size_t SymbolFileNativePDB::ParseBlocksRecursive(Function &func) { for (uint64_t uid : remove_uids) { m_inline_sites.erase(uid); } + + func.GetBlock(false).SetBlockInfoHasBeenParsed(true, true); return count; } @@ -1655,22 +1657,62 @@ void SymbolFileNativePDB::DumpClangAST(Stream &s, llvm::StringRef filter) { clang->GetNativePDBParser()->Dump(s, filter); } -void SymbolFileNativePDB::CacheFunctionNames() { - if (!m_func_full_names.IsEmpty()) +void SymbolFileNativePDB::CacheGlobalBaseNames() { + if (!m_func_full_names.IsEmpty() || !m_global_variable_base_names.IsEmpty()) return; // (segment, code offset) -> gid - std::map<std::pair<uint16_t, uint32_t>, uint32_t> addr_ids; + std::map<std::pair<uint16_t, uint32_t>, uint32_t> func_addr_ids; - // First, find all function references in the globals table. + // First, look through all items in the globals table. for (const uint32_t gid : m_index->globals().getGlobalsTable()) { - CVSymbol ref_sym = m_index->symrecords().readRecord(gid); - auto kind = ref_sym.kind(); + CVSymbol sym = m_index->symrecords().readRecord(gid); + auto kind = sym.kind(); + + // If this is a global variable, we only need to look at the name + llvm::StringRef name; + switch (kind) { + case SymbolKind::S_GDATA32: + case SymbolKind::S_LDATA32: { + DataSym data = + llvm::cantFail(SymbolDeserializer::deserializeAs<DataSym>(sym)); + name = data.Name; + break; + } + case SymbolKind::S_GTHREAD32: + case SymbolKind::S_LTHREAD32: { + ThreadLocalDataSym data = llvm::cantFail( + SymbolDeserializer::deserializeAs<ThreadLocalDataSym>(sym)); + name = data.Name; + break; + } + case SymbolKind::S_CONSTANT: { + ConstantSym data = + llvm::cantFail(SymbolDeserializer::deserializeAs<ConstantSym>(sym)); + name = data.Name; + break; + } + default: + break; + } + + if (!name.empty()) { + llvm::StringRef base = MSVCUndecoratedNameParser::DropScope(name); + if (base.empty()) + base = name; + + m_global_variable_base_names.Append(ConstString(base), gid); + continue; + } + if (kind != S_PROCREF && kind != S_LPROCREF) continue; + // For functions, we need to follow the reference to the procedure and look + // at the type + ProcRefSym ref = - llvm::cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(ref_sym)); + llvm::cantFail(SymbolDeserializer::deserializeAs<ProcRefSym>(sym)); if (ref.Name.empty()) continue; @@ -1694,7 +1736,7 @@ void SymbolFileNativePDB::CacheFunctionNames() { // The function/procedure symbol only contains the demangled name. // The mangled names are in the publics table. Save the address of this // function to lookup the mangled name later. - addr_ids.emplace(std::make_pair(proc.Segment, proc.CodeOffset), gid); + func_addr_ids.emplace(std::make_pair(proc.Segment, proc.CodeOffset), gid); llvm::StringRef basename = MSVCUndecoratedNameParser::DropScope(proc.Name); if (basename.empty()) @@ -1729,43 +1771,47 @@ void SymbolFileNativePDB::CacheFunctionNames() { continue; // Check if this symbol is for one of our functions. - auto it = addr_ids.find({pub.Segment, pub.Offset}); - if (it != addr_ids.end()) + auto it = func_addr_ids.find({pub.Segment, pub.Offset}); + if (it != func_addr_ids.end()) m_func_full_names.Append(ConstString(pub.Name), it->second); } // Sort them before value searching is working properly. - m_func_full_names.Sort(); + m_func_full_names.Sort(std::less<uint32_t>()); m_func_full_names.SizeToFit(); - m_func_method_names.Sort(); + m_func_method_names.Sort(std::less<uint32_t>()); m_func_method_names.SizeToFit(); - m_func_base_names.Sort(); + m_func_base_names.Sort(std::less<uint32_t>()); m_func_base_names.SizeToFit(); + m_global_variable_base_names.Sort(std::less<uint32_t>()); + m_global_variable_base_names.SizeToFit(); } void SymbolFileNativePDB::FindGlobalVariables( ConstString name, const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, VariableList &variables) { std::lock_guard<std::recursive_mutex> guard(GetModuleMutex()); - using SymbolAndOffset = std::pair<uint32_t, llvm::codeview::CVSymbol>; - std::vector<SymbolAndOffset> results = m_index->globals().findRecordsByName( - name.GetStringRef(), m_index->symrecords()); - for (const SymbolAndOffset &result : results) { - switch (result.second.kind()) { - case SymbolKind::S_GDATA32: - case SymbolKind::S_LDATA32: - case SymbolKind::S_GTHREAD32: - case SymbolKind::S_LTHREAD32: - case SymbolKind::S_CONSTANT: { - PdbGlobalSymId global(result.first, false); - if (VariableSP var = GetOrCreateGlobalVariable(global)) - variables.AddVariable(var); - break; - } - default: + CacheGlobalBaseNames(); + + std::vector<uint32_t> results; + m_global_variable_base_names.GetValues(name, results); + + size_t n_matches = 0; + for (uint32_t gid : results) { + PdbGlobalSymId global(gid, false); + + if (parent_decl_ctx.IsValid() && + GetDeclContextContainingUID(toOpaqueUid(global)) != parent_decl_ctx) continue; - } + + VariableSP var = GetOrCreateGlobalVariable(global); + if (!var) + continue; + variables.AddVariable(var); + + if (++n_matches >= max_matches) + break; } } @@ -1783,7 +1829,7 @@ void SymbolFileNativePDB::FindFunctions( name_type_mask & eFunctionNameTypeBase || name_type_mask & eFunctionNameTypeMethod)) return; - CacheFunctionNames(); + CacheGlobalBaseNames(); std::set<uint32_t> resolved_ids; // avoid duplicate lookups auto resolve_from = [&](UniqueCStringMap<uint32_t> &Names) { @@ -2426,7 +2472,7 @@ void SymbolFileNativePDB::BuildParentMap() { // After calling Append(), the type-name map needs to be sorted again to be // able to look up a type by its name. - m_type_base_names.Sort(); + m_type_base_names.Sort(std::less<uint32_t>()); // Now that we know the forward -> full mapping of all type indices, we can // re-write all the indices. At the end of this process, we want a mapping diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h index cfa00416d967..095b40c72c52 100644 --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -260,7 +260,10 @@ private: std::vector<CompilerContext> GetContextForType(llvm::codeview::TypeIndex ti); - void CacheFunctionNames(); + /// Caches the basenames of symbols found in the globals stream. + /// + /// This includes functions and global variables + void CacheGlobalBaseNames(); void CacheUdtDeclarations(); llvm::Expected<Declaration> ResolveUdtDeclaration(PdbTypeSymId type_id); @@ -306,6 +309,9 @@ private: lldb_private::UniqueCStringMap<uint32_t> m_func_base_names; /// method basename -> Global ID(s) lldb_private::UniqueCStringMap<uint32_t> m_func_method_names; + + /// global variable basename -> Global ID(s) + lldb_private::UniqueCStringMap<uint32_t> m_global_variable_base_names; }; } // namespace npdb |
