Index: include/lldb/Core/Mangled.h
===================================================================
--- include/lldb/Core/Mangled.h
+++ include/lldb/Core/Mangled.h
@@ -11,8 +11,9 @@
 #define liblldb_Mangled_h_
 #if defined(__cplusplus)
 
-#include "lldb/Utility/ConstString.h"
 #include "lldb/lldb-enumerations.h"
+#include "lldb/lldb-forward.h"
+#include "lldb/Utility/ConstString.h"
 #include "llvm/ADT/StringRef.h"
 
 #include <memory>
@@ -306,20 +307,23 @@
   /// ItaniumPartialDemangler. All other names fall back to LLDB's builtin
   /// parser currently.
   ///
-  /// @param[in] spec
-  ///     The RichManglingSpec that provides the context for this function. One
-  ///     instance can be used for multiple calls. Should be stack-allocated in
-  ///     the caller's frame.
+  /// This function is thread-safe when used with different \a context
+  /// instances in different threads.
+  ///
+  /// @param[in] context
+  ///     The context for this function. A single instance can be stack-
+  ///     allocated in the caller's frame and used for multiple calls.
   ///
   /// @param[in] skip_mangled_name
   ///     A filtering function for skipping entities based on name and mangling
   ///     scheme. This can be null if unused.
   ///
   /// @return
-  ///     The rich mangling info on success, null otherwise.
+  ///     The rich mangling info on success, null otherwise. Expect the pointer
+  ///     to be valid only until the next call to this funtion.
   //----------------------------------------------------------------------
   const RichManglingInfo *
