diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.h @@ -11,6 +11,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Threading.h" #include "Plugins/ExpressionParser/Clang/ClangASTImporter.h" @@ -122,7 +123,9 @@ TypeIndex func_ti, CompilerType func_ct, uint32_t param_count, clang::StorageClass func_storage, bool is_inline, clang::DeclContext *parent); - void ParseAllNamespacesPlusChildrenOf(llvm::Optional parent); + void ParseNamespace(clang::DeclContext &parent); + void ParseAllTypes(); + void ParseAllFunctionsAndNonLocalVars(); void ParseDeclsForSimpleContext(clang::DeclContext &context); void ParseBlockChildren(PdbCompilandSymId block_id); @@ -135,7 +138,8 @@ TypeSystemClang &m_clang; ClangASTImporter m_importer; - + llvm::once_flag m_parse_functions_and_non_local_vars; + llvm::once_flag m_parse_all_types; llvm::DenseMap m_decl_to_status; llvm::DenseMap m_uid_to_decl; llvm::DenseMap m_uid_to_type; @@ -145,6 +149,7 @@ llvm::DenseMap, 8>> m_cxx_record_map; + llvm::DenseSet m_parsed_namespaces; }; } // namespace npdb diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp --- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp @@ -21,7 +21,6 @@ #include "lldb/Core/Module.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Utility/LLDBAssert.h" - #include "PdbUtil.h" #include "UdtRecordCompleter.h" #include "SymbolFileNativePDB.h" @@ -1232,8 +1231,11 @@ return llvm::isa(&context); } -void PdbAstBuilder::ParseAllNamespacesPlusChildrenOf( - llvm::Optional parent) { +void PdbAstBuilder::ParseNamespace(clang::DeclContext &context) { + clang::NamespaceDecl *ns = llvm::dyn_cast(&context); + if (m_parsed_namespaces.contains(ns)) + return; + std::string qname = ns->getQualifiedNameAsString(); SymbolFileNativePDB *pdb = static_cast( m_clang.GetSymbolFile()->GetBackingSymbolFile()); PdbIndex &index = pdb->GetIndex(); @@ -1247,12 +1249,6 @@ CVTagRecord tag = CVTagRecord::create(cvt); - if (!parent) { - clang::QualType qt = GetOrCreateType(tid); - CompleteType(qt); - continue; - } - // Call CreateDeclInfoForType unconditionally so that the namespace info // gets created. But only call CreateRecordType if the namespace name // matches. @@ -1263,41 +1259,68 @@ continue; clang::NamespaceDecl *ns = llvm::cast(context); - std::string actual_ns = ns->getQualifiedNameAsString(); - if (llvm::StringRef(actual_ns).startswith(*parent)) { - clang::QualType qt = GetOrCreateType(tid); - CompleteType(qt); - continue; + llvm::StringRef ns_name = ns->getName(); + if (ns_name.startswith(qname)) { + ns_name = ns_name.drop_front(qname.size()); + if (ns_name.startswith("::")) + GetOrCreateType(tid); } } + ParseAllFunctionsAndNonLocalVars(); + m_parsed_namespaces.insert(ns); +} - uint32_t module_count = index.dbi().modules().getModuleCount(); - for (uint16_t modi = 0; modi < module_count; ++modi) { - CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(modi); - const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray(); - auto iter = symbols.begin(); - while (iter != symbols.end()) { - PdbCompilandSymId sym_id{modi, iter.offset()}; - - switch (iter->kind()) { - case S_GPROC32: - case S_LPROC32: - GetOrCreateFunctionDecl(sym_id); - iter = symbols.at(getScopeEndOffset(*iter)); - break; - case S_GDATA32: - case S_GTHREAD32: - case S_LDATA32: - case S_LTHREAD32: - GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id); - ++iter; - break; - default: - ++iter; +void PdbAstBuilder::ParseAllTypes() { + llvm::call_once(m_parse_all_types, [this]() { + SymbolFileNativePDB *pdb = static_cast( + m_clang.GetSymbolFile()->GetBackingSymbolFile()); + PdbIndex &index = pdb->GetIndex(); + TypeIndex ti{index.tpi().TypeIndexBegin()}; + for (const CVType &cvt : index.tpi().typeArray()) { + PdbTypeSymId tid{ti}; + ++ti; + + if (!IsTagRecord(cvt)) continue; + + GetOrCreateType(tid); + } + }); +} + +void PdbAstBuilder::ParseAllFunctionsAndNonLocalVars() { + llvm::call_once(m_parse_functions_and_non_local_vars, [this]() { + SymbolFileNativePDB *pdb = static_cast( + m_clang.GetSymbolFile()->GetBackingSymbolFile()); + PdbIndex &index = pdb->GetIndex(); + uint32_t module_count = index.dbi().modules().getModuleCount(); + for (uint16_t modi = 0; modi < module_count; ++modi) { + CompilandIndexItem &cii = index.compilands().GetOrCreateCompiland(modi); + const CVSymbolArray &symbols = cii.m_debug_stream.getSymbolArray(); + auto iter = symbols.begin(); + while (iter != symbols.end()) { + PdbCompilandSymId sym_id{modi, iter.offset()}; + + switch (iter->kind()) { + case S_GPROC32: + case S_LPROC32: + GetOrCreateFunctionDecl(sym_id); + iter = symbols.at(getScopeEndOffset(*iter)); + break; + case S_GDATA32: + case S_GTHREAD32: + case S_LDATA32: + case S_LTHREAD32: + GetOrCreateVariableDecl(PdbCompilandSymId(modi, 0), sym_id); + ++iter; + break; + default: + ++iter; + continue; + } } } - } + }); } static CVSymbolArray skipFunctionParameters(clang::Decl &decl, @@ -1384,14 +1407,13 @@ // work (such as parsing the items that appear within the namespaces) at the // same time. if (context.isTranslationUnit()) { - ParseAllNamespacesPlusChildrenOf(llvm::None); + ParseAllTypes(); + ParseAllFunctionsAndNonLocalVars(); return; } if (context.isNamespace()) { - clang::NamespaceDecl &ns = *llvm::dyn_cast(&context); - std::string qname = ns.getQualifiedNameAsString(); - ParseAllNamespacesPlusChildrenOf(llvm::StringRef{qname}); + ParseNamespace(context); return; }