Extend FindTypes with CompilerContext to allow filtering by language.

This patch is also motivated by the Swift branch and is effectively NFC for the single-TypeSystem llvm.org branch.

In multi-language projects it is extremely common to have, e.g., a
Clang type and a similarly-named rendition of that same type in
another language. When searching for a type It is much cheaper to pass
a set of supported languages to the SymbolFile than having it
materialize every result and then rejecting the materialized types
that have the wrong language.

Differential Revision: https://reviews.llvm.org/D66546

<rdar://problem/54471165>

llvm-svn: 369690
diff --git a/lldb/source/Core/Debugger.cpp b/lldb/source/Core/Debugger.cpp
index e3cd18a..513ea7a 100644
--- a/lldb/source/Core/Debugger.cpp
+++ b/lldb/source/Core/Debugger.cpp
@@ -1623,13 +1623,11 @@
   FileSpec repl_executable;
 
   if (language == eLanguageTypeUnknown) {
-    std::set<LanguageType> 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;
diff --git a/lldb/source/Core/PluginManager.cpp b/lldb/source/Core/PluginManager.cpp
index e0026e3..80b64fb 100644
--- a/lldb/source/Core/PluginManager.cpp
+++ b/lldb/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<TypeSystemInstance> 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<std::recursive_mutex> guard(GetTypeSystemMutex());
     GetTypeSystemInstances().push_back(instance);
   }
@@ -2163,30 +2163,22 @@
   return nullptr;
 }
 
-TypeSystemEnumerateSupportedLanguages
-PluginManager::GetTypeSystemEnumerateSupportedLanguagesCallbackAtIndex(
-    uint32_t idx) {
+LanguageSet PluginManager::GetAllTypeSystemSupportedLanguagesForTypes() {
   std::lock_guard<std::recursive_mutex> 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<std::recursive_mutex> 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<std::recursive_mutex> 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<REPLInstance> 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<std::recursive_mutex> guard(GetREPLMutex());
     GetREPLInstances().push_back(instance);
   }
@@ -2269,29 +2260,13 @@
   return nullptr;
 }
 
-REPLEnumerateSupportedLanguages
-PluginManager::GetREPLEnumerateSupportedLanguagesCallbackAtIndex(uint32_t idx) {
+LanguageSet PluginManager::GetREPLAllTypeSystemSupportedLanguages() {
   std::lock_guard<std::recursive_mutex> 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<std::recursive_mutex> 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
diff --git a/lldb/source/Interpreter/OptionValueLanguage.cpp b/lldb/source/Interpreter/OptionValueLanguage.cpp
index d935d5e..1d7e188 100644
--- a/lldb/source/Interpreter/OptionValueLanguage.cpp
+++ b/lldb/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<lldb::LanguageType> languages_for_types;
-    std::set<lldb::LanguageType> 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());
     }
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
index d5f5145..494e2d4 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.cpp
@@ -319,7 +319,8 @@
 }
 
 size_t SymbolFileBreakpad::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
-                                     bool append, TypeMap &types) {
+                                     LanguageSet languages, bool append,
+                                     TypeMap &types) {
   if (!append)
     types.Clear();
   return types.GetSize();
diff --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
index def975e..c066ae3 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -116,8 +116,8 @@
                      llvm::DenseSet<SymbolFile *> &searched_symbol_files,
                      TypeMap &types) override;
 
-  size_t FindTypes(llvm::ArrayRef<CompilerContext> pattern, bool append,
-                   TypeMap &types) override;
+  size_t FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+                   LanguageSet languages, bool append, TypeMap &types) override;
 
   llvm::Expected<TypeSystem &>
   GetTypeSystemForLanguage(lldb::LanguageType language) override {
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 5ef46ef..8956a4f 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/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;
     }
   }
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index ba63b41..6b357c2 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -2485,7 +2485,8 @@
 }
 
 size_t SymbolFileDWARF::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
-                                  bool append, TypeMap &types) {
+                                  LanguageSet languages, bool append,
+                                  TypeMap &types) {
   std::lock_guard<std::recursive_mutex> 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<CompilerContext, 4> die_context;
       die.GetDeclContext(die_context);
       if (!contextMatches(die_context, pattern))
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 0d59013..2a1eb8a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -185,7 +185,8 @@
             lldb_private::TypeMap &types) override;
 
   size_t FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> 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,
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 32b13c9..05e4878 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -1270,7 +1270,10 @@
 }
 
 size_t SymbolFileNativePDB::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
