Index: include/lldb/Core/Module.h =================================================================== --- include/lldb/Core/Module.h +++ include/lldb/Core/Module.h @@ -1193,7 +1193,7 @@ const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, - TypeList& types); + TypeMap& types); DISALLOW_COPY_AND_ASSIGN (Module); Index: include/lldb/Symbol/SymbolContext.h =================================================================== --- include/lldb/Symbol/SymbolContext.h +++ include/lldb/Symbol/SymbolContext.h @@ -299,6 +299,13 @@ ConstString &language_object_name); //------------------------------------------------------------------ + /// Sorts the types in TypeMap according to SymbolContext + /// to TypeList + /// + //------------------------------------------------------------------ + void + SortTypeList(TypeMap &type_map, TypeList &type_list) const; + //------------------------------------------------------------------ /// Find a name of the innermost function for the symbol context. /// /// For instance, if the symbol context contains an inlined block, Index: include/lldb/Symbol/SymbolFile.h =================================================================== --- include/lldb/Symbol/SymbolFile.h +++ include/lldb/Symbol/SymbolFile.h @@ -141,7 +141,7 @@ virtual uint32_t FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables); virtual uint32_t FindFunctions (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list); virtual uint32_t FindFunctions (const RegularExpression& regex, 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, TypeList& types); + virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeMap& types); // virtual uint32_t FindTypes (const SymbolContext& sc, const RegularExpression& regex, bool append, uint32_t max_matches, TypeList& types) = 0; virtual TypeList * GetTypeList (); virtual size_t GetTypes (lldb_private::SymbolContextScope *sc_scope, Index: include/lldb/Symbol/SymbolVendor.h =================================================================== --- include/lldb/Symbol/SymbolVendor.h +++ include/lldb/Symbol/SymbolVendor.h @@ -16,6 +16,7 @@ #include "lldb/Core/ModuleChild.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/TypeList.h" +#include "lldb/Symbol/TypeMap.h" namespace lldb_private { @@ -125,7 +126,7 @@ const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, - TypeList& types); + TypeMap& types); virtual CompilerDeclContext FindNamespace (const SymbolContext& sc, Index: include/lldb/Symbol/TypeList.h =================================================================== --- include/lldb/Symbol/TypeList.h +++ include/lldb/Symbol/TypeList.h @@ -13,7 +13,7 @@ #include "lldb/lldb-private.h" #include "lldb/Symbol/Type.h" #include "lldb/Utility/Iterable.h" -#include +#include #include namespace lldb_private { @@ -24,7 +24,7 @@ //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - TypeList(); + TypeList(); virtual ~TypeList(); @@ -44,17 +44,14 @@ void Insert (const lldb::TypeSP& type); - bool - InsertUnique (const lldb::TypeSP& type); - uint32_t GetSize() const; lldb::TypeSP GetTypeAtIndex(uint32_t idx); - typedef std::multimap collection; - typedef AdaptedIterable TypeIterable; + typedef std::vector collection; + typedef AdaptedIterable TypeIterable; TypeIterable Types () @@ -68,8 +65,6 @@ void ForEach (std::function const &callback); - bool - RemoveTypeWithUID (lldb::user_id_t uid); void RemoveMismatchedTypes (const char *qualified_typename, Index: include/lldb/Symbol/TypeMap.h =================================================================== --- /dev/null +++ include/lldb/Symbol/TypeMap.h @@ -0,0 +1,101 @@ +//===-- TypeMap.h ----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_TypeMap_h_ +#define liblldb_TypeMap_h_ + +#include "lldb/lldb-private.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Utility/Iterable.h" +#include +#include + +namespace lldb_private { + +class TypeMap +{ +public: + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + TypeMap(); + + virtual + ~TypeMap(); + + void + Clear(); + + void + Dump(Stream *s, bool show_context); + +// lldb::TypeSP +// FindType(lldb::user_id_t uid); + + TypeMap + FindTypes(const ConstString &name); + + void + Insert (const lldb::TypeSP& type); + + bool + Empty() const; + + bool + InsertUnique (const lldb::TypeSP& type); + + uint32_t + GetSize() const; + + lldb::TypeSP + GetTypeAtIndex(uint32_t idx); + + typedef std::multimap collection; + typedef AdaptedIterable TypeIterable; + + TypeIterable + Types () + { + return TypeIterable(m_types); + } + + void + ForEach (std::function const &callback) const; + + void + ForEach (std::function const &callback); + + bool + RemoveTypeWithUID (lldb::user_id_t uid); + + void + RemoveMismatchedTypes (const char *qualified_typename, + bool exact_match); + + 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 collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + collection m_types; + + DISALLOW_COPY_AND_ASSIGN (TypeMap); +}; + +} // namespace lldb_private + +#endif // liblldb_TypeMap_h_ Index: include/lldb/lldb-forward.h =================================================================== --- include/lldb/lldb-forward.h +++ include/lldb/lldb-forward.h @@ -255,6 +255,7 @@ class TypeCategoryMap; class TypeImpl; class TypeList; +class TypeMap; class TypeListImpl; class TypeMemberImpl; class TypeMemberFunctionImpl; Index: lldb.xcodeproj/project.pbxproj =================================================================== --- lldb.xcodeproj/project.pbxproj +++ lldb.xcodeproj/project.pbxproj @@ -713,6 +713,7 @@ 6D95DC001B9DC057000E318A /* DIERef.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D95DBFD1B9DC057000E318A /* DIERef.cpp */; }; 6D95DC011B9DC057000E318A /* HashedNameToDIE.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D95DBFE1B9DC057000E318A /* HashedNameToDIE.cpp */; }; 6D95DC021B9DC057000E318A /* SymbolFileDWARFDwo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D95DBFF1B9DC057000E318A /* SymbolFileDWARFDwo.cpp */; }; + 6D9AB3DD1BB2B74E003F2289 /* TypeMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6D9AB3DC1BB2B74E003F2289 /* TypeMap.cpp */; }; 8C2D6A53197A1EAF006989C9 /* MemoryHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */; }; 8C2D6A5E197A250F006989C9 /* MemoryHistoryASan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */; }; 8CCB017E19BA28A80009FD44 /* ThreadCollection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8CCB017A19BA283D0009FD44 /* ThreadCollection.cpp */; }; @@ -2403,6 +2404,8 @@ 6D95DBFF1B9DC057000E318A /* SymbolFileDWARFDwo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SymbolFileDWARFDwo.cpp; sourceTree = ""; }; 6D95DC031B9DC06F000E318A /* DIERef.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DIERef.h; sourceTree = ""; }; 6D95DC041B9DC06F000E318A /* SymbolFileDWARFDwo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SymbolFileDWARFDwo.h; sourceTree = ""; }; + 6D9AB3DC1BB2B74E003F2289 /* TypeMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TypeMap.cpp; path = source/Symbol/TypeMap.cpp; sourceTree = ""; }; + 6D9AB3DE1BB2B76B003F2289 /* TypeMap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = TypeMap.h; path = include/lldb/Symbol/TypeMap.h; sourceTree = ""; }; 8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MemoryHistory.cpp; path = source/Target/MemoryHistory.cpp; sourceTree = ""; }; 8C2D6A54197A1EBE006989C9 /* MemoryHistory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MemoryHistory.h; path = include/lldb/Target/MemoryHistory.h; sourceTree = ""; }; 8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryHistoryASan.cpp; sourceTree = ""; }; @@ -4207,6 +4210,8 @@ 26BC7C4B10F1B6C100F91463 /* Symbol */ = { isa = PBXGroup; children = ( + 6D9AB3DE1BB2B76B003F2289 /* TypeMap.h */, + 6D9AB3DC1BB2B74E003F2289 /* TypeMap.cpp */, 26BC7C5510F1B6E900F91463 /* Block.h */, 26BC7F1310F1B8EC00F91463 /* Block.cpp */, 26BC7C5610F1B6E900F91463 /* ClangASTContext.h */, @@ -6638,6 +6643,7 @@ 3FBA69E11B6067120008F44A /* ScriptInterpreterNone.cpp in Sources */, 266DFE9713FD656E00D0C574 /* OperatingSystem.cpp in Sources */, 26954EBE1401EE8B00294D09 /* DynamicRegisterInfo.cpp in Sources */, + 6D9AB3DD1BB2B74E003F2289 /* TypeMap.cpp in Sources */, 255EFF761AFABA950069F277 /* LockFilePosix.cpp in Sources */, 3FBA69EC1B6067430008F44A /* PythonDataObjects.cpp in Sources */, 26274FA714030F79006BA130 /* DynamicLoaderDarwinKernel.cpp in Sources */, Index: source/Core/Module.cpp =================================================================== --- source/Core/Module.cpp +++ source/Core/Module.cpp @@ -36,6 +36,7 @@ #include "lldb/Target/Target.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" +#include "lldb/Symbol/TypeMap.h" #include "Plugins/ObjectFile/JIT/ObjectFileJIT.h" @@ -940,7 +941,7 @@ const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, - TypeList& types) + TypeMap& types) { Timer scoped_timer(__PRETTY_FUNCTION__, __PRETTY_FUNCTION__); if (sc.module_sp.get() == NULL || sc.module_sp.get() == this) @@ -960,7 +961,11 @@ TypeList& type_list) { const bool append = true; - return FindTypes_Impl(sc, type_name, parent_decl_ctx, append, max_matches, type_list); + TypeMap types_map; + size_t num_types = FindTypes_Impl(sc, type_name, parent_decl_ctx, append, max_matches, types_map); + if (num_types > 0) + sc.SortTypeList(types_map, type_list); + return num_types; } lldb::TypeSP @@ -989,6 +994,7 @@ std::string 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 @@ -1002,10 +1008,10 @@ exact_match = true; } ConstString type_basename_const_str (type_basename.c_str()); - if (FindTypes_Impl(sc, type_basename_const_str, NULL, append, max_matches, types)) + if (FindTypes_Impl(sc, type_basename_const_str, NULL, append, max_matches, typesmap)) { - types.RemoveMismatchedTypes (type_scope, type_basename, type_class, exact_match); - num_matches = types.GetSize(); + typesmap.RemoveMismatchedTypes (type_scope, type_basename, type_class, exact_match); + num_matches = typesmap.GetSize(); } } else @@ -1015,18 +1021,18 @@ { // 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_name_cstr), NULL, append, max_matches, types); - types.RemoveMismatchedTypes (type_class); - num_matches = types.GetSize(); + FindTypes_Impl(sc, ConstString(type_name_cstr), NULL, append, max_matches, typesmap); + typesmap.RemoveMismatchedTypes (type_class); + num_matches = typesmap.GetSize(); } else { - num_matches = FindTypes_Impl(sc, name, NULL, append, max_matches, types); + num_matches = FindTypes_Impl(sc, name, NULL, append, max_matches, typesmap); } } - + if (num_matches > 0) + sc.SortTypeList(typesmap, types); return num_matches; - } SymbolVendor* Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -207,7 +207,7 @@ const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, - lldb_private::TypeList& types) override; + lldb_private::TypeMap& types) override; lldb_private::TypeList * GetTypeList () override; Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -43,6 +43,7 @@ #include "lldb/Symbol/SymbolVendor.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Symbol/TypeMap.h" #include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h" #include "Plugins/Language/ObjC/ObjCLanguage.h" @@ -2840,7 +2841,7 @@ const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, - TypeList& types) + TypeMap& types) { DWARFDebugInfo* info = DebugInfo(); if (info == NULL) @@ -3054,6 +3055,17 @@ CompileUnit* lldb_cu = GetCompUnitForDWARFCompUnit(die.GetCU()); assert (lldb_cu); SymbolContext sc(lldb_cu); + const DWARFDebugInfoEntry* parent_die = die.GetParent().GetDIE(); + while (parent_die != nullptr) + { + if (parent_die->Tag() == DW_TAG_subprogram) + break; + parent_die = parent_die->GetParent(); + } + SymbolContext sc_backup = sc; + if (parent_die != nullptr && !GetFunction(DWARFDIE(die.GetCU(),parent_die), sc)) + sc = sc_backup; + type_sp = ParseType(sc, die, NULL); } else if (type_ptr != DIE_IS_BEING_PARSED) Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h @@ -79,7 +79,7 @@ uint32_t FindGlobalVariables (const lldb_private::RegularExpression& regex, bool append, uint32_t max_matches, lldb_private::VariableList& variables) override; uint32_t FindFunctions (const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list) override; uint32_t FindFunctions (const lldb_private::RegularExpression& regex, bool include_inlines, bool append, lldb_private::SymbolContextList& sc_list) override; - uint32_t FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, lldb_private::TypeList& types) override; + uint32_t FindTypes (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, const lldb_private::CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, lldb_private::TypeMap& types) override; lldb_private::CompilerDeclContext FindNamespace (const lldb_private::SymbolContext& sc, const lldb_private::ConstString &name, Index: source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp =================================================================== --- source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp +++ source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp @@ -28,6 +28,7 @@ #include "lldb/Symbol/LineTable.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/VariableList.h" #include "LogChannelDWARF.h" @@ -1295,7 +1296,7 @@ const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, - TypeList& types + TypeMap& types ) { if (!append) Index: source/Symbol/CMakeLists.txt =================================================================== --- source/Symbol/CMakeLists.txt +++ source/Symbol/CMakeLists.txt @@ -25,6 +25,7 @@ Symtab.cpp Type.cpp TypeList.cpp + TypeMap.cpp TypeSystem.cpp UnwindPlan.cpp UnwindTable.cpp Index: source/Symbol/SymbolContext.cpp =================================================================== --- source/Symbol/SymbolContext.cpp +++ source/Symbol/SymbolContext.cpp @@ -659,6 +659,174 @@ return false; } +class TypeMoveMatchingBlock +{ +public: + TypeMoveMatchingBlock(Block * block, TypeMap &typem, TypeList &typel) : + curr_block(block),type_map(typem),type_list(typel) + { + } + + bool + operator() (const lldb::TypeSP& type) + { + if (type && type->GetSymbolContextScope() != nullptr && curr_block == type->GetSymbolContextScope()->CalculateSymbolContextBlock()) + { + type_list.Insert(type); + type_map.RemoveTypeWithUID(type->GetID()); + return false; + } + return true; + } + +private: + const Block * const curr_block; + TypeMap &type_map; + TypeList &type_list; +}; + +class TypeMoveMatchingFunction +{ +public: + TypeMoveMatchingFunction(Function * block, TypeMap &typem, TypeList &typel) : + func(block),type_map(typem),type_list(typel) + { + } + + bool + operator() (const lldb::TypeSP& type) + { + if (type && type->GetSymbolContextScope() != nullptr && func == type->GetSymbolContextScope()->CalculateSymbolContextFunction()) + { + type_list.Insert(type); + type_map.RemoveTypeWithUID(type->GetID()); + return false; + } + return true; + } + +private: + const Function * const func; + TypeMap &type_map; + TypeList &type_list; +}; + +class TypeMoveMatchingCompileUnit +{ +public: + TypeMoveMatchingCompileUnit(CompileUnit * cunit, TypeMap &typem, TypeList &typel) : + comp_unit(cunit),type_map(typem),type_list(typel) + { + } + + bool + operator() (const lldb::TypeSP& type) + { + if (type && type->GetSymbolContextScope() != nullptr && comp_unit == type->GetSymbolContextScope()->CalculateSymbolContextCompileUnit()) + { + type_list.Insert(type); + type_map.RemoveTypeWithUID(type->GetID()); + return false; + } + return true; + } + +private: + const CompileUnit * const comp_unit; + TypeMap &type_map; + TypeList &type_list; +}; + +class TypeMoveMatchingModule +{ +public: + TypeMoveMatchingModule(lldb::ModuleSP modsp, TypeMap &typem, TypeList &typel) : + modulesp(modsp),type_map(typem),type_list(typel) + { + } + + bool + operator() (const lldb::TypeSP& type) + { + if (type && type->GetSymbolContextScope() != nullptr && modulesp.get() == type->GetSymbolContextScope()->CalculateSymbolContextModule().get()) + { + type_list.Insert(type); + type_map.RemoveTypeWithUID(type->GetID()); + return false; + } + return true; + } + +private: + lldb::ModuleSP modulesp; + TypeMap &type_map; + TypeList &type_list; +}; + +class TypeMaptoList +{ +public: + TypeMaptoList(TypeMap &typem, TypeList &typel) : + type_map(typem),type_list(typel) + { + } + + bool + operator() (const lldb::TypeSP& type) + { + if(type) + { + type_list.Insert(type); + type_map.RemoveTypeWithUID(type->GetID()); + if (type_map.Empty()) + return false; + } + return true; + } + +private: + TypeMap &type_map; + TypeList &type_list; +}; + +void +SymbolContext::SortTypeList(TypeMap &type_map, TypeList &type_list ) const +{ + Block * curr_block = block; + bool isInlinedblock = false; + if (curr_block != nullptr && curr_block->GetContainingInlinedBlock() != nullptr) + isInlinedblock = true; + + while (curr_block != nullptr && !isInlinedblock) + { + TypeMoveMatchingBlock callbackBlock (curr_block, type_map, type_list); + type_map.ForEach(callbackBlock); + curr_block = curr_block->GetParent(); + } + if(function != nullptr && type_map.GetSize() > 0) + { + TypeMoveMatchingFunction callbackFunction (function, type_map, type_list); + type_map.ForEach(callbackFunction); + } + if(comp_unit != nullptr && type_map.GetSize() > 0) + { + TypeMoveMatchingCompileUnit callbackCompileUnit (comp_unit, type_map, type_list); + type_map.ForEach(callbackCompileUnit); + } + if(module_sp && type_map.GetSize() > 0) + { + TypeMoveMatchingModule callbackModule (module_sp, type_map, type_list); + type_map.ForEach(callbackModule); + } + if(type_map.GetSize() > 0) + { + TypeMaptoList callbackM2L (type_map, type_list); + type_map.ForEach(callbackM2L); + + } + return ; +} + ConstString SymbolContext::GetFunctionName (Mangled::NamePreference preference) const { Index: source/Symbol/SymbolFile.cpp =================================================================== --- source/Symbol/SymbolFile.cpp +++ source/Symbol/SymbolFile.cpp @@ -15,7 +15,7 @@ #include "lldb/Core/PluginManager.h" #include "lldb/Core/StreamString.h" #include "lldb/Symbol/ObjectFile.h" -#include "lldb/Symbol/TypeList.h" +#include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Symbol/VariableList.h" @@ -135,7 +135,7 @@ } uint32_t -SymbolFile::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeList& types) +SymbolFile::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeMap& types) { if (!append) types.Clear(); Index: source/Symbol/SymbolVendor.cpp =================================================================== --- source/Symbol/SymbolVendor.cpp +++ source/Symbol/SymbolVendor.cpp @@ -346,7 +346,7 @@ size_t -SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, TypeList& types) +SymbolVendor::FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, TypeMap& types) { ModuleSP module_sp(GetModule()); if (module_sp) Index: source/Symbol/TypeList.cpp =================================================================== --- source/Symbol/TypeList.cpp +++ source/Symbol/TypeList.cpp @@ -42,26 +42,7 @@ { // Just push each type on the back for now. We will worry about uniquing later if (type_sp) - m_types.insert(std::make_pair(type_sp->GetID(), type_sp)); -} - - -bool -TypeList::InsertUnique (const TypeSP& type_sp) -{ - if (type_sp) - { - user_id_t type_uid = type_sp->GetID(); - iterator pos, end = m_types.end(); - - for (pos = m_types.find(type_uid); pos != end && pos->second->GetID() == type_uid; ++pos) - { - if (pos->second.get() == type_sp.get()) - return false; - } - } - Insert (type_sp); - return true; + m_types.push_back(type_sp); } //---------------------------------------------------------------------- @@ -116,7 +97,7 @@ for (pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) { if (i == 0) - return pos->second; + return *pos; --i; } return TypeSP(); @@ -127,7 +108,7 @@ { for (auto pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) { - if (!callback(pos->second)) + if (!callback(*pos)) break; } } @@ -137,32 +118,17 @@ { for (auto pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) { - if (!callback(pos->second)) + if (!callback(*pos)) break; } } - -bool -TypeList::RemoveTypeWithUID (user_id_t uid) -{ - iterator pos = m_types.find(uid); - - if (pos != m_types.end()) - { - m_types.erase(pos); - return true; - } - return false; -} - - void TypeList::Dump(Stream *s, bool show_context) { for (iterator pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) { - pos->second->Dump(s, show_context); + pos->get()->Dump(s, show_context); } } @@ -197,7 +163,7 @@ for (pos = m_types.begin(); pos != end; ++pos) { - Type* the_type = pos->second.get(); + Type* the_type = pos->get(); bool keep_match = false; TypeClass match_type_class = eTypeClassAny; @@ -269,7 +235,7 @@ if (keep_match) { - matching_types.insert (*pos); + matching_types.push_back(*pos); } } m_types.swap(matching_types); @@ -291,10 +257,10 @@ for (pos = m_types.begin(); pos != end; ++pos) { - Type* the_type = pos->second.get(); + Type* the_type = pos->get(); TypeClass match_type_class = the_type->GetForwardCompilerType ().GetTypeClass (); if (match_type_class & type_class) - matching_types.insert (*pos); + matching_types.push_back (*pos); } m_types.swap(matching_types); } Index: source/Symbol/TypeMap.cpp =================================================================== --- /dev/null +++ source/Symbol/TypeMap.cpp @@ -0,0 +1,319 @@ +//===-- TypeMap.cpp --------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +// C Includes +// C++ Includes +#include + +// Other libraries and framework includes +#include "clang/AST/ASTConsumer.h" +#include "clang/AST/ASTContext.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclGroup.h" + +#include "clang/Basic/Builtins.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Basic/TargetInfo.h" + +#include "llvm/Support/FormattedStream.h" +#include "llvm/Support/raw_ostream.h" + +// Project includes +#include "lldb/Symbol/SymbolFile.h" +#include "lldb/Symbol/SymbolVendor.h" +#include "lldb/Symbol/Type.h" +#include "lldb/Symbol/TypeMap.h" + +using namespace lldb; +using namespace lldb_private; +using namespace clang; + +TypeMap::TypeMap() : + m_types () +{ +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +TypeMap::~TypeMap() +{ +} + +void +TypeMap::Insert (const TypeSP& type_sp) +{ + // Just push each type on the back for now. We will worry about uniquing later + if (type_sp) + m_types.insert(std::make_pair(type_sp->GetID(), type_sp)); +} + + +bool +TypeMap::InsertUnique (const TypeSP& type_sp) +{ + if (type_sp) + { + user_id_t type_uid = type_sp->GetID(); + iterator pos, end = m_types.end(); + + for (pos = m_types.find(type_uid); pos != end && pos->second->GetID() == type_uid; ++pos) + { + if (pos->second.get() == type_sp.get()) + return false; + } + } + Insert (type_sp); + return true; +} + +//---------------------------------------------------------------------- +// Find a base type by its unique ID. +//---------------------------------------------------------------------- +//TypeSP +//TypeMap::FindType(lldb::user_id_t uid) +//{ +// iterator pos = m_types.find(uid); +// if (pos != m_types.end()) +// return pos->second; +// return TypeSP(); +//} + +//---------------------------------------------------------------------- +// Find a type by name. +//---------------------------------------------------------------------- +//TypeMap +//TypeMap::FindTypes (const ConstString &name) +//{ +// // Do we ever need to make a lookup by name map? Here we are doing +// // a linear search which isn't going to be fast. +// TypeMap types(m_ast.getTargetInfo()->getTriple().getTriple().c_str()); +// iterator pos, end; +// for (pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) +// if (pos->second->GetName() == name) +// types.Insert (pos->second); +// return types; +//} + +void +TypeMap::Clear() +{ + m_types.clear(); +} + +uint32_t +TypeMap::GetSize() const +{ + return m_types.size(); +} + +bool +TypeMap::Empty() const +{ + return m_types.empty(); +} + +// GetTypeAtIndex isn't used a lot for large type lists, currently only for +// type lists that are returned for "image dump -t TYPENAME" commands and other +// simple symbol queries that grab the first result... + +TypeSP +TypeMap::GetTypeAtIndex(uint32_t idx) +{ + iterator pos, end; + uint32_t i = idx; + for (pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) + { + if (i == 0) + return pos->second; + --i; + } + return TypeSP(); +} + +void +TypeMap::ForEach (std::function const &callback) const +{ + for (auto pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) + { + if (!callback(pos->second)) + break; + } +} + +void +TypeMap::ForEach (std::function const &callback) +{ + for (auto pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) + { + if (!callback(pos->second)) + break; + } +} + + +bool +TypeMap::RemoveTypeWithUID (user_id_t uid) +{ + iterator pos = m_types.find(uid); + + if (pos != m_types.end()) + { + m_types.erase(pos); + return true; + } + return false; +} + + +void +TypeMap::Dump(Stream *s, bool show_context) +{ + for (iterator pos = m_types.begin(), end = m_types.end(); pos != end; ++pos) + { + pos->second->Dump(s, show_context); + } +} + +void +TypeMap::RemoveMismatchedTypes (const char *qualified_typename, + bool exact_match) +{ + std::string type_scope; + std::string 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, type_class, exact_match); +} + +void +TypeMap::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 + // 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(); + bool keep_match = false; + TypeClass match_type_class = eTypeClassAny; + + if (type_class != eTypeClassAny) + { + match_type_class = the_type->GetForwardCompilerType ().GetTypeClass (); + if ((match_type_class & type_class) == 0) + continue; + } + + 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(); + std::string match_type_scope; + std::string match_type_basename; + if (Type::GetTypeScopeAndBasename (match_type_name, + match_type_scope, + match_type_basename, + match_type_class)) + { + 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(); + if (exact_match || (type_scope_size == match_type_scope_size)) + { + keep_match = match_type_scope == type_scope; + } + else + { + if (match_type_scope_size > type_scope_size) + { + const size_t type_scope_pos = match_type_scope.rfind(type_scope); + if (type_scope_pos == match_type_scope_size - type_scope_size) + { + if (type_scope_pos >= 2) + { + // Our match scope ends with the type scope we were looking for, + // but we need to make sure what comes before the matching + // type scope is a namespace boundary in case we are trying to match: + // type_basename = "d" + // type_scope = "b::c::" + // We want to match: + // match_type_scope "a::b::c::" + // But not: + // match_type_scope "a::bb::c::" + // So below we make sure what comes before "b::c::" in match_type_scope + // is "::", or the namespace boundary + if (match_type_scope[type_scope_pos - 1] == ':' && + match_type_scope[type_scope_pos - 2] == ':') + { + keep_match = true; + } + } + } + } + } + } + } + else + { + // The type we are currently looking at doesn't exists + // in a namespace or class, so it only matches if there + // is no type scope... + keep_match = type_scope.empty() && type_basename.compare(match_type_name) == 0; + } + } + + if (keep_match) + { + matching_types.insert (*pos); + } + } + m_types.swap(matching_types); +} + +void +TypeMap::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 = the_type->GetForwardCompilerType ().GetTypeClass (); + if (match_type_class & type_class) + matching_types.insert (*pos); + } + m_types.swap(matching_types); +}