Index: lldb/include/lldb/Core/Module.h =================================================================== --- lldb/include/lldb/Core/Module.h +++ lldb/include/lldb/Core/Module.h @@ -1181,8 +1181,8 @@ Module(); // Only used internally by CreateJITModule () size_t FindTypes_Impl( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, + const SymbolContext &sc, llvm::StringRef name, + const CompilerDeclContext *parent_decl_ctx, bool exact_match, bool append, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types); Index: lldb/include/lldb/Symbol/SymbolFile.h =================================================================== --- lldb/include/lldb/Symbol/SymbolFile.h +++ lldb/include/lldb/Symbol/SymbolFile.h @@ -177,9 +177,9 @@ bool include_inlines, bool append, SymbolContextList &sc_list); virtual uint32_t - FindTypes(const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, - uint32_t max_matches, + FindTypes(const SymbolContext &sc, llvm::StringRef name, + const CompilerDeclContext *parent_decl_ctx, bool exact_match, + bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types); virtual size_t FindTypes(const std::vector &context, Index: lldb/include/lldb/Symbol/SymbolVendor.h =================================================================== --- lldb/include/lldb/Symbol/SymbolVendor.h +++ lldb/include/lldb/Symbol/SymbolVendor.h @@ -99,9 +99,9 @@ SymbolContextList &sc_list); virtual size_t - FindTypes(const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, - size_t max_matches, + FindTypes(const SymbolContext &sc, llvm::StringRef name, + const CompilerDeclContext *parent_decl_ctx, bool exact_match, + bool append, size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types); Index: lldb/include/lldb/Symbol/Type.h =================================================================== --- lldb/include/lldb/Symbol/Type.h +++ lldb/include/lldb/Symbol/Type.h @@ -194,12 +194,13 @@ static int Compare(const Type &a, const Type &b); + static lldb::TypeClass ConsumeTypeClass(llvm::StringRef &name); + // From a fully qualified typename, split the type into the type basename and // the remaining type scope (namespaces/classes). - static bool GetTypeScopeAndBasename(const llvm::StringRef& name, + static bool GetTypeScopeAndBasename(const llvm::StringRef &name, llvm::StringRef &scope, - llvm::StringRef &basename, - lldb::TypeClass &type_class); + llvm::StringRef &basename); void SetEncodingType(Type *encoding_type) { m_encoding_type = encoding_type; } uint32_t GetEncodingMask(); Index: lldb/include/lldb/Symbol/TypeMap.h =================================================================== --- lldb/include/lldb/Symbol/TypeMap.h +++ lldb/include/lldb/Symbol/TypeMap.h @@ -55,6 +55,8 @@ bool Remove(const lldb::TypeSP &type_sp); + void OnlyKeepTypeClass(lldb::TypeClass type_class); + void RemoveMismatchedTypes(const char *qualified_typename, bool exact_match); void RemoveMismatchedTypes(const std::string &type_scope, Index: lldb/lit/SymbolFile/NativePDB/Inputs/tag-types.lldbinit =================================================================== --- lldb/lit/SymbolFile/NativePDB/Inputs/tag-types.lldbinit +++ lldb/lit/SymbolFile/NativePDB/Inputs/tag-types.lldbinit @@ -5,4 +5,17 @@ type lookup -- Derived2 type lookup -- EnumInt type lookup -- EnumShort +type lookup -- NS::Struct +type lookup -- NS::Struct::Local type lookup -- InvalidType + +type lookup -- struct Struct +type lookup -- class Class +type lookup -- union Union +type lookup -- enum EnumInt + +type lookup -- ::Struct +type lookup -- struct ::Struct + +type lookup -- class Struct +type lookup -- class ::Struct \ No newline at end of file Index: lldb/lit/SymbolFile/NativePDB/tag-types.cpp =================================================================== --- lldb/lit/SymbolFile/NativePDB/tag-types.cpp +++ lldb/lit/SymbolFile/NativePDB/tag-types.cpp @@ -128,6 +128,15 @@ ES_B = 3 }; +namespace NS { + struct Struct { + int X; + struct Local { + int Y; + }; + }; +} + int main(int argc, char **argv) { Struct S; Class C; @@ -136,6 +145,8 @@ Derived2 D2; EnumInt EI; EnumShort ES; + NS::Struct NSS; + NS::Struct::Local NSSL; return 0; } @@ -232,5 +243,37 @@ // CHECK-NEXT: ES_A, // CHECK-NEXT: ES_B // CHECK-NEXT: } +// CHECK-NEXT: (lldb) type lookup -- NS::Struct +// CHECK-NEXT: struct NS::Struct { +// CHECK-NEXT: int X; +// CHECK-NEXT: } +// CHECK-NEXT: (lldb) type lookup -- NS::Struct::Local +// CHECK-NEXT: struct NS::Struct::Local { +// CHECK-NEXT: int Y; +// CHECK-NEXT: } // CHECK-NEXT: (lldb) type lookup -- InvalidType // CHECK-NEXT: no type was found matching 'InvalidType' + +// CHECK-NEXT: (lldb) type lookup -- struct Struct +// CHECK-NEXT: struct Struct { + +// CHECK: (lldb) type lookup -- class Class +// CHECK-NEXT: class Class { + +// CHECK: (lldb) type lookup -- union Union +// CHECK-NEXT: union Union { + +// CHECK: (lldb) type lookup -- enum EnumInt +// CHECK-NEXT: enum EnumInt { + +// CHECK: (lldb) type lookup -- ::Struct +// CHECK-NEXT: struct Struct { + +// CHECK: (lldb) type lookup -- struct ::Struct +// CHECK-NEXT: struct Struct { + +// CHECK: (lldb) type lookup -- class Struct +// CHECK-NEXT: no type was found matching 'class Struct' + +// CHECK: (lldb) type lookup -- class ::Struct +// CHECK-NEXT: no type was found matching 'class ::Struct' Index: lldb/source/Core/Module.cpp =================================================================== --- lldb/source/Core/Module.cpp +++ lldb/source/Core/Module.cpp @@ -943,8 +943,9 @@ } size_t Module::FindTypes_Impl( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, + const SymbolContext &sc, llvm::StringRef name, + const CompilerDeclContext *parent_decl_ctx, bool exact_match, bool append, + size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { static Timer::Category func_cat(LLVM_PRETTY_FUNCTION); @@ -952,8 +953,8 @@ if (!sc.module_sp || sc.module_sp.get() == this) { SymbolVendor *symbols = GetSymbolVendor(); if (symbols) - return symbols->FindTypes(sc, name, parent_decl_ctx, append, max_matches, - searched_symbol_files, types); + return symbols->FindTypes(sc, name, parent_decl_ctx, exact_match, append, + max_matches, searched_symbol_files, types); } return 0; } @@ -966,8 +967,8 @@ TypeMap types_map; llvm::DenseSet searched_symbol_files; size_t num_types = - FindTypes_Impl(sc, type_name, parent_decl_ctx, append, max_matches, - searched_symbol_files, types_map); + FindTypes_Impl(sc, type_name.GetStringRef(), parent_decl_ctx, false, + append, max_matches, searched_symbol_files, types_map); if (num_types > 0) sc.SortTypeList(types_map, type_list); return num_types; @@ -989,53 +990,39 @@ size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeList &types) { - size_t num_matches = 0; - const char *type_name_cstr = name.GetCString(); - llvm::StringRef type_scope; - llvm::StringRef type_basename; - const bool append = true; - TypeClass type_class = eTypeClassAny; TypeMap typesmap; - 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 - // in order to get the qualified names to match - exact_match = type_scope.consume_front("::"); - - ConstString type_basename_const_str(type_basename); - if (FindTypes_Impl(sc, type_basename_const_str, nullptr, append, - max_matches, searched_symbol_files, typesmap)) { - typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class, - exact_match); - num_matches = typesmap.GetSize(); - } - } else { - // The type is not in a namespace/class scope, just search for it by - // basename - if (type_class != eTypeClassAny && !type_basename.empty()) { - // The "type_name_cstr" will have been modified if we have a valid type - // class prefix (like "struct", "class", "union", "typedef" etc). - FindTypes_Impl(sc, ConstString(type_basename), nullptr, append, - UINT_MAX, searched_symbol_files, typesmap); - typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class, - exact_match); - num_matches = typesmap.GetSize(); + // Debug info is optimized for doing O(1) lookups on types when we know we're + // looking for an exact match. But the only way for this to be possible is if + // we can pass this knowledge through to the SymbolFile plugin. + llvm::StringRef search_name = name.GetStringRef(); + TypeClass type_class = Type::ConsumeTypeClass(search_name); + + if (search_name.consume_front("::")) + exact_match = true; + + bool success = FindTypes_Impl(sc, search_name, nullptr, exact_match, true, + max_matches, searched_symbol_files, typesmap); + + size_t num_matches = 0; + if (success) { + if (exact_match) { + // If this is something like "type lookup -- class ::Struct" it should + // fail. So we need to make sure we always filter out types whose type + // class doesn't match. + typesmap.OnlyKeepTypeClass(type_class); } else { - num_matches = FindTypes_Impl(sc, name, nullptr, append, UINT_MAX, - searched_symbol_files, typesmap); - if (exact_match) { - std::string name_str(name.AsCString("")); - typesmap.RemoveMismatchedTypes(type_scope, name_str, type_class, - exact_match); - num_matches = typesmap.GetSize(); - } + llvm::StringRef type_scope; + llvm::StringRef type_basename; + Type::GetTypeScopeAndBasename(search_name, type_scope, type_basename); + + typesmap.RemoveMismatchedTypes(type_scope, type_basename, type_class, + false); } } - if (num_matches > 0) - sc.SortTypeList(typesmap, types); + + num_matches = typesmap.GetSize(); + sc.SortTypeList(typesmap, types); return num_matches; } Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -203,10 +203,9 @@ std::vector &mangled_names) override; uint32_t - FindTypes(const lldb_private::SymbolContext &sc, - const lldb_private::ConstString &name, + FindTypes(const lldb_private::SymbolContext &sc, llvm::StringRef name, const lldb_private::CompilerDeclContext *parent_decl_ctx, - bool append, uint32_t max_matches, + bool exact_match, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) override; Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2434,11 +2434,20 @@ } uint32_t SymbolFileDWARF::FindTypes( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, + const SymbolContext &sc, llvm::StringRef name, + const CompilerDeclContext *parent_decl_ctx, bool exact_match, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { + + // FIXME: When exact_match is true, we should do an optimized O(1) lookup. + llvm::StringRef scope; + llvm::StringRef base; + bool has_namespace_separator = + Type::GetTypeScopeAndBasename(name, scope, base); + if (has_namespace_separator) + name = base; + // If we aren't appending the results to this list, then clear the list if (!append) types.Clear(); @@ -2458,22 +2467,24 @@ if (log) { if (parent_decl_ctx) GetObjectFile()->GetModule()->LogMessage( - log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = " - "%p (\"%s\"), append=%u, max_matches=%u, type_list)", - name.GetCString(), static_cast(parent_decl_ctx), + log, + "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = " + "%p (\"%s\"), append=%u, max_matches=%u, type_list)", + name.str().c_str(), static_cast(parent_decl_ctx), parent_decl_ctx->GetName().AsCString(""), append, max_matches); else GetObjectFile()->GetModule()->LogMessage( - log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = " - "NULL, append=%u, max_matches=%u, type_list)", - name.GetCString(), append, max_matches); + log, + "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx = " + "NULL, append=%u, max_matches=%u, type_list)", + name.str().c_str(), append, max_matches); } if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return 0; DIEArray die_offsets; - m_index->GetTypes(name, die_offsets); + m_index->GetTypes(ConstString(name), die_offsets); const size_t num_die_matches = die_offsets.size(); if (num_die_matches) { @@ -2495,24 +2506,25 @@ break; } } else { - m_index->ReportInvalidDIEOffset(die_ref.die_offset, - name.GetStringRef()); + m_index->ReportInvalidDIEOffset(die_ref.die_offset, name); } } const uint32_t num_matches = types.GetSize() - initial_types_size; if (log && num_matches) { if (parent_decl_ctx) { GetObjectFile()->GetModule()->LogMessage( - log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx " - "= %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u", - name.GetCString(), static_cast(parent_decl_ctx), + log, + "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx " + "= %p (\"%s\"), append=%u, max_matches=%u, type_list) => %u", + name.str().c_str(), static_cast(parent_decl_ctx), parent_decl_ctx->GetName().AsCString(""), append, max_matches, num_matches); } else { GetObjectFile()->GetModule()->LogMessage( - log, "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx " - "= NULL, append=%u, max_matches=%u, type_list) => %u", - name.GetCString(), append, max_matches, num_matches); + log, + "SymbolFileDWARF::FindTypes (sc, name=\"%s\", parent_decl_ctx " + "= NULL, append=%u, max_matches=%u, type_list) => %u", + name.str().c_str(), append, max_matches, num_matches); } } return num_matches; @@ -2524,9 +2536,9 @@ if (external_module_sp) { SymbolVendor *sym_vendor = external_module_sp->GetSymbolVendor(); if (sym_vendor) { - const uint32_t num_external_matches = - sym_vendor->FindTypes(sc, name, parent_decl_ctx, append, - max_matches, searched_symbol_files, types); + const uint32_t num_external_matches = sym_vendor->FindTypes( + sc, name, parent_decl_ctx, exact_match, append, max_matches, + searched_symbol_files, types); if (num_external_matches) return num_external_matches; } Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -110,10 +110,9 @@ bool include_inlines, bool append, lldb_private::SymbolContextList &sc_list) override; uint32_t - FindTypes(const lldb_private::SymbolContext &sc, - const lldb_private::ConstString &name, + FindTypes(const lldb_private::SymbolContext &sc, llvm::StringRef name, const lldb_private::CompilerDeclContext *parent_decl_ctx, - bool append, uint32_t max_matches, + bool exact_match, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) override; lldb_private::CompilerDeclContext FindNamespace( Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -1162,8 +1162,8 @@ } uint32_t SymbolFileDWARFDebugMap::FindTypes( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, + const SymbolContext &sc, llvm::StringRef name, + const CompilerDeclContext *parent_decl_ctx, bool exact_match, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { @@ -1176,12 +1176,13 @@ if (sc.comp_unit) { oso_dwarf = GetSymbolFile(sc); if (oso_dwarf) - return oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, - max_matches, searched_symbol_files, types); + return oso_dwarf->FindTypes(sc, name, parent_decl_ctx, exact_match, + append, max_matches, searched_symbol_files, + types); } else { ForEachSymbolFile([&](SymbolFileDWARF *oso_dwarf) -> bool { - oso_dwarf->FindTypes(sc, name, parent_decl_ctx, append, max_matches, - searched_symbol_files, types); + oso_dwarf->FindTypes(sc, name, parent_decl_ctx, exact_match, append, + max_matches, searched_symbol_files, types); if (types.GetSize() >= max_matches) return true; else Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h =================================================================== --- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -125,9 +125,9 @@ uint32_t FindFunctions(const RegularExpression ®ex, bool include_inlines, bool append, SymbolContextList &sc_list) override; - uint32_t FindTypes(const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, - uint32_t max_matches, + uint32_t FindTypes(const SymbolContext &sc, llvm::StringRef name, + const CompilerDeclContext *parent_decl_ctx, + bool exact_match, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) override; Index: lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -691,8 +691,7 @@ return nullptr; // Ignore unnamed-tag UDTs. - name = DropNameScope(name); - if (name.empty()) + if (DropNameScope(name).empty()) return nullptr; clang::DeclContext *decl_context = m_clang->GetTranslationUnitDecl(); @@ -1189,20 +1188,20 @@ } uint32_t SymbolFileNativePDB::FindTypes( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, + const SymbolContext &sc, llvm::StringRef name, + const CompilerDeclContext *parent_decl_ctx, bool exact_match, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { if (!append) types.Clear(); - if (!name) + if (name.empty()) return 0; searched_symbol_files.clear(); searched_symbol_files.insert(this); // There is an assumption 'name' is not a regex - size_t match_count = FindTypesByName(name.GetStringRef(), max_matches, types); + size_t match_count = FindTypesByName(name, max_matches, types); return match_count; } Index: lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h =================================================================== --- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -134,10 +134,9 @@ std::vector &mangled_names) override; uint32_t - FindTypes(const lldb_private::SymbolContext &sc, - const lldb_private::ConstString &name, + FindTypes(const lldb_private::SymbolContext &sc, llvm::StringRef name, const lldb_private::CompilerDeclContext *parent_decl_ctx, - bool append, uint32_t max_matches, + bool exact_match, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) override; @@ -187,7 +186,7 @@ const llvm::pdb::PDBSymbolCompiland &pdb_compiland, llvm::DenseMap &index_map) const; - void FindTypesByName(const std::string &name, + void FindTypesByName(llvm::StringRef name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, lldb_private::TypeMap &types); Index: lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp =================================================================== --- lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1332,15 +1332,14 @@ std::vector &mangled_names) {} uint32_t SymbolFilePDB::FindTypes( - const lldb_private::SymbolContext &sc, - const lldb_private::ConstString &name, - const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, - uint32_t max_matches, + const lldb_private::SymbolContext &sc, llvm::StringRef name, + const lldb_private::CompilerDeclContext *parent_decl_ctx, bool exact_match, + bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, lldb_private::TypeMap &types) { if (!append) types.Clear(); - if (!name) + if (name.empty()) return 0; if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx)) return 0; @@ -1348,10 +1347,8 @@ searched_symbol_files.clear(); searched_symbol_files.insert(this); - std::string name_str = name.AsCString(); - // There is an assumption 'name' is not a regex - FindTypesByName(name_str, parent_decl_ctx, max_matches, types); + FindTypesByName(name, parent_decl_ctx, max_matches, types); return types.GetSize(); } @@ -1412,7 +1409,7 @@ } void SymbolFilePDB::FindTypesByName( - const std::string &name, + llvm::StringRef name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t max_matches, lldb_private::TypeMap &types) { if (!parent_decl_ctx) Index: lldb/source/Symbol/SymbolFile.cpp =================================================================== --- lldb/source/Symbol/SymbolFile.cpp +++ lldb/source/Symbol/SymbolFile.cpp @@ -140,8 +140,8 @@ } uint32_t SymbolFile::FindTypes( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, + const SymbolContext &sc, llvm::StringRef name, + const CompilerDeclContext *parent_decl_ctx, bool exact_match, bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { Index: lldb/source/Symbol/SymbolVendor.cpp =================================================================== --- lldb/source/Symbol/SymbolVendor.cpp +++ lldb/source/Symbol/SymbolVendor.cpp @@ -315,17 +315,18 @@ } size_t SymbolVendor::FindTypes( - const SymbolContext &sc, const ConstString &name, - const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, + const SymbolContext &sc, llvm::StringRef name, + const CompilerDeclContext *parent_decl_ctx, bool exact_match, bool append, + size_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types) { ModuleSP module_sp(GetModule()); if (module_sp) { std::lock_guard guard(module_sp->GetMutex()); if (m_sym_file_ap.get()) - return m_sym_file_ap->FindTypes(sc, name, parent_decl_ctx, append, - max_matches, searched_symbol_files, - types); + return m_sym_file_ap->FindTypes(sc, name, parent_decl_ctx, exact_match, + append, max_matches, + searched_symbol_files, types); } if (!append) types.Clear(); Index: lldb/source/Symbol/Type.cpp =================================================================== --- lldb/source/Symbol/Type.cpp +++ lldb/source/Symbol/Type.cpp @@ -618,27 +618,27 @@ return GetForwardCompilerType().GetConstTypeName(); } -bool Type::GetTypeScopeAndBasename(const llvm::StringRef& name, +TypeClass Type::ConsumeTypeClass(llvm::StringRef &name) { + if (name.consume_front("struct ")) + return eTypeClassStruct; + else if (name.consume_front("class ")) + return eTypeClassClass; + else if (name.consume_front("union ")) + return eTypeClassUnion; + else if (name.consume_front("enum ")) + return eTypeClassEnumeration; + else if (name.consume_front("typedef ")) + return eTypeClassTypedef; + return eTypeClassAny; +} + +bool Type::GetTypeScopeAndBasename(const llvm::StringRef &name, llvm::StringRef &scope, - llvm::StringRef &basename, - TypeClass &type_class) { - type_class = eTypeClassAny; - + llvm::StringRef &basename) { if (name.empty()) return false; basename = name; - if (basename.consume_front("struct ")) - type_class = eTypeClassStruct; - else if (basename.consume_front("class ")) - type_class = eTypeClassClass; - else if (basename.consume_front("union ")) - type_class = eTypeClassUnion; - else if (basename.consume_front("enum ")) - type_class = eTypeClassEnumeration; - else if (basename.consume_front("typedef ")) - type_class = eTypeClassTypedef; - size_t namespace_separator = basename.find("::"); if (namespace_separator == llvm::StringRef::npos) return false; Index: lldb/source/Symbol/TypeList.cpp =================================================================== --- lldb/source/Symbol/TypeList.cpp +++ lldb/source/Symbol/TypeList.cpp @@ -112,9 +112,10 @@ bool exact_match) { llvm::StringRef type_scope; llvm::StringRef type_basename; - TypeClass type_class = eTypeClassAny; + llvm::StringRef name(qualified_typename); + TypeClass type_class = Type::ConsumeTypeClass(name); if (!Type::GetTypeScopeAndBasename(qualified_typename, type_scope, - type_basename, type_class)) { + type_basename)) { type_basename = qualified_typename; type_scope = ""; } @@ -146,12 +147,12 @@ ConstString match_type_name_const_str(the_type->GetQualifiedName()); if (match_type_name_const_str) { - const char *match_type_name = match_type_name_const_str.GetCString(); + llvm::StringRef match_type_name = + match_type_name_const_str.GetStringRef(); llvm::StringRef match_type_scope; llvm::StringRef match_type_basename; if (Type::GetTypeScopeAndBasename(match_type_name, match_type_scope, - match_type_basename, - match_type_class)) { + match_type_basename)) { if (match_type_basename == type_basename) { const size_t type_scope_size = type_scope.size(); const size_t match_type_scope_size = match_type_scope.size(); Index: lldb/source/Symbol/TypeMap.cpp =================================================================== --- lldb/source/Symbol/TypeMap.cpp +++ lldb/source/Symbol/TypeMap.cpp @@ -153,11 +153,12 @@ void TypeMap::RemoveMismatchedTypes(const char *qualified_typename, bool exact_match) { + llvm::StringRef name(qualified_typename); llvm::StringRef type_scope; llvm::StringRef type_basename; - TypeClass type_class = eTypeClassAny; + TypeClass type_class = Type::ConsumeTypeClass(name); if (!Type::GetTypeScopeAndBasename(qualified_typename, type_scope, - type_basename, type_class)) { + type_basename)) { type_basename = qualified_typename; type_scope = ""; } @@ -165,6 +166,22 @@ exact_match); } +void TypeMap::OnlyKeepTypeClass(lldb::TypeClass type_class) { + if (type_class == eTypeClassAny) + return; + + collection matching_types; + + iterator pos, end = m_types.end(); + + for (const auto &t : m_types) { + TypeClass tc = t.second->GetForwardCompilerType().GetTypeClass(); + if (tc & type_class) + matching_types.insert(t); + } + m_types.swap(matching_types); +} + void TypeMap::RemoveMismatchedTypes(const std::string &type_scope, const std::string &type_basename, TypeClass type_class, bool exact_match) { @@ -193,8 +210,7 @@ llvm::StringRef match_type_scope; llvm::StringRef match_type_basename; if (Type::GetTypeScopeAndBasename(match_type_name, match_type_scope, - match_type_basename, - match_type_class)) { + match_type_basename)) { if (match_type_basename == type_basename) { const size_t type_scope_size = type_scope.size(); const size_t match_type_scope_size = match_type_scope.size(); Index: lldb/tools/lldb-test/lldb-test.cpp =================================================================== --- lldb/tools/lldb-test/lldb-test.cpp +++ lldb/tools/lldb-test/lldb-test.cpp @@ -456,8 +456,8 @@ SymbolContext SC; DenseSet SearchedFiles; TypeMap Map; - Vendor.FindTypes(SC, ConstString(Name), ContextPtr, true, UINT32_MAX, - SearchedFiles, Map); + Vendor.FindTypes(SC, Name, ContextPtr, false, true, UINT32_MAX, SearchedFiles, + Map); outs() << formatv("Found {0} types:\n", Map.GetSize()); StreamString Stream; Index: lldb/unittests/Symbol/TestType.cpp =================================================================== --- lldb/unittests/Symbol/TestType.cpp +++ lldb/unittests/Symbol/TestType.cpp @@ -21,9 +21,7 @@ const char *expected_scope, const char *expected_name) { llvm::StringRef scope, name; - lldb::TypeClass type_class; - bool is_scoped = - Type::GetTypeScopeAndBasename(full_type, scope, name, type_class); + bool is_scoped = Type::GetTypeScopeAndBasename(full_type, scope, name); EXPECT_EQ(is_scoped, expected_is_scoped); if (expected_is_scoped) { EXPECT_EQ(scope, expected_scope);