Index: lldb/trunk/include/lldb/Core/PluginManager.h =================================================================== --- lldb/trunk/include/lldb/Core/PluginManager.h +++ lldb/trunk/include/lldb/Core/PluginManager.h @@ -384,10 +384,10 @@ GetInstrumentationRuntimeCreateCallbackForPluginName(ConstString name); // TypeSystem - static bool RegisterPlugin( - ConstString name, const char *description, - TypeSystemCreateInstance create_callback, - TypeSystemEnumerateSupportedLanguages enumerate_languages_callback); + static bool RegisterPlugin(ConstString name, const char *description, + TypeSystemCreateInstance create_callback, + LanguageSet supported_languages_for_types, + LanguageSet supported_languages_for_expressions); static bool UnregisterPlugin(TypeSystemCreateInstance create_callback); @@ -397,18 +397,14 @@ static TypeSystemCreateInstance GetTypeSystemCreateCallbackForPluginName(ConstString name); - static TypeSystemEnumerateSupportedLanguages - GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx); + static LanguageSet GetAllTypeSystemSupportedLanguagesForTypes(); - static TypeSystemEnumerateSupportedLanguages - GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName( - ConstString name); + static LanguageSet GetAllTypeSystemSupportedLanguagesForExpressions(); // REPL - static bool - RegisterPlugin(ConstString name, const char *description, - REPLCreateInstance create_callback, - REPLEnumerateSupportedLanguages enumerate_languages_callback); + static bool RegisterPlugin(ConstString name, const char *description, + REPLCreateInstance create_callback, + LanguageSet supported_languages); static bool UnregisterPlugin(REPLCreateInstance create_callback); @@ -417,12 +413,7 @@ static REPLCreateInstance GetREPLCreateCallbackForPluginName(ConstString name); - static REPLEnumerateSupportedLanguages - GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx); - - static REPLEnumerateSupportedLanguages - GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName( - ConstString name); + static LanguageSet GetREPLAllTypeSystemSupportedLanguages(); // Some plug-ins might register a DebuggerInitializeCallback callback when // registering the plug-in. After a new Debugger instance is created, this @@ -440,32 +431,28 @@ ConstString description, bool is_global_property); static lldb::OptionValuePropertiesSP - GetSettingForPlatformPlugin(Debugger &debugger, - ConstString setting_name); + GetSettingForPlatformPlugin(Debugger &debugger, ConstString setting_name); static bool CreateSettingForPlatformPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, bool is_global_property); static lldb::OptionValuePropertiesSP - GetSettingForProcessPlugin(Debugger &debugger, - ConstString setting_name); + GetSettingForProcessPlugin(Debugger &debugger, ConstString setting_name); static bool CreateSettingForProcessPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, bool is_global_property); static lldb::OptionValuePropertiesSP - GetSettingForSymbolFilePlugin(Debugger &debugger, - ConstString setting_name); + GetSettingForSymbolFilePlugin(Debugger &debugger, ConstString setting_name); static bool CreateSettingForSymbolFilePlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, ConstString description, bool is_global_property); static lldb::OptionValuePropertiesSP - GetSettingForJITLoaderPlugin(Debugger &debugger, - ConstString setting_name); + GetSettingForJITLoaderPlugin(Debugger &debugger, ConstString setting_name); static bool CreateSettingForJITLoaderPlugin( Debugger &debugger, const lldb::OptionValuePropertiesSP &properties_sp, Index: lldb/trunk/include/lldb/Symbol/ClangASTContext.h =================================================================== --- lldb/trunk/include/lldb/Symbol/ClangASTContext.h +++ lldb/trunk/include/lldb/Symbol/ClangASTContext.h @@ -68,9 +68,8 @@ static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language, Module *module, Target *target); - static void EnumerateSupportedLanguages( - std::set &languages_for_types, - std::set &languages_for_expressions); + static LanguageSet GetSupportedLanguagesForTypes(); + static LanguageSet GetSupportedLanguagesForExpressions(); static void Initialize(); Index: lldb/trunk/include/lldb/Symbol/SymbolFile.h =================================================================== --- lldb/trunk/include/lldb/Symbol/SymbolFile.h +++ lldb/trunk/include/lldb/Symbol/SymbolFile.h @@ -17,6 +17,7 @@ #include "lldb/Symbol/SourceModule.h" #include "lldb/Symbol/Type.h" #include "lldb/Symbol/TypeList.h" +#include "lldb/Symbol/TypeSystem.h" #include "lldb/lldb-private.h" #include "llvm/ADT/DenseSet.h" @@ -189,7 +190,11 @@ bool append, uint32_t max_matches, llvm::DenseSet &searched_symbol_files, TypeMap &types); - virtual size_t FindTypes(llvm::ArrayRef pattern, bool append, + + /// Find types specified by a CompilerContextPattern. + /// \param languages Only return results in these languages. + virtual size_t FindTypes(llvm::ArrayRef pattern, + LanguageSet languages, bool append, TypeMap &types); virtual void Index: lldb/trunk/include/lldb/Symbol/TypeSystem.h =================================================================== --- lldb/trunk/include/lldb/Symbol/TypeSystem.h +++ lldb/trunk/include/lldb/Symbol/TypeSystem.h @@ -15,6 +15,7 @@ #include #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/SmallBitVector.h" #include "llvm/Support/Casting.h" #include "llvm/Support/Error.h" @@ -30,7 +31,24 @@ namespace lldb_private { -// Interface for representing the Type Systems in different languages. +/// A SmallBitVector that represents a set of source languages (\p +/// lldb::LanguageType). Each lldb::LanguageType is represented by +/// the bit with the position of its enumerator. The largest +/// LanguageType is < 64, so this is space-efficient and on 64-bit +/// architectures a LanguageSet can be completely stack-allocated. +struct LanguageSet { + llvm::SmallBitVector bitvector; + LanguageSet() = default; + + /// If the set contains a single language only, return it. + llvm::Optional GetSingularLanguage(); + void Insert(lldb::LanguageType language); + bool Empty() const; + size_t Size() const; + bool operator[](unsigned i) const; +}; + +/// Interface for representing the Type Systems in different languages. class TypeSystem : public PluginInterface { public: // Intrusive type system that allows us to use llvm casting. Index: lldb/trunk/include/lldb/Target/Language.h =================================================================== --- lldb/trunk/include/lldb/Target/Language.h +++ lldb/trunk/include/lldb/Target/Language.h @@ -266,12 +266,9 @@ static std::set GetSupportedLanguages(); - static void GetLanguagesSupportingTypeSystems( - std::set &languages, - std::set &languages_for_expressions); - - static void - GetLanguagesSupportingREPLs(std::set &languages); + static LanguageSet GetLanguagesSupportingTypeSystems(); + static LanguageSet GetLanguagesSupportingTypeSystemsForExpressions(); + static LanguageSet GetLanguagesSupportingREPLs(); protected: // Classes that inherit from Language can see and modify these Index: lldb/trunk/include/lldb/lldb-private-interfaces.h =================================================================== --- lldb/trunk/include/lldb/lldb-private-interfaces.h +++ lldb/trunk/include/lldb/lldb-private-interfaces.h @@ -102,11 +102,6 @@ lldb::LanguageType language, Debugger *debugger, Target *target, const char *repl_options); -typedef void (*TypeSystemEnumerateSupportedLanguages)( - std::set &languages_for_types, - std::set &languages_for_expressions); -typedef void (*REPLEnumerateSupportedLanguages)( - std::set &languages); typedef int (*ComparisonFunction)(const void *, const void *); typedef void (*DebuggerInitializeCallback)(Debugger &debugger); Index: lldb/trunk/lit/SymbolFile/DWARF/compilercontext.ll =================================================================== --- lldb/trunk/lit/SymbolFile/DWARF/compilercontext.ll +++ lldb/trunk/lit/SymbolFile/DWARF/compilercontext.ll @@ -1,18 +1,21 @@ ; Test finding types by CompilerContext. ; RUN: llc %s -filetype=obj -o %t.o -; RUN: lldb-test symbols %t.o -find=type \ +; RUN: lldb-test symbols %t.o -find=type --language=C99 \ ; RUN: -compiler-context="Module:CModule,Module:SubModule,Struct:FromSubmoduleX" \ ; RUN: | FileCheck %s --check-prefix=NORESULTS -; RUN: lldb-test symbols %t.o -find=type \ +; RUN: lldb-test symbols %t.o -find=type --language=C++ \ +; RUN: -compiler-context="Module:CModule,Module:SubModule,Struct:FromSubmodule" \ +; RUN: | FileCheck %s --check-prefix=NORESULTS +; RUN: lldb-test symbols %t.o -find=type --language=C99 \ ; RUN: -compiler-context="Module:CModule,Module:SubModule,Struct:FromSubmodule" \ ; RUN: | FileCheck %s -; RUN: lldb-test symbols %t.o -find=type \ +; RUN: lldb-test symbols %t.o -find=type --language=C99 \ ; RUN: -compiler-context="Module:CModule,AnyModule:*,Struct:FromSubmodule" \ ; RUN: | FileCheck %s -; RUN: lldb-test symbols %t.o -find=type \ +; RUN: lldb-test symbols %t.o -find=type --language=C99 \ ; RUN: -compiler-context="AnyModule:*,Struct:FromSubmodule" \ ; RUN: | FileCheck %s -; RUN: lldb-test symbols %t.o -find=type \ +; RUN: lldb-test symbols %t.o -find=type --language=C99 \ ; RUN: -compiler-context="Module:CModule,Module:SubModule,AnyType:FromSubmodule" \ ; RUN: | FileCheck %s ; Index: lldb/trunk/source/Core/Debugger.cpp =================================================================== --- lldb/trunk/source/Core/Debugger.cpp +++ lldb/trunk/source/Core/Debugger.cpp @@ -1623,13 +1623,11 @@ FileSpec repl_executable; if (language == eLanguageTypeUnknown) { - std::set repl_languages; + LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs(); - Language::GetLanguagesSupportingREPLs(repl_languages); - - if (repl_languages.size() == 1) { - language = *repl_languages.begin(); - } else if (repl_languages.empty()) { + if (auto single_lang = repl_languages.GetSingularLanguage()) { + language = *single_lang; + } else if (repl_languages.Empty()) { err.SetErrorStringWithFormat( "LLDB isn't configured with REPL support for any languages."); return err; Index: lldb/trunk/source/Core/PluginManager.cpp =================================================================== --- lldb/trunk/source/Core/PluginManager.cpp +++ lldb/trunk/source/Core/PluginManager.cpp @@ -2083,12 +2083,11 @@ #pragma mark TypeSystem struct TypeSystemInstance { - TypeSystemInstance() : name(), description(), create_callback(nullptr) {} - ConstString name; std::string description; TypeSystemCreateInstance create_callback; - TypeSystemEnumerateSupportedLanguages enumerate_callback; + LanguageSet supported_languages_for_types; + LanguageSet supported_languages_for_expressions; }; typedef std::vector TypeSystemInstances; @@ -2103,11 +2102,11 @@ return g_instances; } -bool PluginManager::RegisterPlugin(ConstString name, - const char *description, - TypeSystemCreateInstance create_callback, - TypeSystemEnumerateSupportedLanguages - enumerate_supported_languages_callback) { +bool PluginManager::RegisterPlugin( + ConstString name, const char *description, + TypeSystemCreateInstance create_callback, + LanguageSet supported_languages_for_types, + LanguageSet supported_languages_for_expressions) { if (create_callback) { TypeSystemInstance instance; assert((bool)name); @@ -2115,7 +2114,8 @@ if (description && description[0]) instance.description = description; instance.create_callback = create_callback; - instance.enumerate_callback = enumerate_supported_languages_callback; + instance.supported_languages_for_types = supported_languages_for_types; + instance.supported_languages_for_expressions = supported_languages_for_expressions; std::lock_guard guard(GetTypeSystemMutex()); GetTypeSystemInstances().push_back(instance); } @@ -2163,30 +2163,22 @@ return nullptr; } -TypeSystemEnumerateSupportedLanguages -PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex( - uint32_t idx) { +LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() { std::lock_guard guard(GetTypeSystemMutex()); + LanguageSet all; TypeSystemInstances &instances = GetTypeSystemInstances(); - if (idx < instances.size()) - return instances[idx].enumerate_callback; - return nullptr; + for (unsigned i = 0; i < instances.size(); ++i) + all.bitvector |= instances[i].supported_languages_for_types.bitvector; + return all; } -TypeSystemEnumerateSupportedLanguages -PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetTypeSystemMutex()); - TypeSystemInstances &instances = GetTypeSystemInstances(); - - TypeSystemInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->enumerate_callback; - } - } - return nullptr; +LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions() { + std::lock_guard guard(GetTypeSystemMutex()); + LanguageSet all; + TypeSystemInstances &instances = GetTypeSystemInstances(); + for (unsigned i = 0; i < instances.size(); ++i) + all.bitvector |= instances[i].supported_languages_for_expressions.bitvector; + return all; } #pragma mark REPL @@ -2197,7 +2189,7 @@ ConstString name; std::string description; REPLCreateInstance create_callback; - REPLEnumerateSupportedLanguages enumerate_languages_callback; + LanguageSet supported_languages; }; typedef std::vector REPLInstances; @@ -2212,10 +2204,9 @@ return g_instances; } -bool PluginManager::RegisterPlugin( - ConstString name, const char *description, - REPLCreateInstance create_callback, - REPLEnumerateSupportedLanguages enumerate_languages_callback) { +bool PluginManager::RegisterPlugin(ConstString name, const char *description, + REPLCreateInstance create_callback, + LanguageSet supported_languages) { if (create_callback) { REPLInstance instance; assert((bool)name); @@ -2223,7 +2214,7 @@ if (description && description[0]) instance.description = description; instance.create_callback = create_callback; - instance.enumerate_languages_callback = enumerate_languages_callback; + instance.supported_languages = supported_languages; std::lock_guard guard(GetREPLMutex()); GetREPLInstances().push_back(instance); } @@ -2269,29 +2260,13 @@ return nullptr; } -REPLEnumerateSupportedLanguages -PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) { +LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() { std::lock_guard guard(GetREPLMutex()); + LanguageSet all; REPLInstances &instances = GetREPLInstances(); - if (idx < instances.size()) - return instances[idx].enumerate_languages_callback; - return nullptr; -} - -REPLEnumerateSupportedLanguages -PluginManager::GetREPLSystemEnumerateSupportedLanguagesCallbackForPluginName( - ConstString name) { - if (name) { - std::lock_guard guard(GetREPLMutex()); - REPLInstances &instances = GetREPLInstances(); - - REPLInstances::iterator pos, end = instances.end(); - for (pos = instances.begin(); pos != end; ++pos) { - if (name == pos->name) - return pos->enumerate_languages_callback; - } - } - return nullptr; + for (unsigned i = 0; i < instances.size(); ++i) + all.bitvector |= instances[i].supported_languages.bitvector; + return all; } #pragma mark PluginManager Index: lldb/trunk/source/Interpreter/OptionValueLanguage.cpp =================================================================== --- lldb/trunk/source/Interpreter/OptionValueLanguage.cpp +++ lldb/trunk/source/Interpreter/OptionValueLanguage.cpp @@ -10,6 +10,7 @@ #include "lldb/DataFormatters/FormatManager.h" #include "lldb/Target/Language.h" +#include "lldb/Symbol/TypeSystem.h" #include "lldb/Utility/Args.h" #include "lldb/Utility/Stream.h" @@ -39,23 +40,20 @@ case eVarSetOperationReplace: case eVarSetOperationAssign: { ConstString lang_name(value.trim()); - std::set languages_for_types; - std::set languages_for_expressions; - Language::GetLanguagesSupportingTypeSystems(languages_for_types, - languages_for_expressions); - + LanguageSet languages_for_types = Language::GetLanguagesSupportingTypeSystems(); LanguageType new_type = Language::GetLanguageTypeFromString(lang_name.GetStringRef()); - if (new_type && languages_for_types.count(new_type)) { + if (new_type && languages_for_types[new_type]) { m_value_was_set = true; m_current_value = new_type; } else { StreamString error_strm; error_strm.Printf("invalid language type '%s', ", value.str().c_str()); error_strm.Printf("valid values are:\n"); - for (lldb::LanguageType language : languages_for_types) { - error_strm.Printf("%s%s%s", " ", - Language::GetNameForLanguageType(language), "\n"); + for (int bit : languages_for_types.bitvector.set_bits()) { + auto language = (LanguageType)bit; + error_strm.Printf(" %s\n", + Language::GetNameForLanguageType(language)); } error.SetErrorString(error_strm.GetString()); } Index: lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h +++ lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h @@ -116,8 +116,8 @@ llvm::DenseSet &searched_symbol_files, TypeMap &types) override; - size_t FindTypes(llvm::ArrayRef pattern, bool append, - TypeMap &types) override; + size_t FindTypes(llvm::ArrayRef pattern, + LanguageSet languages, bool append, TypeMap &types) override; llvm::Expected GetTypeSystemForLanguage(lldb::LanguageType language) override { Index: lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp +++ lldb/trunk/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp @@ -319,7 +319,8 @@ } size_t SymbolFileBreakpad::FindTypes(llvm::ArrayRef pattern, - bool append, TypeMap &types) { + LanguageSet languages, bool append, + TypeMap &types) { if (!append) types.Clear(); return types.GetSize(); Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp @@ -148,7 +148,10 @@ die.GetDeclContext(decl_context); TypeMap dwo_types; - if (!dwo_module_sp->GetSymbolFile()->FindTypes(decl_context, true, + // The type in the Clang module must have the same langage as the current CU. + LanguageSet languages; + languages.Insert(die.GetCU()->GetLanguageType()); + if (!dwo_module_sp->GetSymbolFile()->FindTypes(decl_context, languages, true, dwo_types)) { if (!IsClangModuleFwdDecl(die)) return TypeSP(); @@ -159,8 +162,8 @@ for (const auto &name_module : sym_file.getExternalTypeModules()) { if (!name_module.second) continue; - if (name_module.second->GetSymbolFile()->FindTypes(decl_context, true, - dwo_types)) + if (name_module.second->GetSymbolFile()->FindTypes( + decl_context, languages, true, dwo_types)) break; } } Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h @@ -185,7 +185,8 @@ lldb_private::TypeMap &types) override; size_t FindTypes(llvm::ArrayRef pattern, - bool append, lldb_private::TypeMap &types) override; + lldb_private::LanguageSet languages, bool append, + lldb_private::TypeMap &types) override; size_t GetTypes(lldb_private::SymbolContextScope *sc_scope, lldb::TypeClass type_mask, Index: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp @@ -2485,7 +2485,8 @@ } size_t SymbolFileDWARF::FindTypes(llvm::ArrayRef pattern, - bool append, TypeMap &types) { + LanguageSet languages, bool append, + TypeMap &types) { std::lock_guard guard(GetModuleMutex()); if (!append) types.Clear(); @@ -2508,6 +2509,9 @@ DWARFDIE die = GetDIE(die_ref); if (die) { + if (!languages[die.GetCU()->GetLanguageType()]) + continue; + llvm::SmallVector die_context; die.GetDeclContext(die_context); if (!contextMatches(die_context, pattern)) Index: lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h +++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h @@ -134,8 +134,8 @@ llvm::DenseSet &searched_symbol_files, TypeMap &types) override; - size_t FindTypes(llvm::ArrayRef pattern, bool append, - TypeMap &types) override; + size_t FindTypes(llvm::ArrayRef pattern, + LanguageSet languages, bool append, TypeMap &types) override; llvm::Expected GetTypeSystemForLanguage(lldb::LanguageType language) override; Index: lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp +++ lldb/trunk/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp @@ -1270,7 +1270,10 @@ } size_t SymbolFileNativePDB::FindTypes(llvm::ArrayRef pattern, - bool append, TypeMap &types) { + LanguageSet languages, bool append, + TypeMap &types) { + if (!append) + types.Clear(); return 0; } Index: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h +++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h @@ -133,7 +133,8 @@ lldb_private::TypeMap &types) override; size_t FindTypes(llvm::ArrayRef pattern, - bool append, lldb_private::TypeMap &types) override; + lldb_private::LanguageSet languages, bool append, + lldb_private::TypeMap &types) override; void FindTypesByRegex(const lldb_private::RegularExpression ®ex, uint32_t max_matches, lldb_private::TypeMap &types); Index: lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp =================================================================== --- lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp +++ lldb/trunk/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp @@ -1585,7 +1585,10 @@ } size_t SymbolFilePDB::FindTypes(llvm::ArrayRef pattern, - bool append, lldb_private::TypeMap &types) { + LanguageSet languages, bool append, + lldb_private::TypeMap &types) { + if (!append) + types.Clear(); return 0; } Index: lldb/trunk/source/Symbol/ClangASTContext.cpp =================================================================== --- lldb/trunk/source/Symbol/ClangASTContext.cpp +++ lldb/trunk/source/Symbol/ClangASTContext.cpp @@ -734,32 +734,36 @@ return lldb::TypeSystemSP(); } -void ClangASTContext::EnumerateSupportedLanguages( - std::set &languages_for_types, - std::set &languages_for_expressions) { - static std::vector s_supported_languages_for_types( - {lldb::eLanguageTypeC89, lldb::eLanguageTypeC, lldb::eLanguageTypeC11, - lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeC99, - lldb::eLanguageTypeObjC, lldb::eLanguageTypeObjC_plus_plus, - lldb::eLanguageTypeC_plus_plus_03, lldb::eLanguageTypeC_plus_plus_11, - lldb::eLanguageTypeC11, lldb::eLanguageTypeC_plus_plus_14}); - - static std::vector s_supported_languages_for_expressions( - {lldb::eLanguageTypeC_plus_plus, lldb::eLanguageTypeObjC_plus_plus, - lldb::eLanguageTypeC_plus_plus_03, lldb::eLanguageTypeC_plus_plus_11, - lldb::eLanguageTypeC_plus_plus_14}); - - languages_for_types.insert(s_supported_languages_for_types.begin(), - s_supported_languages_for_types.end()); - languages_for_expressions.insert( - s_supported_languages_for_expressions.begin(), - s_supported_languages_for_expressions.end()); +LanguageSet ClangASTContext::GetSupportedLanguagesForTypes() { + LanguageSet languages; + languages.Insert(lldb::eLanguageTypeC89); + languages.Insert(lldb::eLanguageTypeC); + languages.Insert(lldb::eLanguageTypeC11); + languages.Insert(lldb::eLanguageTypeC_plus_plus); + languages.Insert(lldb::eLanguageTypeC99); + languages.Insert(lldb::eLanguageTypeObjC); + languages.Insert(lldb::eLanguageTypeObjC_plus_plus); + languages.Insert(lldb::eLanguageTypeC_plus_plus_03); + languages.Insert(lldb::eLanguageTypeC_plus_plus_11); + languages.Insert(lldb::eLanguageTypeC11); + languages.Insert(lldb::eLanguageTypeC_plus_plus_14); + return languages; +} + +LanguageSet ClangASTContext::GetSupportedLanguagesForExpressions() { + LanguageSet languages; + languages.Insert(lldb::eLanguageTypeC_plus_plus); + languages.Insert(lldb::eLanguageTypeObjC_plus_plus); + languages.Insert(lldb::eLanguageTypeC_plus_plus_03); + languages.Insert(lldb::eLanguageTypeC_plus_plus_11); + languages.Insert(lldb::eLanguageTypeC_plus_plus_14); + return languages; } void ClangASTContext::Initialize() { - PluginManager::RegisterPlugin(GetPluginNameStatic(), - "clang base AST context plug-in", - CreateInstance, EnumerateSupportedLanguages); + PluginManager::RegisterPlugin( + GetPluginNameStatic(), "clang base AST context plug-in", CreateInstance, + GetSupportedLanguagesForTypes(), GetSupportedLanguagesForExpressions()); } void ClangASTContext::Terminate() { Index: lldb/trunk/source/Symbol/SymbolFile.cpp =================================================================== --- lldb/trunk/source/Symbol/SymbolFile.cpp +++ lldb/trunk/source/Symbol/SymbolFile.cpp @@ -150,7 +150,8 @@ } size_t SymbolFile::FindTypes(llvm::ArrayRef pattern, - bool append, TypeMap &types) { + LanguageSet languages, bool append, + TypeMap &types) { if (!append) types.Clear(); return 0; Index: lldb/trunk/source/Symbol/TypeSystem.cpp =================================================================== --- lldb/trunk/source/Symbol/TypeSystem.cpp +++ lldb/trunk/source/Symbol/TypeSystem.cpp @@ -25,6 +25,23 @@ using namespace lldb_private; using namespace lldb; +/// A 64-bit SmallBitVector is only small up to 64-7 bits, and the +/// setBitsInMask interface wants to write full bytes. +static const size_t num_small_bitvector_bits = 64 - 8; +static_assert(eNumLanguageTypes < num_small_bitvector_bits, + "Languages bit vector is no longer small on 64 bit systems"); + +llvm::Optional LanguageSet::GetSingularLanguage() { + if (bitvector.count() == 1) + return (LanguageType)bitvector.find_first(); + return {}; +} + +void LanguageSet::Insert(LanguageType language) { bitvector.set(language); } +size_t LanguageSet::Size() const { return bitvector.count(); } +bool LanguageSet::Empty() const { return bitvector.none(); } +bool LanguageSet::operator[](unsigned i) const { return bitvector[i]; } + TypeSystem::TypeSystem(LLVMCastKind kind) : m_kind(kind), m_sym_file(nullptr) {} TypeSystem::~TypeSystem() {} Index: lldb/trunk/source/Target/Language.cpp =================================================================== --- lldb/trunk/source/Target/Language.cpp +++ lldb/trunk/source/Target/Language.cpp @@ -357,26 +357,16 @@ return supported_languages; } -void Language::GetLanguagesSupportingTypeSystems( - std::set &languages, - std::set &languages_for_expressions) { - uint32_t idx = 0; - - while (TypeSystemEnumerateSupportedLanguages enumerate = PluginManager:: - GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(idx++)) { - (*enumerate)(languages, languages_for_expressions); - } +LanguageSet Language::GetLanguagesSupportingTypeSystems() { + return PluginManager::GetAllTypeSystemSupportedLanguagesForTypes(); } -void Language::GetLanguagesSupportingREPLs( - std::set &languages) { - uint32_t idx = 0; +LanguageSet Language::GetLanguagesSupportingTypeSystemsForExpressions() { + return PluginManager::GetAllTypeSystemSupportedLanguagesForExpressions(); +} - while (REPLEnumerateSupportedLanguages enumerate = - PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex( - idx++)) { - (*enumerate)(languages); - } +LanguageSet Language::GetLanguagesSupportingREPLs() { + return PluginManager::GetREPLAllTypeSystemSupportedLanguages(); } std::unique_ptr Language::GetTypeScavenger() { Index: lldb/trunk/source/Target/Target.cpp =================================================================== --- lldb/trunk/source/Target/Target.cpp +++ lldb/trunk/source/Target/Target.cpp @@ -206,13 +206,11 @@ lldb::REPLSP Target::GetREPL(Status &err, lldb::LanguageType language, const char *repl_options, bool can_create) { if (language == eLanguageTypeUnknown) { - std::set repl_languages; + LanguageSet repl_languages = Language::GetLanguagesSupportingREPLs(); - Language::GetLanguagesSupportingREPLs(repl_languages); - - if (repl_languages.size() == 1) { - language = *repl_languages.begin(); - } else if (repl_languages.size() == 0) { + if (auto single_lang = repl_languages.GetSingularLanguage()) { + language = *single_lang; + } else if (repl_languages.Empty()) { err.SetErrorStringWithFormat( "LLDB isn't configured with REPL support for any languages."); return REPLSP(); @@ -2129,23 +2127,18 @@ if (language == eLanguageTypeMipsAssembler // GNU AS and LLVM use it for all // assembly code || language == eLanguageTypeUnknown) { - std::set languages_for_types; - std::set languages_for_expressions; - - Language::GetLanguagesSupportingTypeSystems(languages_for_types, - languages_for_expressions); + LanguageSet languages_for_expressions = + Language::GetLanguagesSupportingTypeSystemsForExpressions(); - if (languages_for_expressions.count(eLanguageTypeC)) { + if (languages_for_expressions[eLanguageTypeC]) { language = eLanguageTypeC; // LLDB's default. Override by setting the // target language. } else { - if (languages_for_expressions.empty()) { + if (languages_for_expressions.Empty()) return llvm::make_error( "No expression support for any languages", llvm::inconvertibleErrorCode()); - } else { - language = *languages_for_expressions.begin(); - } + language = (LanguageType)languages_for_expressions.bitvector.find_first(); } } @@ -2159,21 +2152,19 @@ std::vector scratch_type_systems; - std::set languages_for_types; - std::set languages_for_expressions; - - Language::GetLanguagesSupportingTypeSystems(languages_for_types, - languages_for_expressions); + LanguageSet languages_for_expressions = + Language::GetLanguagesSupportingTypeSystemsForExpressions(); - for (auto lang : languages_for_expressions) { + for (auto bit : languages_for_expressions.bitvector.set_bits()) { + auto language = (LanguageType)bit; auto type_system_or_err = - GetScratchTypeSystemForLanguage(lang, create_on_demand); + GetScratchTypeSystemForLanguage(language, create_on_demand); if (!type_system_or_err) LLDB_LOG_ERROR(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_TARGET), type_system_or_err.takeError(), "Language '{}' has expression support but no scratch type " "system available", - Language::GetNameForLanguageType(lang)); + Language::GetNameForLanguageType(language)); else scratch_type_systems.emplace_back(&type_system_or_err.get()); } Index: lldb/trunk/tools/lldb-test/lldb-test.cpp =================================================================== --- lldb/trunk/tools/lldb-test/lldb-test.cpp +++ lldb/trunk/tools/lldb-test/lldb-test.cpp @@ -26,6 +26,7 @@ #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeMap.h" #include "lldb/Symbol/VariableList.h" +#include "lldb/Target/Language.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Utility/CleanUp.h" @@ -144,6 +145,10 @@ cl::desc("Specify a compiler context as \"kind:name,...\"."), cl::value_desc("context"), cl::sub(SymbolsSubcommand)); +static cl::opt + Language("language", cl::desc("Specify a language type, like C99."), + cl::value_desc("language"), cl::sub(SymbolsSubcommand)); + static cl::list FunctionNameFlags( "function-flags", cl::desc("Function search flags:"), cl::values(clEnumValN(eFunctionNameTypeAuto, "auto", @@ -507,13 +512,17 @@ CompilerDeclContext *ContextPtr = ContextOr->IsValid() ? &*ContextOr : nullptr; + LanguageSet languages; + if (!Language.empty()) + languages.Insert(Language::GetLanguageTypeFromString(Language)); + DenseSet SearchedFiles; TypeMap Map; if (!Name.empty()) Symfile.FindTypes(ConstString(Name), ContextPtr, true, UINT32_MAX, SearchedFiles, Map); else - Symfile.FindTypes(parseCompilerContext(), true, Map); + Symfile.FindTypes(parseCompilerContext(), languages, true, Map); outs() << formatv("Found {0} types:\n", Map.GetSize()); StreamString Stream;