diff --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h --- a/lldb/include/lldb/Core/Module.h +++ b/lldb/include/lldb/Core/Module.h @@ -429,7 +429,11 @@ /// This behaves like the other FindTypes method but allows to /// specify a DeclContext and a language for the type being searched /// for. + /// + /// \param searched_symbol_files + /// Prevents one file from being visited multiple times. void FindTypes(llvm::ArrayRef pattern, LanguageSet languages, + llvm::DenseSet &searched_symbol_files, TypeMap &types); lldb::TypeSP FindFirstType(const SymbolContext &sc, diff --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h --- a/lldb/include/lldb/Symbol/SymbolFile.h +++ b/lldb/include/lldb/Symbol/SymbolFile.h @@ -193,9 +193,14 @@ TypeMap &types); /// Find types specified by a CompilerContextPattern. - /// \param languages Only return results in these languages. - virtual void FindTypes(llvm::ArrayRef pattern, - LanguageSet languages, TypeMap &types); + /// \param languages + /// Only return results in these languages. + /// \param searched_symbol_files + /// Prevents one file from being visited multiple times. + virtual void + FindTypes(llvm::ArrayRef pattern, LanguageSet languages, + llvm::DenseSet &searched_symbol_files, + TypeMap &types); virtual void GetMangledNamesForFunction(const std::string &scope_qualified_name, diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -1006,12 +1006,14 @@ } } -void Module::FindTypes(llvm::ArrayRef pattern, - LanguageSet languages, TypeMap &types) { +void Module::FindTypes( + llvm::ArrayRef pattern, LanguageSet languages, + llvm::DenseSet &searched_symbol_files, + TypeMap &types) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION); if (SymbolFile *symbols = GetSymbolFile()) - symbols->FindTypes(pattern, languages, types); + symbols->FindTypes(pattern, languages, searched_symbol_files, types); } SymbolFile *Module::GetSymbolFile(bool can_create, Stream *feedback_strm) { diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -112,6 +112,7 @@ TypeMap &types) override; void FindTypes(llvm::ArrayRef pattern, LanguageSet languages, + llvm::DenseSet &searched_symbol_files, TypeMap &types) override; llvm::Expected diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp --- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -307,8 +307,9 @@ uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) {} -void SymbolFileBreakpad::FindTypes(llvm::ArrayRef pattern, - LanguageSet languages, TypeMap &types) {} +void SymbolFileBreakpad::FindTypes( + llvm::ArrayRef pattern, LanguageSet languages, + llvm::DenseSet &searched_symbol_files, TypeMap &types) {} void SymbolFileBreakpad::AddSymbols(Symtab &symtab) { Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_SYMBOLS); diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -150,7 +150,9 @@ // The type in the Clang module must have the same language as the current CU. LanguageSet languages; languages.Insert(die.GetCU()->GetLanguageType()); - dwo_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, dwo_types); + llvm::DenseSet searched_symbol_files; + dwo_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, + searched_symbol_files, dwo_types); if (dwo_types.Empty()) { if (!IsClangModuleFwdDecl(die)) return TypeSP(); @@ -161,8 +163,8 @@ for (const auto &name_module : sym_file.getExternalTypeModules()) { if (!name_module.second) continue; - name_module.second->GetSymbolFile()->FindTypes(decl_context, - languages, dwo_types); + name_module.second->GetSymbolFile()->FindTypes( + decl_context, languages, searched_symbol_files, dwo_types); if (dwo_types.GetSize()) break; } diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -190,6 +190,7 @@ void FindTypes(llvm::ArrayRef pattern, lldb_private::LanguageSet languages, + llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) override; void GetTypes(lldb_private::SymbolContextScope *sc_scope, diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp --- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2366,12 +2366,10 @@ llvm::DenseSet &searched_symbol_files, TypeMap &types) { std::lock_guard guard(GetModuleMutex()); - // Make sure we haven't already searched this SymbolFile before... - if (searched_symbol_files.count(this)) + // Make sure we haven't already searched this SymbolFile before. + if (!searched_symbol_files.insert(this).second) return; - searched_symbol_files.insert(this); - DWARFDebugInfo *info = DebugInfo(); if (!info) return; @@ -2453,8 +2451,13 @@ } } -void SymbolFileDWARF::FindTypes(llvm::ArrayRef pattern, - LanguageSet languages, TypeMap &types) { +void SymbolFileDWARF::FindTypes( + llvm::ArrayRef pattern, LanguageSet languages, + llvm::DenseSet &searched_symbol_files, TypeMap &types) { + // Make sure we haven't already searched this SymbolFile before. + if (!searched_symbol_files.insert(this).second) + return; + std::lock_guard guard(GetModuleMutex()); if (pattern.empty()) return; diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -131,6 +131,7 @@ TypeMap &types) override; void FindTypes(llvm::ArrayRef pattern, LanguageSet languages, + llvm::DenseSet &searched_symbol_files, TypeMap &types) override; llvm::Expected diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp --- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1259,8 +1259,9 @@ FindTypesByName(name.GetStringRef(), max_matches, types); } -void SymbolFileNativePDB::FindTypes(llvm::ArrayRef pattern, - LanguageSet languages, TypeMap &types) {} +void SymbolFileNativePDB::FindTypes( + llvm::ArrayRef pattern, LanguageSet languages, + llvm::DenseSet &searched_symbol_files, TypeMap &types) {} void SymbolFileNativePDB::FindTypesByName(llvm::StringRef name, uint32_t max_matches, diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -134,6 +134,7 @@ void FindTypes(llvm::ArrayRef pattern, lldb_private::LanguageSet languages, + llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) override; void FindTypesByRegex(const lldb_private::RegularExpression ®ex, diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp --- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1562,9 +1562,10 @@ } } -void SymbolFilePDB::FindTypes(llvm::ArrayRef pattern, - LanguageSet languages, - lldb_private::TypeMap &types) {} +void SymbolFilePDB::FindTypes( + llvm::ArrayRef pattern, LanguageSet languages, + llvm::DenseSet &searched_symbol_files, + lldb_private::TypeMap &types) {} void SymbolFilePDB::GetTypesForPDBSymbol(const llvm::pdb::PDBSymbol &pdb_symbol, uint32_t type_mask, diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp --- a/lldb/source/Symbol/SymbolFile.cpp +++ b/lldb/source/Symbol/SymbolFile.cpp @@ -134,7 +134,9 @@ TypeMap &types) {} void SymbolFile::FindTypes(llvm::ArrayRef pattern, - LanguageSet languages, TypeMap &types) {} + LanguageSet languages, + llvm::DenseSet &searched_symbol_files, + TypeMap &types) {} void SymbolFile::AssertModuleLock() { // The code below is too expensive to leave enabled in release builds. It's diff --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp --- a/lldb/tools/lldb-test/lldb-test.cpp +++ b/lldb/tools/lldb-test/lldb-test.cpp @@ -529,7 +529,7 @@ Symfile.FindTypes(ConstString(Name), ContextPtr, UINT32_MAX, SearchedFiles, Map); else - Module.FindTypes(parseCompilerContext(), languages, Map); + Module.FindTypes(parseCompilerContext(), languages, SearchedFiles, Map); outs() << formatv("Found {0} types:\n", Map.GetSize()); StreamString Stream;