From 7bc31332b8350e297e08477e39f7ca28f5f6de80 Mon Sep 17 00:00:00 2001 From: Greg Clayton Date: Mon, 22 Oct 2012 16:19:56 +0000 Subject: [PATCH] Allow type searches to specify a type keyword when searching for type. Currently supported type keywords are: struct, class, union, enum, and typedef. So now you can search for types with a string like "struct foo". llvm-svn: 166420 --- lldb/include/lldb/Symbol/Type.h | 5 ++-- lldb/include/lldb/Symbol/TypeList.h | 5 ++++ lldb/source/Core/Module.cpp | 18 ++++++++++-- lldb/source/Symbol/Type.cpp | 35 +++++++++++++++++++++-- lldb/source/Symbol/TypeList.cpp | 43 +++++++++++++++++++++++++++-- 5 files changed, 96 insertions(+), 10 deletions(-) diff --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h index 85940c61f7f4..82cf079daf98 100644 --- a/lldb/include/lldb/Symbol/Type.h +++ b/lldb/include/lldb/Symbol/Type.h @@ -255,9 +255,10 @@ public: // From a fully qualified typename, split the type into the type basename // and the remaining type scope (namespaces/classes). static bool - GetTypeScopeAndBasename (const char* name_cstr, + GetTypeScopeAndBasename (const char* &name_cstr, std::string &scope, - std::string &basename); + std::string &basename, + lldb::TypeClass &type_class); void SetEncodingType (Type *encoding_type) { diff --git a/lldb/include/lldb/Symbol/TypeList.h b/lldb/include/lldb/Symbol/TypeList.h index 9be29e1b57ab..cd32b11ce332 100644 --- a/lldb/include/lldb/Symbol/TypeList.h +++ b/lldb/include/lldb/Symbol/TypeList.h @@ -61,7 +61,12 @@ public: void RemoveMismatchedTypes (const std::string &type_scope, const std::string &type_basename, + lldb::TypeClass type_class, bool exact_match); + + void + RemoveMismatchedTypes (lldb::TypeClass type_class); + private: typedef std::multimap collection; typedef collection::iterator iterator; diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp index 14d2e42ac50e..08f826ee42bf 100644 --- a/lldb/source/Core/Module.cpp +++ b/lldb/source/Core/Module.cpp @@ -696,7 +696,8 @@ Module::FindTypes (const SymbolContext& sc, std::string type_scope; std::string type_basename; const bool append = true; - if (Type::GetTypeScopeAndBasename (type_name_cstr, type_scope, type_basename)) + TypeClass type_class = eTypeClassAny; + 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 @@ -711,14 +712,25 @@ Module::FindTypes (const SymbolContext& sc, ConstString type_basename_const_str (type_basename.c_str()); if (FindTypes_Impl(sc, type_basename_const_str, NULL, append, max_matches, types)) { - types.RemoveMismatchedTypes (type_scope, type_basename, exact_match); + types.RemoveMismatchedTypes (type_scope, type_basename, type_class, exact_match); num_matches = types.GetSize(); } } else { // The type is not in a namespace/class scope, just search for it by basename - num_matches = FindTypes_Impl(sc, name, NULL, append, max_matches, types); + if (type_class != eTypeClassAny) + { + // The "type_name_cstr" will have been modified if we have a valid type class + // prefix (like "struct", "class", "union", "typedef" etc). + num_matches = FindTypes_Impl(sc, ConstString(type_name_cstr), NULL, append, max_matches, types); + types.RemoveMismatchedTypes (type_class); + num_matches = types.GetSize(); + } + else + { + num_matches = FindTypes_Impl(sc, name, NULL, append, max_matches, types); + } } return num_matches; diff --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp index 335cbce3ce63..bcdfeafdc93e 100644 --- a/lldb/source/Symbol/Type.cpp +++ b/lldb/source/Symbol/Type.cpp @@ -28,6 +28,8 @@ #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" +#include "llvm/ADT/StringRef.h" + using namespace lldb; using namespace lldb_private; @@ -728,14 +730,43 @@ Type::GetQualifiedName () bool -Type::GetTypeScopeAndBasename (const char* name_cstr, +Type::GetTypeScopeAndBasename (const char* &name_cstr, std::string &scope, - std::string &basename) + std::string &basename, + TypeClass &type_class) { // Protect against null c string. + type_class = eTypeClassAny; + if (name_cstr && name_cstr[0]) { + llvm::StringRef name_strref(name_cstr); + if (name_strref.startswith("struct ")) + { + name_cstr += 7; + type_class = eTypeClassStruct; + } + else if (name_strref.startswith("class ")) + { + name_cstr += 6; + type_class = eTypeClassClass; + } + else if (name_strref.startswith("union ")) + { + name_cstr += 6; + type_class = eTypeClassUnion; + } + else if (name_strref.startswith("enum ")) + { + name_cstr += 5; + type_class = eTypeClassEnumeration; + } + else if (name_strref.startswith("typedef ")) + { + name_cstr += 8; + type_class = eTypeClassTypedef; + } const char *basename_cstr = name_cstr; const char* namespace_separator = ::strstr (basename_cstr, "::"); if (namespace_separator) diff --git a/lldb/source/Symbol/TypeList.cpp b/lldb/source/Symbol/TypeList.cpp index f90334ea9ec4..7c1d969b84ed 100644 --- a/lldb/source/Symbol/TypeList.cpp +++ b/lldb/source/Symbol/TypeList.cpp @@ -207,17 +207,19 @@ TypeList::RemoveMismatchedTypes (const char *qualified_typename, { std::string type_scope; std::string type_basename; - if (!Type::GetTypeScopeAndBasename (qualified_typename, type_scope, type_basename)) + TypeClass type_class = eTypeClassAny; + if (!Type::GetTypeScopeAndBasename (qualified_typename, type_scope, type_basename, type_class)) { type_basename = qualified_typename; type_scope.clear(); } - return RemoveMismatchedTypes (type_scope, type_basename, exact_match); + return RemoveMismatchedTypes (type_scope, type_basename, type_class, exact_match); } void TypeList::RemoveMismatchedTypes (const std::string &type_scope, const std::string &type_basename, + TypeClass type_class, bool exact_match) { // Our "collection" type currently is a std::map which doesn't @@ -232,6 +234,15 @@ TypeList::RemoveMismatchedTypes (const std::string &type_scope, { Type* the_type = pos->second.get(); bool keep_match = false; + TypeClass match_type_class = eTypeClassAny; + + if (type_class != eTypeClassAny) + { + match_type_class = ClangASTType::GetTypeClass (the_type->GetClangAST(), + the_type->GetClangForwardType()); + if ((match_type_class & type_class) == 0) + continue; + } ConstString match_type_name_const_str (the_type->GetQualifiedName()); if (match_type_name_const_str) @@ -241,7 +252,8 @@ TypeList::RemoveMismatchedTypes (const std::string &type_scope, std::string match_type_basename; if (Type::GetTypeScopeAndBasename (match_type_name, match_type_scope, - match_type_basename)) + match_type_basename, + match_type_class)) { if (match_type_basename == type_basename) { @@ -299,6 +311,31 @@ TypeList::RemoveMismatchedTypes (const std::string &type_scope, m_types.swap(matching_types); } +void +TypeList::RemoveMismatchedTypes (TypeClass type_class) +{ + if (type_class == eTypeClassAny) + return; + + // Our "collection" type currently is a std::map which doesn't + // have any good way to iterate and remove items from the map + // so we currently just make a new list and add all of the matching + // types to it, and then swap it into m_types at the end + collection matching_types; + + iterator pos, end = m_types.end(); + + for (pos = m_types.begin(); pos != end; ++pos) + { + Type* the_type = pos->second.get(); + TypeClass match_type_class = ClangASTType::GetTypeClass (the_type->GetClangAST(), + the_type->GetClangForwardType()); + if (match_type_class & type_class) + matching_types.insert (*pos); + } + m_types.swap(matching_types); +} + //void * //TypeList::CreateClangPointerType (Type *type) //{