-  DemangleWithRichManglingInfo(RichManglingSpec &spec,
+  DemangleWithRichManglingInfo(RichManglingContext &context,
                                SkipMangledNameFn *skip_mangled_name);
 
 private:
Index: include/lldb/Core/RichManglingInfo.h
===================================================================
--- /dev/null
+++ include/lldb/Core/RichManglingInfo.h
@@ -0,0 +1,95 @@
+//===-- RichManglingInfo.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_RichManglingInfo_h_
+#define liblldb_RichManglingInfo_h_
+
+#include "lldb/lldb-private.h"
+#include "llvm/ADT/Any.h"
+#include "llvm/Demangle/Demangle.h"
+
+namespace lldb_private {
+
+/// Uniform wrapper for access to rich mangling information from different
+/// providers. See Mangled::DemangleWithRichManglingInfo()
+class RichManglingInfo {
+public:
+  /// If this symbol describes a constructor or destructor.
+  bool IsCtorOrDtor() const;
+
+  /// If this symbol describes a function.
+  bool IsFunction() const;
+
+  /// Get the base name of a function. This doesn't include trailing template
+  /// arguments, ie for "a::b<int>" this function returns "b".
+  const char *GetFunctionBaseName() const;
+
+  /// Get the context name for a function. For "a::b::c", this function returns
+  /// "a::b".
+  const char *GetFunctionDeclContextName() const;
+
+private:
+  enum InfoProvider { ItaniumPartialDemangler, PluginCxxLanguage };
+
+  /// Selects the rich mangling info provider. Initially undefined. Configured
+  /// from RichManglingContext::SetX (instance not accessible before).
+  InfoProvider m_provider;
+
+  /// Members for ItaniumPartialDemangler
+  llvm::ItaniumPartialDemangler *m_IPD = nullptr;
+  mutable size_t m_IPD_size = 0;
+  mutable char *m_IPD_buf = nullptr;
+
+  /// Members for PluginCxxLanguage
+  /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The
+  /// respective header is in Plugins and including it from here causes cyclic
+  /// dependency. Instead keep a llvm::Any and cast it on-access in the cpp.
+  mutable llvm::Any m_legacy_parser;
+
+  /// Obtain the legacy parser casted to the given type. Ideally we had a type
+  /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we
+  /// can't access CPlusPlusLanguage::MethodName from within the header.
+  template <class ParserT> ParserT *get() const {
+    assert(m_legacy_parser.hasValue());
+    assert(llvm::any_isa<ParserT>(m_legacy_parser));
+    return llvm::any_cast<ParserT *>(m_legacy_parser);
+  }
+
+  /// Reset the provider and clean up memory before reassigning/destroying.
+  void ResetProvider();
+
+  // Default construction in undefined state from RichManglingContext.
+  RichManglingInfo() = default;
+
+  // Destruction from RichManglingContext.
+  ~RichManglingInfo();
+
+  // Declare RichManglingContext as friend so it can access the default ctor and
+  // assign to members in its SetX methods.
+  friend class RichManglingContext;
+};
+
+//----------------------------------------------------------------------
+
+/// Unique owner of RichManglingInfo. Handles configuration and lifetime.
+class RichManglingContext {
+public:
+  RichManglingInfo *SetItaniumInfo();
+  RichManglingInfo *SetLegacyCxxParserInfo(const ConstString &mangled);
+
+  llvm::ItaniumPartialDemangler &GetIPD() { return m_IPD; }
+
+private:
+  RichManglingInfo m_info;
+  llvm::ItaniumPartialDemangler m_IPD;
+};
+
+} // namespace lldb_private
+
+#endif
Index: include/lldb/Symbol/Symtab.h
===================================================================
--- include/lldb/Symbol/Symtab.h
+++ include/lldb/Symbol/Symtab.h
@@ -17,93 +17,9 @@
 #include "lldb/Core/UniqueCStringMap.h"
 #include "lldb/Symbol/Symbol.h"
 #include "lldb/lldb-private.h"
-#include "llvm/Demangle/Demangle.h"
 
 namespace lldb_private {
 
-/// Uniform wrapper for access to rich mangling information from different
-/// providers. See Mangled::DemangleWithRichManglingInfo()
-class RichManglingInfo {
-public:
-  /// If this symbol describes a constructor or destructor.
-  bool isCtorOrDtor() const;
-
-  /// If this symbol describes a function.
-  bool isFunction() const;
-
-  /// Get the base name of a function. This doesn't include trailing template
-  /// arguments, ie for "a::b<int>" this function returns "b".
-  const char *getFunctionBaseName() const;
-
-  /// Get the context name for a function. For "a::b::c", this function returns
-  /// "a::b".
-  const char *getFunctionDeclContextName() const;
-
-private:
-  enum InfoProvider { ItaniumPartialDemangler, PluginCxxLanguage };
-
-  /// Selects the rich mangling info provider. Initially undefined, but
-  /// initialized in RichManglingSpec::CreateX (instance not accessible before).
-  InfoProvider m_provider;
-
-  /// Members for ItaniumPartialDemangler
-  llvm::ItaniumPartialDemangler *m_IPD = nullptr;
-  mutable size_t m_IPD_size = 0;
-  mutable char *m_IPD_buf = nullptr;
-
-  /// Members for PluginCxxLanguage
-  /// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The
-  /// respective header is in Plugins and including it from here causes cyclic
-  /// dependency. Keep a void* here instead and cast it on-demand on the cpp.
-  void *m_legacy_parser = nullptr;
-
-  /// Obtain the legacy parser casted to the given type. Ideally we had a type
-  /// trait to deduce \a ParserT from a given InfoProvider, but unfortunately we
-  /// can't access CPlusPlusLanguage::MethodName from within the header.
-  template <class ParserT> ParserT *get() const {
-    assert(m_legacy_parser);
-    return reinterpret_cast<ParserT *>(m_legacy_parser);
-  }
-
-  /// Reset the provider and clean up memory before reassigning/destroying.
-  void ResetProvider();
-
-  // Default construction in undefined state from RichManglingSpec.
-  RichManglingInfo() = default;
-
-  // Destruction from RichManglingSpec.
-  ~RichManglingInfo();
-
-  // No copy
-  RichManglingInfo(const RichManglingInfo &) = delete;
-  RichManglingInfo &operator=(const RichManglingInfo &) = delete;
-
-  // No move
-  RichManglingInfo(RichManglingInfo &&) = delete;
-  RichManglingInfo &operator=(RichManglingInfo &&) = delete;
-
-  // Declare RichManglingSpec as friend so it can access the default ctor and
-  // assign to members in its CreateX methods.
-  friend class RichManglingSpec;
-};
-
-//----------------------------------------------------------------------
-
-/// Unique owner of RichManglingInfo. Handles initialization and lifetime.
-class RichManglingSpec {
-public:
-  RichManglingInfo *CreateItaniumInfo();
-  RichManglingInfo *CreateLegacyCxxParserInfo(const ConstString &mangled);
-
-  llvm::ItaniumPartialDemangler &GetIPD() { return m_IPD; }
-
-private:
-  RichManglingInfo m_info;
-  llvm::ItaniumPartialDemangler m_IPD;
-};
-
-//----------------------------------------------------------------------
-
 class Symtab {
 public:
   typedef std::vector<uint32_t> IndexCollection;
Index: include/lldb/lldb-forward.h
===================================================================
--- include/lldb/lldb-forward.h
+++ include/lldb/lldb-forward.h
@@ -192,7 +192,7 @@
 class RegularExpression;
 class REPL;
 class RichManglingInfo;
-class RichManglingSpec;
+class RichManglingContext;
 class Scalar;
 class ScriptInterpreter;
 class ScriptInterpreterLocker;
Index: source/Core/CMakeLists.txt
===================================================================
--- source/Core/CMakeLists.txt
+++ source/Core/CMakeLists.txt
@@ -34,6 +34,7 @@
   Opcode.cpp
   PluginManager.cpp
   RegisterValue.cpp
+  RichManglingInfo.cpp
   Scalar.cpp
   SearchFilter.cpp
   Section.cpp
Index: source/Core/Mangled.cpp
===================================================================
--- source/Core/Mangled.cpp
+++ source/Core/Mangled.cpp
@@ -16,6 +16,7 @@
 #pragma comment(lib, "dbghelp.lib")
 #endif
 
+#include "lldb/Core/RichManglingInfo.h"
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/Logging.h"
@@ -289,7 +290,7 @@
 // makes use of ItaniumPartialDemangler's rich demangle info
 //----------------------------------------------------------------------
 const RichManglingInfo *
-Mangled::DemangleWithRichManglingInfo(RichManglingSpec &spec,
+Mangled::DemangleWithRichManglingInfo(RichManglingContext &context,
                                       SkipMangledNameFn *skip_mangled_name) {
   // We need to generate and cache the demangled name.
   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
@@ -315,13 +316,13 @@
   case eManglingSchemeItanium:
     // We want the rich mangling info here, so we don't care whether or not
     // there is a demangled string in the pool already.
-    if (char *D = GetItaniumRichDemangleInfo(M.data(), spec.GetIPD())) {
+    if (char *D = GetItaniumRichDemangleInfo(M.data(), context.GetIPD())) {
       // Connect the counterparts in the string pool to accelerate subsequent
       // access in GetDemangledName().
       m_demangled.SetCStringWithMangledCounterpart(D, m_mangled);
       std::free(D);
 
-      return spec.CreateItaniumInfo();
+      return context.SetItaniumInfo();
     } else {
       m_demangled.SetCString("");
       return nullptr;
@@ -347,7 +348,7 @@
     } else {
       // Demangled successfully, we can try and parse it with
       // CPlusPlusLanguage::MethodName.
-      return spec.CreateLegacyCxxParserInfo(m_mangled);
+      return context.SetLegacyCxxParserInfo(m_mangled);
     }
   }
   }
Index: source/Core/RichManglingInfo.cpp
===================================================================
--- /dev/null
+++ source/Core/RichManglingInfo.cpp
@@ -0,0 +1,93 @@
+//===-- RichManglingInfo.cpp ------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Core/RichManglingInfo.h"
+#include "lldb/Utility/ConstString.h"
+
+#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+void RichManglingInfo::ResetProvider() {
+  // If we want to support parsers for other languages some day, we need a
+  // switch here to delete the correct parser type.
+  if (m_legacy_parser.hasValue()) {
+    assert(m_provider == RichManglingInfo::PluginCxxLanguage);
+    delete get<CPlusPlusLanguage::MethodName>();
+    m_legacy_parser = nullptr;
+  }
+}
+
+RichManglingInfo *RichManglingContext::SetItaniumInfo() {
+  m_info.ResetProvider();
+  m_info.m_provider = RichManglingInfo::ItaniumPartialDemangler;
+  m_info.m_IPD = &m_IPD;
+  return &m_info;
+}
+
+RichManglingInfo *
+RichManglingContext::SetLegacyCxxParserInfo(const ConstString &mangled) {
+  m_info.ResetProvider();
+  m_info.m_provider = RichManglingInfo::PluginCxxLanguage;
+  m_info.m_legacy_parser = new CPlusPlusLanguage::MethodName(mangled);
+  return &m_info;
+}
+
+RichManglingInfo::~RichManglingInfo() {
+  ResetProvider();
+  delete m_IPD_buf;
+}
+
+bool RichManglingInfo::IsCtorOrDtor() const {
+  switch (m_provider) {
+  case ItaniumPartialDemangler:
+    return m_IPD->isCtorOrDtor();
+  case PluginCxxLanguage: {
+    // We can only check for destructors here.
+    auto base_name = get<CPlusPlusLanguage::MethodName>()->GetBasename();
+    return base_name.front() == '~';
+  }
+  }
+}
+
+bool RichManglingInfo::IsFunction() const {
+  switch (m_provider) {
+  case ItaniumPartialDemangler:
+    return m_IPD->isFunction();
+  case PluginCxxLanguage:
+    return get<CPlusPlusLanguage::MethodName>()->IsValid();
+  }
+}
+
+const char *RichManglingInfo::GetFunctionBaseName() const {
+  switch (m_provider) {
+  case ItaniumPartialDemangler:
+    if (auto buf = m_IPD->getFunctionBaseName(m_IPD_buf, &m_IPD_size)) {
+      m_IPD_buf = buf;
+      return buf;
+    }
+    return nullptr;
+  case PluginCxxLanguage:
+    return get<CPlusPlusLanguage::MethodName>()->GetBasename().data();
+  }
+}
+
+const char *RichManglingInfo::GetFunctionDeclContextName() const {
+  switch (m_provider) {
+  case ItaniumPartialDemangler:
+    if (auto buf = m_IPD->getFunctionDeclContextName(m_IPD_buf, &m_IPD_size)) {
+      m_IPD_buf = buf;
+      return buf;
+    }
+    return nullptr;
+  case PluginCxxLanguage:
+    return get<CPlusPlusLanguage::MethodName>()->GetContext().data();
+  }
+}
Index: source/Symbol/Symtab.cpp
===================================================================
--- source/Symbol/Symtab.cpp
+++ source/Symbol/Symtab.cpp
@@ -10,9 +10,10 @@
 #include <map>
 #include <set>
 
-#include "Plugins/Language/CPlusPlus/CPlusPlusLanguage.h"
 #include "Plugins/Language/ObjC/ObjCLanguage.h"
+
 #include "lldb/Core/Module.h"
+#include "lldb/Core/RichManglingInfo.h"
 #include "lldb/Core/STLUtils.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Symbol/ObjectFile.h"
@@ -22,7 +23,6 @@
 #include "lldb/Utility/RegularExpression.h"
 #include "lldb/Utility/Stream.h"
 #include "lldb/Utility/Timer.h"
-#include "llvm/Demangle/Demangle.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -213,81 +213,6 @@
   return nullptr;
 }
 
-//----------------------------------------------------------------------
-// RichManglingInfo
-//----------------------------------------------------------------------
-
-void RichManglingInfo::ResetProvider() {
-  // If we want to support parsers for other languages some day, we need a
-  // switch here to delete the correct parser type.
-  if (m_legacy_parser) {
-    assert(m_provider == RichManglingInfo::PluginCxxLanguage);
-    delete get<CPlusPlusLanguage::MethodName>();
-    m_legacy_parser = nullptr;
-  }
-}
-
-RichManglingInfo *RichManglingSpec::CreateItaniumInfo() {
-  m_info.ResetProvider();
-  m_info.m_provider = RichManglingInfo::ItaniumPartialDemangler;
-  m_info.m_IPD = &m_IPD;
-  return &m_info;
-}
-
-RichManglingInfo *
-RichManglingSpec::CreateLegacyCxxParserInfo(const ConstString &mangled) {
-  m_info.ResetProvider();
-  m_info.m_provider = RichManglingInfo::PluginCxxLanguage;
-  m_info.m_legacy_parser = new CPlusPlusLanguage::MethodName(mangled);
-  return &m_info;
-}
-
-RichManglingInfo::~RichManglingInfo() { 
-  ResetProvider();
-  delete m_IPD_buf;
-}
-
-bool RichManglingInfo::isCtorOrDtor() const {
-  switch (m_provider) {
-  case ItaniumPartialDemangler:
-    return m_IPD->isCtorOrDtor();
-  case PluginCxxLanguage: {
-    // We can only check for destructors here.
-    auto base_name = get<CPlusPlusLanguage::MethodName>()->GetBasename();
-    return base_name.front() == '~';
-  }
-  }
-}
-
-bool RichManglingInfo::isFunction() const {
-  switch (m_provider) {
-  case ItaniumPartialDemangler:
-    return m_IPD->isFunction();
-  case PluginCxxLanguage:
-    return get<CPlusPlusLanguage::MethodName>()->IsValid();
-  }
-}
-
-const char *RichManglingInfo::getFunctionBaseName() const {
-  switch (m_provider) {
-  case ItaniumPartialDemangler:
-    m_IPD_buf = m_IPD->getFunctionBaseName(m_IPD_buf, &m_IPD_size);
-    return m_IPD_buf;
-  case PluginCxxLanguage:
-    return get<CPlusPlusLanguage::MethodName>()->GetBasename().data();
-  }
-}
-
-const char *RichManglingInfo::getFunctionDeclContextName() const {
-  switch (m_provider) {
-  case ItaniumPartialDemangler:
-    m_IPD_buf = m_IPD->getFunctionDeclContextName(m_IPD_buf, &m_IPD_size);
-    return m_IPD_buf;
-  case PluginCxxLanguage:
-    return get<CPlusPlusLanguage::MethodName>()->GetContext().data();
-  }
-}
-
 //----------------------------------------------------------------------
 // InitNameIndexes
 //----------------------------------------------------------------------
@@ -361,7 +286,7 @@
 
     // Instantiation of the demangler is expensive, so better use a single one
     // for all entries during batch processing.
-    RichManglingSpec spec;
+    RichManglingContext MC;
     NameToIndexMap::Entry entry;
 
     for (entry.value = 0; entry.value < num_symbols; ++entry.value) {
@@ -392,7 +317,7 @@
         const SymbolType type = symbol->GetType();
         if (type == eSymbolTypeCode || type == eSymbolTypeResolver) {
           if (const RichManglingInfo *info =
-                  mangled.DemangleWithRichManglingInfo(spec, lldb_skip_name))
+                  mangled.DemangleWithRichManglingInfo(MC, lldb_skip_name))
             RegisterMangledNameEntry(entry, class_contexts,
                                      mangled_name_to_index, symbol_contexts,
                                      *info);
@@ -465,7 +390,7 @@
     UniqueCStringMap<uint32_t> &mangled_name_to_index,
     std::vector<const char *> &symbol_contexts, const RichManglingInfo &info) {
   // Only register functions that have a base name.
-  const char *base_name_cstr = info.getFunctionBaseName();
+  const char *base_name_cstr = info.GetFunctionBaseName();
   if (base_name_cstr == nullptr)
     return;
 
@@ -473,7 +398,7 @@
   entry.cstring = ConstString(base_name_cstr);
 
   // Register functions with no context.
-  ConstString decl_context(info.getFunctionDeclContextName());
+  ConstString decl_context(info.GetFunctionDeclContextName());
   if (decl_context.IsEmpty()) {
     // This has to be a basename
     m_basename_to_index.Append(entry);
@@ -488,7 +413,7 @@
 
   // Register constructors and destructors. They are methods and create
   // declaration contexts.
-  if (info.isCtorOrDtor()) {
+  if (info.IsCtorOrDtor()) {
     m_method_to_index.Append(entry);
     if (it == class_contexts.end())
       class_contexts.insert(it, decl_context.GetCString());