-                                      bool append, TypeMap &types) {
+                                      LanguageSet languages, bool append,
+                                      TypeMap &types) {
+  if (!append)
+    types.Clear();
   return 0;
 }
 
diff --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index f64fb4f..f2e840c 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -134,8 +134,8 @@
                      llvm::DenseSet<SymbolFile *> &searched_symbol_files,
                      TypeMap &types) override;
 
-  size_t FindTypes(llvm::ArrayRef<CompilerContext> pattern, bool append,
-                   TypeMap &types) override;
+  size_t FindTypes(llvm::ArrayRef<CompilerContext> pattern,
+                   LanguageSet languages, bool append, TypeMap &types) override;
 
   llvm::Expected<TypeSystem &>
   GetTypeSystemForLanguage(lldb::LanguageType language) override;
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 51b84c4..efd3b0c 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -1585,7 +1585,10 @@
 }
 
 size_t SymbolFilePDB::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
-                                bool append, lldb_private::TypeMap &types) {
+                                LanguageSet languages, bool append,
+                                lldb_private::TypeMap &types) {
+  if (!append)
+    types.Clear();
   return 0;
 }
 
diff --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index 15eed0f..a360a18 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -133,7 +133,8 @@
             lldb_private::TypeMap &types) override;
 
   size_t FindTypes(llvm::ArrayRef<lldb_private::CompilerContext> 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 &regex,
                         uint32_t max_matches, lldb_private::TypeMap &types);
diff --git a/lldb/source/Symbol/ClangASTContext.cpp b/lldb/source/Symbol/ClangASTContext.cpp
index 43b19fb..d1d9a73 100644
--- a/lldb/source/Symbol/ClangASTContext.cpp
+++ b/lldb/source/Symbol/ClangASTContext.cpp
@@ -734,32 +734,36 @@
   return lldb::TypeSystemSP();
 }
 
-void ClangASTContext::EnumerateSupportedLanguages(
-    std::set<lldb::LanguageType> &languages_for_types,
-    std::set<lldb::LanguageType> &languages_for_expressions) {
-  static std::vector<lldb::LanguageType> 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});
+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;
+}
 
-  static std::vector<lldb::LanguageType> 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::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() {
diff --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp
index 1cbfb4c..b1fc852 100644
--- a/lldb/source/Symbol/SymbolFile.cpp
+++ b/lldb/source/Symbol/SymbolFile.cpp
@@ -150,7 +150,8 @@
 }
 
 size_t SymbolFile::FindTypes(llvm::ArrayRef<CompilerContext> pattern,
-                             bool append, TypeMap &types) {
+                             LanguageSet languages, bool append,
+                             TypeMap &types) {
   if (!append)
     types.Clear();
   return 0;
diff --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp
index e5fd7e5..7ce551f 100644
--- a/lldb/source/Symbol/TypeSystem.cpp
+++ b/lldb/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<LanguageType> 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() {}
diff --git a/lldb/source/Target/Language.cpp b/lldb/source/Target/Language.cpp
index 3c3ef28..43d0be0 100644
--- a/lldb/source/Target/Language.cpp
+++ b/lldb/source/Target/Language.cpp
@@ -357,26 +357,16 @@
   return supported_languages;
 }
 
-void Language::GetLanguagesSupportingTypeSystems(
-    std::set<lldb::LanguageType> &languages,
-    std::set<lldb::LanguageType> &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<lldb::LanguageType> &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::TypeScavenger> Language::GetTypeScavenger() {
diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 2368fa1..957b97e 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/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<LanguageType> 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<lldb::LanguageType> languages_for_types;
-    std::set<lldb::LanguageType> languages_for_expressions;
+    LanguageSet languages_for_expressions =
+        Language::GetLanguagesSupportingTypeSystemsForExpressions();
 
-    Language::GetLanguagesSupportingTypeSystems(languages_for_types,
-                                                languages_for_expressions);
-
-    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<llvm::StringError>(
             "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<TypeSystem *> scratch_type_systems;
 
-  std::set<lldb::LanguageType> languages_for_types;
-  std::set<lldb::LanguageType> languages_for_expressions;
+  LanguageSet languages_for_expressions =
+      Language::GetLanguagesSupportingTypeSystemsForExpressions();
 
-  Language::GetLanguagesSupportingTypeSystems(languages_for_types,
-                                              languages_for_expressions);
-
-  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());
   }