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 @@ -1076,6 +1076,12 @@ llvm::DenseSet &searched_symbol_files, TypeMap &types); + void FindTypes_Impl( + ConstString name, ConstString scope, + const CompilerDeclContext &parent_decl_ctx, size_t max_matches, + llvm::DenseSet &searched_symbol_files, + TypeMap &types); + Module(const Module &) = delete; const Module &operator=(const Module &) = delete; }; 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 @@ -235,6 +235,15 @@ llvm::DenseSet &searched_symbol_files, TypeMap &types); + // Find types in a specific scope. + // \param scope + // Must be either the scope prefix (without leading ::) or empty + virtual void + FindTypes(ConstString name, ConstString scope, + const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, + llvm::DenseSet &searched_symbol_files, + TypeMap &types); + /// Find types specified by a CompilerContextPattern. /// \param languages /// Only return results in these languages. 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 @@ -944,6 +944,17 @@ searched_symbol_files, types); } +void Module::FindTypes_Impl( + ConstString name, ConstString scope, + const CompilerDeclContext &parent_decl_ctx, size_t max_matches, + llvm::DenseSet &searched_symbol_files, + TypeMap &types) { + LLDB_SCOPED_TIMER(); + if (SymbolFile *symbols = GetSymbolFile()) + symbols->FindTypes(name, scope, parent_decl_ctx, max_matches, + searched_symbol_files, types); +} + void Module::FindTypesInNamespace(ConstString type_name, const CompilerDeclContext &parent_decl_ctx, size_t max_matches, TypeList &type_list) { @@ -980,6 +991,7 @@ if (Type::GetTypeScopeAndBasename(type_name_cstr, type_scope, type_basename, type_class)) { + // Check if "name" starts with "::" which means the qualified type starts // from the root namespace and implies and exact match. The typenames we // get back from clang do not start with "::" so we need to strip this off @@ -987,8 +999,11 @@ exact_match = type_scope.consume_front("::"); ConstString type_basename_const_str(type_basename); - FindTypes_Impl(type_basename_const_str, CompilerDeclContext(), max_matches, - searched_symbol_files, typesmap); + ConstString type_scope_const_str(type_scope); + FindTypes_Impl(type_basename_const_str, type_scope_const_str, + CompilerDeclContext(), max_matches, searched_symbol_files, + typesmap); + if (typesmap.GetSize()) typesmap.RemoveMismatchedTypes(std::string(type_scope), std::string(type_basename), type_class, 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 @@ -191,6 +191,13 @@ const std::string &scope_qualified_name, std::vector &mangled_names) override; + void + FindTypes(lldb_private::ConstString name, lldb_private::ConstString scope, + const lldb_private::CompilerDeclContext &parent_decl_ctx, + uint32_t max_matches, + llvm::DenseSet &searched_symbol_files, + lldb_private::TypeMap &types) override; + void FindTypes(lldb_private::ConstString name, const lldb_private::CompilerDeclContext &parent_decl_ctx, 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 @@ -9,6 +9,7 @@ #include "SymbolFileDWARF.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Threading.h" @@ -21,6 +22,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Core/Value.h" #include "lldb/Utility/ArchSpec.h" +#include "lldb/Utility/ConstString.h" #include "lldb/Utility/RegularExpression.h" #include "lldb/Utility/Scalar.h" #include "lldb/Utility/StreamString.h" @@ -2419,6 +2421,15 @@ uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { + FindTypes(name, ConstString(), parent_decl_ctx, max_matches, + searched_symbol_files, types); +} + +void SymbolFileDWARF::FindTypes( + ConstString name, ConstString scope, + const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, + 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.insert(this).second) @@ -2445,10 +2456,21 @@ if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return; + // prepare string to check against in case this is a fully qualified search + bool has_scope = !scope.IsEmpty(); + llvm::StringRef sc(scope.GetStringRef()); + std::string storage; + m_index->GetTypes(name, [&](DWARFDIE die) { if (!DIEInDeclContext(parent_decl_ctx, die)) return true; // The containing decl contexts don't match + if (has_scope) { + const char *qn = die.GetQualifiedName(storage); + if (qn && !llvm::StringRef(qn).startswith(sc)) + return true; + } + Type *matching_type = ResolveType(die, true, true); if (!matching_type) return true; 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 @@ -135,6 +135,19 @@ llvm::DenseSet &searched_symbol_files, TypeMap &types) {} +void SymbolFile::FindTypes( + ConstString basename, ConstString scope, + const CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, + llvm::DenseSet &searched_symbol_files, + TypeMap &types) { + FindTypes(basename, parent_decl_ctx, max_matches, searched_symbol_files, + types); + TypeClass type_class = eTypeClassAny; + types.RemoveMismatchedTypes(std::string(basename.GetCString()), + std::string(scope.GetCString()), type_class, + true); +} + void SymbolFile::FindTypes(llvm::ArrayRef pattern, LanguageSet languages, llvm::DenseSet &searched_symbol_files,