zturner updated this revision to Diff 171134.
zturner added a comment.

Fixed issues pointed out by @jingham and added some test coverage for this.


https://reviews.llvm.org/D53662

Files:
  lldb/include/lldb/Core/Module.h
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/include/lldb/Symbol/SymbolVendor.h
  lldb/include/lldb/Symbol/Type.h
  lldb/include/lldb/Symbol/TypeMap.h
  lldb/lit/SymbolFile/NativePDB/Inputs/tag-types.lldbinit
  lldb/lit/SymbolFile/NativePDB/tag-types.cpp
  lldb/source/Core/Module.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
  lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
  lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
  lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
  lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
  lldb/source/Symbol/SymbolFile.cpp
  lldb/source/Symbol/SymbolVendor.cpp
  lldb/source/Symbol/Type.cpp
  lldb/source/Symbol/TypeList.cpp
  lldb/source/Symbol/TypeMap.cpp
  lldb/tools/lldb-test/lldb-test.cpp
  lldb/unittests/Symbol/TestType.cpp

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);
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<SymbolFile *> 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/source/Symbol/TypeMap.cpp
===================================================================
--- lldb/source/Symbol/TypeMap.cpp
+++ lldb/source/Symbol/TypeMap.cpp
@@ -153,18 +153,35 @@
 
 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 = "";
   }
   return RemoveMismatchedTypes(type_scope, type_basename, type_class,
                                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/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/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/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<lldb_private::SymbolFile *> &searched_symbol_files,
     TypeMap &types) {
   ModuleSP module_sp(GetModule());
   if (module_sp) {
     std::lock_guard<std::recursive_mutex> 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/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<lldb_private::SymbolFile *> &searched_symbol_files,
     TypeMap &types) {
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<lldb_private::ConstString> &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<lldb_private::SymbolFile *> &searched_symbol_files,
             lldb_private::TypeMap &types) override;
 
@@ -187,7 +186,7 @@
       const llvm::pdb::PDBSymbolCompiland &pdb_compiland,
       llvm::DenseMap<uint32_t, uint32_t> &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,26 +1332,23 @@
     std::vector<lldb_private::ConstString> &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<lldb_private::SymbolFile *> &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;
 
   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/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 &regex, 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<SymbolFile *> &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<SymbolFile *> &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/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<lldb_private::SymbolFile *> &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<lldb_private::SymbolFile *> &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/DWARF/SymbolFileDWARF.h
===================================================================
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -203,10 +203,9 @@
       std::vector<lldb_private::ConstString> &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<lldb_private::SymbolFile *> &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<lldb_private::SymbolFile *> &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<const void *>(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<const void *>(parent_decl_ctx),
           parent_decl_ctx->GetName().AsCString("<NULL>"), 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<const void *>(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<const void *>(parent_decl_ctx),
             parent_decl_ctx->GetName().AsCString("<NULL>"), 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/Core/Module.cpp
===================================================================
--- lldb/source/Core/Module.cpp
+++ lldb/source/Core/Module.cpp
@@ -943,17 +943,18 @@
 }
 
 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<lldb_private::SymbolFile *> &searched_symbol_files,
     TypeMap &types) {
   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
   Timer scoped_timer(func_cat, LLVM_PRETTY_FUNCTION);
   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<lldb_private::SymbolFile *> 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<lldb_private::SymbolFile *> &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/lit/SymbolFile/NativePDB/tag-types.cpp
===================================================================
--- lldb/lit/SymbolFile/NativePDB/tag-types.cpp
+++ lldb/lit/SymbolFile/NativePDB/tag-types.cpp
@@ -128,14 +128,25 @@
   ES_B = 3
 };
 
+namespace NS {
+  struct Struct {
+    int X;
+    struct Local {
+      int Y;
+    };
+  };
+}
+
 int main(int argc, char **argv) {
   Struct S;
   Class C;
   Union U;
   Derived D;
   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/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/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/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/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<lldb_private::SymbolFile *> &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<lldb_private::SymbolFile *> &searched_symbol_files,
             TypeMap &types);
   virtual size_t FindTypes(const std::vector<CompilerContext> &context,
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<lldb_private::SymbolFile *> &searched_symbol_files,
       TypeMap &types);
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to