[Lldb-commits] [lldb] 6eaedbb - Make CompilerType safe

Adrian Prantl via lldb-commits lldb-commits at lists.llvm.org
Wed Nov 16 15:51:55 PST 2022


Author: Adrian Prantl
Date: 2022-11-16T15:51:26-08:00
New Revision: 6eaedbb52f2a616e644e5acc7279c8b07c4cfe82

URL: https://github.com/llvm/llvm-project/commit/6eaedbb52f2a616e644e5acc7279c8b07c4cfe82
DIFF: https://github.com/llvm/llvm-project/commit/6eaedbb52f2a616e644e5acc7279c8b07c4cfe82.diff

LOG: Make CompilerType safe

When a process gets restarted TypeSystem objects associated with it
may get deleted, and any CompilerType objects holding on to a
reference to that type system are a use-after-free in waiting. Because
of the SBAPI, we don't have tight control over where CompilerTypes go
and when they are used. This is particularly a problem in the Swift
plugin, where the scratch TypeSystem can be restarted while the
process is still running. The Swift plugin has a lock to prevent
abuse, but where there's a lock there can be bugs.

This patch changes CompilerType to store a std::weak_ptr<TypeSystem>.
Most of the std::weak_ptr<TypeSystem>* uglyness is hidden by
introducing a wrapper class CompilerType::WrappedTypeSystem that has a
dyn_cast_or_null() method. The only sites that need to know about the
weak pointer implementation detail are the ones that deal with
creating TypeSystems.

rdar://101505232

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

Added: 
    

Modified: 
    lldb/include/lldb/Core/Module.h
    lldb/include/lldb/Symbol/CompilerType.h
    lldb/include/lldb/Symbol/SymbolFile.h
    lldb/include/lldb/Symbol/SymbolFileOnDemand.h
    lldb/include/lldb/Symbol/TaggedASTType.h
    lldb/include/lldb/Symbol/Type.h
    lldb/include/lldb/Symbol/TypeSystem.h
    lldb/include/lldb/Target/Target.h
    lldb/include/lldb/lldb-enumerations.h
    lldb/include/lldb/lldb-forward.h
    lldb/source/API/SBModule.cpp
    lldb/source/API/SBTarget.cpp
    lldb/source/API/SBType.cpp
    lldb/source/Breakpoint/Watchpoint.cpp
    lldb/source/Commands/CommandObjectTarget.cpp
    lldb/source/Core/DumpDataExtractor.cpp
    lldb/source/Core/Module.cpp
    lldb/source/Core/ValueObjectMemory.cpp
    lldb/source/Core/ValueObjectRegister.cpp
    lldb/source/DataFormatters/VectorType.cpp
    lldb/source/Expression/Materializer.cpp
    lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
    lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
    lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
    lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
    lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp
    lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
    lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
    lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
    lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
    lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
    lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
    lldb/source/Plugins/Language/ObjC/NSArray.cpp
    lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
    lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
    lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
    lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
    lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
    lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
    lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
    lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
    lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
    lldb/source/Plugins/Platform/Linux/PlatformLinux.h
    lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
    lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
    lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
    lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
    lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
    lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
    lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
    lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
    lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
    lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
    lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
    lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
    lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
    lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
    lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
    lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
    lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
    lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
    lldb/source/Symbol/CompilerType.cpp
    lldb/source/Symbol/SymbolFile.cpp
    lldb/source/Symbol/SymbolFileOnDemand.cpp
    lldb/source/Symbol/Type.cpp
    lldb/source/Symbol/TypeSystem.cpp
    lldb/source/Target/Process.cpp
    lldb/source/Target/StackFrame.cpp
    lldb/source/Target/Statistics.cpp
    lldb/source/Target/Target.cpp
    lldb/source/Target/ThreadPlanTracer.cpp
    lldb/tools/lldb-test/lldb-test.cpp
    lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp
    lldb/unittests/Symbol/TestClangASTImporter.cpp
    lldb/unittests/Symbol/TestTypeSystemClang.cpp
    lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
    lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h

Removed: 
    


################################################################################
diff  --git a/lldb/include/lldb/Core/Module.h b/lldb/include/lldb/Core/Module.h
index 523e04c6e6b4c..87caf1cde0d36 100644
--- a/lldb/include/lldb/Core/Module.h
+++ b/lldb/include/lldb/Core/Module.h
@@ -812,10 +812,10 @@ class Module : public std::enable_shared_from_this<Module>,
 
   bool GetIsDynamicLinkEditor();
 
-  llvm::Expected<TypeSystem &>
+  llvm::Expected<lldb::TypeSystemSP>
   GetTypeSystemForLanguage(lldb::LanguageType language);
 
-  void ForEachTypeSystem(llvm::function_ref<bool(TypeSystem *)> callback);
+  void ForEachTypeSystem(llvm::function_ref<bool(lldb::TypeSystemSP)> callback);
 
   // Special error functions that can do printf style formatting that will
   // prepend the message with something appropriate for this module (like the

diff  --git a/lldb/include/lldb/Symbol/CompilerType.h b/lldb/include/lldb/Symbol/CompilerType.h
index 1ad9d6ae4c406..fc2c849261d06 100644
--- a/lldb/include/lldb/Symbol/CompilerType.h
+++ b/lldb/include/lldb/Symbol/CompilerType.h
@@ -15,10 +15,12 @@
 
 #include "lldb/lldb-private.h"
 #include "llvm/ADT/APSInt.h"
+#include "llvm/Support/Casting.h"
 
 namespace lldb_private {
 
 class DataExtractor;
+class TypeSystem;
 
 /// Generic representation of a type in a programming language.
 ///
@@ -38,38 +40,87 @@ class CompilerType {
   /// implementation.
   ///
   /// \see lldb_private::TypeSystemClang::GetType(clang::QualType)
-  CompilerType(TypeSystem *type_system, lldb::opaque_compiler_type_t type)
-      : m_type(type), m_type_system(type_system) {
+  CompilerType(lldb::TypeSystemWP type_system,
+               lldb::opaque_compiler_type_t type)
+    : m_type_system(type_system), m_type(type) {
+    assert(Verify() && "verification failed");
+  }
+
+  /// This is a minimal wrapper of a TypeSystem shared pointer as
+  /// returned by CompilerType which conventien dyn_cast support.
+  class TypeSystemSPWrapper {
+    lldb::TypeSystemSP m_typesystem_sp;
+
+  public:
+    TypeSystemSPWrapper() = default;
+    TypeSystemSPWrapper(lldb::TypeSystemSP typesystem_sp)
+        : m_typesystem_sp(typesystem_sp) {}
+
+    template <class TypeSystemType> bool isa_and_nonnull() {
+      if (auto *ts = m_typesystem_sp.get())
+        return llvm::isa<TypeSystemType>(ts);
+      return false;
+    }
+
+    /// Return a shared_ptr<TypeSystemType> if dyn_cast succeeds.
+    template <class TypeSystemType>
+    std::shared_ptr<TypeSystemType> dyn_cast_or_null() {
+      if (isa_and_nonnull<TypeSystemType>())
+        return std::shared_ptr<TypeSystemType>(
+            m_typesystem_sp, llvm::cast<TypeSystemType>(m_typesystem_sp.get()));
+      return nullptr;
+    }
+
+    explicit operator bool() const {
+      return static_cast<bool>(m_typesystem_sp);
+    }
+    bool operator==(const TypeSystemSPWrapper &other) const;
+    bool operator!=(const TypeSystemSPWrapper &other) const {
+      return !(*this == other);
+    }
+
+    /// Only to be used in a one-off situations like
+    ///    if (typesystem && typesystem->method())
+    /// Do not store this pointer!
+    TypeSystem *operator->() const;
+
+    lldb::TypeSystemSP GetSharedPointer() const { return m_typesystem_sp; }
+  };
+
+  CompilerType(TypeSystemSPWrapper type_system, lldb::opaque_compiler_type_t type)
+    : m_type_system(type_system.GetSharedPointer()), m_type(type) {
     assert(Verify() && "verification failed");
   }
 
   CompilerType(const CompilerType &rhs)
-      : m_type(rhs.m_type), m_type_system(rhs.m_type_system) {}
+      : m_type_system(rhs.m_type_system), m_type(rhs.m_type) {}
 
   CompilerType() = default;
 
   /// Operators.
   /// \{
   const CompilerType &operator=(const CompilerType &rhs) {
-    m_type = rhs.m_type;
     m_type_system = rhs.m_type_system;
+    m_type = rhs.m_type;
     return *this;
   }
 
   bool operator<(const CompilerType &rhs) const {
-    if (m_type_system == rhs.m_type_system)
+    auto lts = m_type_system.lock();
+    auto rts = rhs.m_type_system.lock();
+    if (lts.get() == rts.get())
       return m_type < rhs.m_type;
-    return m_type_system < rhs.m_type_system;
+    return lts.get() < rts.get();
   }
   /// \}
 
   /// Tests.
   /// \{
   explicit operator bool() const {
-    return m_type != nullptr && m_type_system != nullptr;
+    return m_type_system.lock() && m_type;
   }
 
-  bool IsValid() const { return m_type != nullptr && m_type_system != nullptr; }
+  bool IsValid() const { return (bool)*this; }
 
   bool IsArrayType(CompilerType *element_type = nullptr,
                    uint64_t *size = nullptr,
@@ -159,7 +210,10 @@ class CompilerType {
 
   /// Accessors.
   /// \{
-  TypeSystem *GetTypeSystem() const { return m_type_system; }
+
+  /// Returns a shared pointer to the type system. The
+  /// TypeSystem::TypeSystemSPWrapper can be compared for equality.
+  TypeSystemSPWrapper GetTypeSystem() const;
 
   ConstString GetTypeName(bool BaseOnly = false) const;
 
@@ -174,7 +228,9 @@ class CompilerType {
 
   lldb::TypeClass GetTypeClass() const;
 
-  void SetCompilerType(TypeSystem *type_system,
+  void SetCompilerType(lldb::TypeSystemWP type_system,
+                       lldb::opaque_compiler_type_t type);
+  void SetCompilerType(TypeSystemSPWrapper type_system,
                        lldb::opaque_compiler_type_t type);
 
   unsigned GetTypeQualifiers() const;
@@ -407,8 +463,8 @@ class CompilerType {
                         size_t data_byte_size, Scalar &value,
                         ExecutionContextScope *exe_scope) const;
   void Clear() {
+    m_type_system = {};
     m_type = nullptr;
-    m_type_system = nullptr;
   }
 
 private:
@@ -419,8 +475,8 @@ class CompilerType {
   bool Verify() const;
 #endif
 
+  lldb::TypeSystemWP m_type_system;
   lldb::opaque_compiler_type_t m_type = nullptr;
-  TypeSystem *m_type_system = nullptr;
 };
 
 bool operator==(const CompilerType &lhs, const CompilerType &rhs);

diff  --git a/lldb/include/lldb/Symbol/SymbolFile.h b/lldb/include/lldb/Symbol/SymbolFile.h
index 74ce1f7f82a04..e6ba4c7227ec9 100644
--- a/lldb/include/lldb/Symbol/SymbolFile.h
+++ b/lldb/include/lldb/Symbol/SymbolFile.h
@@ -310,7 +310,7 @@ class SymbolFile : public PluginInterface {
 
   virtual void PreloadSymbols();
 
-  virtual llvm::Expected<lldb_private::TypeSystem &>
+  virtual llvm::Expected<lldb::TypeSystemSP>
   GetTypeSystemForLanguage(lldb::LanguageType language) = 0;
 
   virtual CompilerDeclContext
@@ -465,7 +465,7 @@ class SymbolFileCommon : public SymbolFile {
   uint32_t GetNumCompileUnits() override;
   lldb::CompUnitSP GetCompileUnitAtIndex(uint32_t idx) override;
 
-  llvm::Expected<lldb_private::TypeSystem &>
+  llvm::Expected<lldb::TypeSystemSP>
   GetTypeSystemForLanguage(lldb::LanguageType language) override;
 
   void Dump(Stream &s) override;

diff  --git a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
index a215c7e32b26a..a0c8b2d734251 100644
--- a/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
+++ b/lldb/include/lldb/Symbol/SymbolFileOnDemand.h
@@ -167,7 +167,7 @@ class SymbolFileOnDemand : public lldb_private::SymbolFile {
                 lldb::TypeClass type_mask,
                 lldb_private::TypeList &type_list) override;
 
-  llvm::Expected<lldb_private::TypeSystem &>
+  llvm::Expected<lldb::TypeSystemSP>
   GetTypeSystemForLanguage(lldb::LanguageType language) override;
 
   lldb_private::CompilerDeclContext FindNamespace(

diff  --git a/lldb/include/lldb/Symbol/TaggedASTType.h b/lldb/include/lldb/Symbol/TaggedASTType.h
index fe1a2c659d9fd..e46cf1b474286 100644
--- a/lldb/include/lldb/Symbol/TaggedASTType.h
+++ b/lldb/include/lldb/Symbol/TaggedASTType.h
@@ -20,7 +20,8 @@ template <unsigned int C> class TaggedASTType : public CompilerType {
   TaggedASTType(const CompilerType &compiler_type)
       : CompilerType(compiler_type) {}
 
-  TaggedASTType(lldb::opaque_compiler_type_t type, TypeSystem *type_system)
+  TaggedASTType(lldb::opaque_compiler_type_t type,
+                lldb::TypeSystemWP type_system)
       : CompilerType(type_system, type) {}
 
   TaggedASTType(const TaggedASTType<C> &tw) : CompilerType(tw) {}

diff  --git a/lldb/include/lldb/Symbol/Type.h b/lldb/include/lldb/Symbol/Type.h
index fd4577028faaa..1b0e608ca88c3 100644
--- a/lldb/include/lldb/Symbol/Type.h
+++ b/lldb/include/lldb/Symbol/Type.h
@@ -297,7 +297,7 @@ class TypeImpl {
 
   CompilerType GetCompilerType(bool prefer_dynamic);
 
-  TypeSystem *GetTypeSystem(bool prefer_dynamic);
+  CompilerType::TypeSystemSPWrapper GetTypeSystem(bool prefer_dynamic);
 
   bool GetDescription(lldb_private::Stream &strm,
                       lldb::DescriptionLevel description_level);

diff  --git a/lldb/include/lldb/Symbol/TypeSystem.h b/lldb/include/lldb/Symbol/TypeSystem.h
index 0da0e35a4f9ca..5c074e9f797dc 100644
--- a/lldb/include/lldb/Symbol/TypeSystem.h
+++ b/lldb/include/lldb/Symbol/TypeSystem.h
@@ -10,12 +10,12 @@
 #define LLDB_SYMBOL_TYPESYSTEM_H
 
 #include <functional>
-#include <map>
 #include <mutex>
 #include <string>
 
 #include "llvm/ADT/APFloat.h"
 #include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallBitVector.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Error.h"
@@ -72,7 +72,8 @@ struct LanguageSet {
 /// \see lldb_private::CompilerType
 /// \see lldb_private::CompilerDecl
 /// \see lldb_private::CompilerDeclContext
-class TypeSystem : public PluginInterface {
+class TypeSystem : public PluginInterface,
+                   public std::enable_shared_from_this<TypeSystem> {
 public:
   // Constructors and Destructors
   ~TypeSystem() override;
@@ -86,10 +87,10 @@ class TypeSystem : public PluginInterface {
   static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language,
                                            Target *target);
 
-  // Free up any resources associated with this TypeSystem.  Done before
-  // removing all the TypeSystems from the TypeSystemMap.
+  /// Free up any resources associated with this TypeSystem.  Done before
+  /// removing all the TypeSystems from the TypeSystemMap.
   virtual void Finalize() {}
-
+ 
   virtual DWARFASTParser *GetDWARFParser() { return nullptr; }
   virtual PDBASTParser *GetPDBParser() { return nullptr; }
   virtual npdb::PdbAstBuilder *GetNativePDBParser() { return nullptr; }
@@ -526,39 +527,41 @@ class TypeSystemMap {
 
   // Iterate through all of the type systems that are created. Return true from
   // callback to keep iterating, false to stop iterating.
-  void ForEach(std::function<bool(TypeSystem *)> const &callback);
+  void ForEach(std::function<bool(lldb::TypeSystemSP)> const &callback);
 
-  llvm::Expected<TypeSystem &>
+  llvm::Expected<lldb::TypeSystemSP>
   GetTypeSystemForLanguage(lldb::LanguageType language, Module *module,
                            bool can_create);
 
-  llvm::Expected<TypeSystem &>
+  llvm::Expected<lldb::TypeSystemSP>
   GetTypeSystemForLanguage(lldb::LanguageType language, Target *target,
                            bool can_create);
 
 protected:
-  typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> collection;
+  typedef llvm::DenseMap<uint16_t, lldb::TypeSystemSP> collection;
   mutable std::mutex m_mutex; ///< A mutex to keep this object happy in
-                              ///multi-threaded environments.
+                              /// multi-threaded environments.
   collection m_map;
   bool m_clear_in_progress = false;
 
 private:
   typedef llvm::function_ref<lldb::TypeSystemSP()> CreateCallback;
   /// Finds the type system for the given language. If no type system could be
-  /// found for a language and a CreateCallback was provided, the value returned
-  /// by the callback will be treated as the TypeSystem for the language.
+  /// found for a language and a CreateCallback was provided, the value
+  /// returned by the callback will be treated as the TypeSystem for the
+  /// language.
   ///
   /// \param language The language for which the type system should be found.
   /// \param create_callback A callback that will be called if no previously
   ///                        created TypeSystem that fits the given language
   ///                        could found. Can be omitted if a non-existent
-  ///                        type system should be treated as an error instead.
+  ///                        type system should be treated as an error
+  ///                        instead.
   /// \return The found type system or an error.
-  llvm::Expected<TypeSystem &> GetTypeSystemForLanguage(
+  llvm::Expected<lldb::TypeSystemSP> GetTypeSystemForLanguage(
       lldb::LanguageType language,
       llvm::Optional<CreateCallback> create_callback = llvm::None);
-};
+  };
 
 } // namespace lldb_private
 

diff  --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h
index 9a03f23547d7b..b2f72cd644a87 100644
--- a/lldb/include/lldb/Target/Target.h
+++ b/lldb/include/lldb/Target/Target.h
@@ -1119,11 +1119,12 @@ class Target : public std::enable_shared_from_this<Target>,
 
   PathMappingList &GetImageSearchPathList();
 
-  llvm::Expected<TypeSystem &>
+  llvm::Expected<lldb::TypeSystemSP>
   GetScratchTypeSystemForLanguage(lldb::LanguageType language,
                                   bool create_on_demand = true);
 
-  std::vector<TypeSystem *> GetScratchTypeSystems(bool create_on_demand = true);
+  std::vector<lldb::TypeSystemSP>
+  GetScratchTypeSystems(bool create_on_demand = true);
 
   PersistentExpressionState *
   GetPersistentExpressionStateForLanguage(lldb::LanguageType language);

diff  --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h
index 3ba29a3013821..a5bd557112b37 100644
--- a/lldb/include/lldb/lldb-enumerations.h
+++ b/lldb/include/lldb/lldb-enumerations.h
@@ -9,6 +9,7 @@
 #ifndef LLDB_LLDB_ENUMERATIONS_H
 #define LLDB_LLDB_ENUMERATIONS_H
 
+#include <cstdint>
 #include <type_traits>
 
 #ifndef SWIG
@@ -433,7 +434,7 @@ FLAGS_ENUM(WatchpointEventType){
 /// specification for ease of use and consistency.
 /// The enum -> string code is in Language.cpp, don't change this
 /// table without updating that code as well.
-enum LanguageType {
+enum LanguageType : uint16_t {
   eLanguageTypeUnknown = 0x0000,        ///< Unknown or invalid language value.
   eLanguageTypeC89 = 0x0001,            ///< ISO C:1989.
   eLanguageTypeC = 0x0002,              ///< Non-standardized C, such as K&R.

diff  --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h
index 2fe6ac58be05c..5774645924e48 100644
--- a/lldb/include/lldb/lldb-forward.h
+++ b/lldb/include/lldb/lldb-forward.h
@@ -432,6 +432,7 @@ typedef std::shared_ptr<lldb_private::TypeMemberFunctionImpl>
 typedef std::shared_ptr<lldb_private::TypeEnumMemberImpl> TypeEnumMemberImplSP;
 typedef std::shared_ptr<lldb_private::TypeFilterImpl> TypeFilterImplSP;
 typedef std::shared_ptr<lldb_private::TypeSystem> TypeSystemSP;
+typedef std::weak_ptr<lldb_private::TypeSystem> TypeSystemWP;
 typedef std::shared_ptr<lldb_private::TypeFormatImpl> TypeFormatImplSP;
 typedef std::shared_ptr<lldb_private::TypeNameSpecifierImpl>
     TypeNameSpecifierImplSP;

diff  --git a/lldb/source/API/SBModule.cpp b/lldb/source/API/SBModule.cpp
index c4e876eb15de5..e7c2b451eb9d5 100644
--- a/lldb/source/API/SBModule.cpp
+++ b/lldb/source/API/SBModule.cpp
@@ -436,26 +436,28 @@ lldb::SBValue SBModule::FindFirstGlobalVariable(lldb::SBTarget &target,
 lldb::SBType SBModule::FindFirstType(const char *name_cstr) {
   LLDB_INSTRUMENT_VA(this, name_cstr);
 
-  SBType sb_type;
   ModuleSP module_sp(GetSP());
-  if (name_cstr && module_sp) {
-    SymbolContext sc;
-    const bool exact_match = false;
-    ConstString name(name_cstr);
+  if (!name_cstr || !module_sp)
+    return {};
+  SymbolContext sc;
+  const bool exact_match = false;
+  ConstString name(name_cstr);
 
-    sb_type = SBType(module_sp->FindFirstType(sc, name, exact_match));
+  SBType sb_type = SBType(module_sp->FindFirstType(sc, name, exact_match));
 
-    if (!sb_type.IsValid()) {
-      auto type_system_or_err =
-          module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
-      if (auto err = type_system_or_err.takeError()) {
-        llvm::consumeError(std::move(err));
-        return SBType();
-      }
-      sb_type = SBType(type_system_or_err->GetBuiltinTypeByName(name));
-    }
+  if (sb_type.IsValid())
+    return sb_type;
+
+  auto type_system_or_err = module_sp->GetTypeSystemForLanguage(eLanguageTypeC);
+  if (auto err = type_system_or_err.takeError()) {
+    llvm::consumeError(std::move(err));
+    return {};
   }
-  return sb_type;
+
+  if (auto ts = *type_system_or_err)
+    return SBType(ts->GetBuiltinTypeByName(name));
+
+  return {};
 }
 
 lldb::SBType SBModule::GetBasicType(lldb::BasicType type) {
@@ -468,7 +470,8 @@ lldb::SBType SBModule::GetBasicType(lldb::BasicType type) {
     if (auto err = type_system_or_err.takeError()) {
       llvm::consumeError(std::move(err));
     } else {
-      return SBType(type_system_or_err->GetBasicTypeFromAST(type));
+      if (auto ts = *type_system_or_err)
+        return SBType(ts->GetBasicTypeFromAST(type));              
     }
   }
   return SBType();
@@ -494,10 +497,9 @@ lldb::SBTypeList SBModule::FindTypes(const char *type) {
       if (auto err = type_system_or_err.takeError()) {
         llvm::consumeError(std::move(err));
       } else {
-        CompilerType compiler_type =
-            type_system_or_err->GetBuiltinTypeByName(name);
-        if (compiler_type)
-          retval.Append(SBType(compiler_type));
+        if (auto ts = *type_system_or_err)
+          if (CompilerType compiler_type = ts->GetBuiltinTypeByName(name))
+            retval.Append(SBType(compiler_type));
       }
     } else {
       for (size_t idx = 0; idx < type_list.GetSize(); idx++) {

diff  --git a/lldb/source/API/SBTarget.cpp b/lldb/source/API/SBTarget.cpp
index bf64bb342aafe..cadaeb472e289 100644
--- a/lldb/source/API/SBTarget.cpp
+++ b/lldb/source/API/SBTarget.cpp
@@ -1766,7 +1766,7 @@ lldb::SBType SBTarget::FindFirstType(const char *typename_cstr) {
       }
     }
 
-    // Didn't find the type in the symbols; Try the loaded language runtimes
+    // Didn't find the type in the symbols; Try the loaded language runtimes.
     if (auto process_sp = target_sp->GetProcessSP()) {
       for (auto *runtime : process_sp->GetLanguageRuntimes()) {
         if (auto vendor = runtime->GetDeclVendor()) {
@@ -1777,9 +1777,9 @@ lldb::SBType SBTarget::FindFirstType(const char *typename_cstr) {
       }
     }
 
-    // No matches, search for basic typename matches
-    for (auto *type_system : target_sp->GetScratchTypeSystems())
-      if (auto type = type_system->GetBuiltinTypeByName(const_typename))
+    // No matches, search for basic typename matches.
+    for (auto type_system_sp : target_sp->GetScratchTypeSystems())
+      if (auto type = type_system_sp->GetBuiltinTypeByName(const_typename))
         return SBType(type);
   }
 
@@ -1791,8 +1791,8 @@ SBType SBTarget::GetBasicType(lldb::BasicType type) {
 
   TargetSP target_sp(GetSP());
   if (target_sp) {
-    for (auto *type_system : target_sp->GetScratchTypeSystems())
-      if (auto compiler_type = type_system->GetBasicTypeFromAST(type))
+    for (auto type_system_sp : target_sp->GetScratchTypeSystems())
+      if (auto compiler_type = type_system_sp->GetBasicTypeFromAST(type))
         return SBType(compiler_type);
   }
   return SBType();
@@ -1832,9 +1832,9 @@ lldb::SBTypeList SBTarget::FindTypes(const char *typename_cstr) {
 
     if (sb_type_list.GetSize() == 0) {
       // No matches, search for basic typename matches
-      for (auto *type_system : target_sp->GetScratchTypeSystems())
+      for (auto type_system_sp : target_sp->GetScratchTypeSystems())
         if (auto compiler_type =
-                type_system->GetBuiltinTypeByName(const_typename))
+                type_system_sp->GetBuiltinTypeByName(const_typename))
           sb_type_list.Append(SBType(compiler_type));
     }
   }

diff  --git a/lldb/source/API/SBType.cpp b/lldb/source/API/SBType.cpp
index adc60a084367d..dc4c666b90362 100644
--- a/lldb/source/API/SBType.cpp
+++ b/lldb/source/API/SBType.cpp
@@ -28,9 +28,7 @@ using namespace lldb_private;
 
 SBType::SBType() { LLDB_INSTRUMENT_VA(this); }
 
-SBType::SBType(const CompilerType &type)
-    : m_opaque_sp(new TypeImpl(
-          CompilerType(type.GetTypeSystem(), type.GetOpaqueQualType()))) {}
+SBType::SBType(const CompilerType &type) : m_opaque_sp(new TypeImpl(type)) {}
 
 SBType::SBType(const lldb::TypeSP &type_sp)
     : m_opaque_sp(new TypeImpl(type_sp)) {}
@@ -364,8 +362,8 @@ SBType SBType::GetBasicType(lldb::BasicType basic_type) {
   LLDB_INSTRUMENT_VA(this, basic_type);
 
   if (IsValid() && m_opaque_sp->IsValid())
-    return SBType(
-        m_opaque_sp->GetTypeSystem(false)->GetBasicTypeFromAST(basic_type));
+    if (auto ts = m_opaque_sp->GetTypeSystem(false))
+      return SBType(ts->GetBasicTypeFromAST(basic_type));
   return SBType();
 }
 

diff  --git a/lldb/source/Breakpoint/Watchpoint.cpp b/lldb/source/Breakpoint/Watchpoint.cpp
index 933661ad7b156..0ad3498dac54c 100644
--- a/lldb/source/Breakpoint/Watchpoint.cpp
+++ b/lldb/source/Breakpoint/Watchpoint.cpp
@@ -43,8 +43,12 @@ Watchpoint::Watchpoint(Target &target, lldb::addr_t addr, uint32_t size,
       LLDB_LOG_ERROR(GetLog(LLDBLog::Watchpoints), std::move(err),
                      "Failed to set type.");
     } else {
-      m_type = type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
-          eEncodingUint, 8 * size);
+      if (auto ts = *type_system_or_err)
+        m_type =
+            ts->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 8 * size);
+      else
+        LLDB_LOG_ERROR(GetLog(LLDBLog::Watchpoints), std::move(err),
+                       "Failed to set type. Typesystem is no longer live.");
     }
   }
 

diff  --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 61ac468ec90d8..86fd994ebb12c 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -5093,8 +5093,9 @@ class CommandObjectTargetDumpTypesystem : public CommandObjectParsed {
 protected:
   bool DoExecute(Args &command, CommandReturnObject &result) override {
     // Go over every scratch TypeSystem and dump to the command output.
-    for (TypeSystem *ts : GetSelectedTarget().GetScratchTypeSystems())
-      ts->Dump(result.GetOutputStream().AsRawOstream());
+    for (lldb::TypeSystemSP ts : GetSelectedTarget().GetScratchTypeSystems())
+      if (ts)
+        ts->Dump(result.GetOutputStream().AsRawOstream());
 
     result.SetStatus(eReturnStatusSuccessFinishResult);
     return result.Succeeded();

diff  --git a/lldb/source/Core/DumpDataExtractor.cpp b/lldb/source/Core/DumpDataExtractor.cpp
index 0bf6722340fec..ec98d6266241e 100644
--- a/lldb/source/Core/DumpDataExtractor.cpp
+++ b/lldb/source/Core/DumpDataExtractor.cpp
@@ -320,11 +320,12 @@ printMemoryTags(const DataExtractor &DE, Stream *s, lldb::addr_t addr,
 static const llvm::fltSemantics &GetFloatSemantics(const TargetSP &target_sp,
                                                    size_t byte_size) {
   if (target_sp) {
-    if (auto type_system_or_err =
-            target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC))
-      return type_system_or_err->GetFloatTypeSemantics(byte_size);
-    else
+    auto type_system_or_err =
+      target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeC);
+    if (!type_system_or_err)
       llvm::consumeError(type_system_or_err.takeError());
+    else if (auto ts = *type_system_or_err)
+      return ts->GetFloatTypeSemantics(byte_size);
   }
   // No target, just make a reasonable guess
   switch(byte_size) {

diff  --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 20bd02f101fcc..b1cc0dd58211d 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -364,13 +364,13 @@ void Module::SetUUID(const lldb_private::UUID &uuid) {
   }
 }
 
-llvm::Expected<TypeSystem &>
+llvm::Expected<TypeSystemSP>
 Module::GetTypeSystemForLanguage(LanguageType language) {
   return m_type_system_map.GetTypeSystemForLanguage(language, this, true);
 }
 
 void Module::ForEachTypeSystem(
-    llvm::function_ref<bool(TypeSystem *)> callback) {
+    llvm::function_ref<bool(lldb::TypeSystemSP)> callback) {
   m_type_system_map.ForEach(callback);
 }
 

diff  --git a/lldb/source/Core/ValueObjectMemory.cpp b/lldb/source/Core/ValueObjectMemory.cpp
index af039ee4040b8..b20e68dc1ac5b 100644
--- a/lldb/source/Core/ValueObjectMemory.cpp
+++ b/lldb/source/Core/ValueObjectMemory.cpp
@@ -83,8 +83,7 @@ ValueObjectMemory::ValueObjectMemory(ExecutionContextScope *exe_scope,
     : ValueObject(exe_scope, manager), m_address(address), m_type_sp(),
       m_compiler_type(ast_type) {
   // Do not attempt to construct one of these objects with no variable!
-  assert(m_compiler_type.GetTypeSystem());
-  assert(m_compiler_type.GetOpaqueQualType());
+  assert(m_compiler_type.IsValid());
 
   TargetSP target_sp(GetTargetSP());
 

diff  --git a/lldb/source/Core/ValueObjectRegister.cpp b/lldb/source/Core/ValueObjectRegister.cpp
index 98fbbd62c6a78..4e91e4a036443 100644
--- a/lldb/source/Core/ValueObjectRegister.cpp
+++ b/lldb/source/Core/ValueObjectRegister.cpp
@@ -206,9 +206,9 @@ CompilerType ValueObjectRegister::GetCompilerTypeImpl() {
           LLDB_LOG_ERROR(GetLog(LLDBLog::Types), std::move(err),
                          "Unable to get CompilerType from TypeSystem");
         } else {
-          m_compiler_type =
-              type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
-                  m_reg_info.encoding, m_reg_info.byte_size * 8);
+          if (auto ts = *type_system_or_err)
+            m_compiler_type = ts->GetBuiltinTypeForEncodingAndBitSize(
+                m_reg_info.encoding, m_reg_info.byte_size * 8);
         }
       }
     }

diff  --git a/lldb/source/DataFormatters/VectorType.cpp b/lldb/source/DataFormatters/VectorType.cpp
index e35ed881db08e..20b2f3a895851 100644
--- a/lldb/source/DataFormatters/VectorType.cpp
+++ b/lldb/source/DataFormatters/VectorType.cpp
@@ -23,8 +23,10 @@ using namespace lldb_private::formatters;
 
 static CompilerType GetCompilerTypeForFormat(lldb::Format format,
                                              CompilerType element_type,
-                                             TypeSystem *type_system) {
+                                             TypeSystemSP type_system) {
   lldbassert(type_system && "type_system needs to be not NULL");
+  if (!type_system)
+    return {};
 
   switch (format) {
   case lldb::eFormatAddressInfo:
@@ -219,8 +221,9 @@ class VectorTypeSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
     CompilerType parent_type(m_backend.GetCompilerType());
     CompilerType element_type;
     parent_type.IsVectorType(&element_type);
-    m_child_type = ::GetCompilerTypeForFormat(m_parent_format, element_type,
-                                              parent_type.GetTypeSystem());
+    m_child_type = ::GetCompilerTypeForFormat(
+        m_parent_format, element_type,
+        parent_type.GetTypeSystem().GetSharedPointer());
     m_num_children = ::CalculateNumChildren(parent_type, m_child_type);
     m_item_format = GetItemFormatForFormat(m_parent_format, m_child_type);
     return false;

diff  --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp
index 946ae10d69c28..926d4af05f617 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -1023,8 +1023,15 @@ class EntityResultVariable : public Materializer::Entity {
                                    llvm::toString(std::move(error)).c_str());
       return;
     }
+    auto ts = *type_system_or_err;
+    if (!ts) {
+      err.SetErrorStringWithFormat("Couldn't dematerialize a result variable: "
+                                   "couldn't corresponding type system is "
+                                   "no longer live.");
+      return;
+    }
     PersistentExpressionState *persistent_state =
-        type_system_or_err->GetPersistentExpressionState();
+        ts->GetPersistentExpressionState();
 
     if (!persistent_state) {
       err.SetErrorString("Couldn't dematerialize a result variable: "

diff  --git a/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp b/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
index 5441432d74089..4d67429e8cd43 100644
--- a/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
+++ b/lldb/source/Plugins/ABI/PowerPC/ABISysV_ppc64.cpp
@@ -809,8 +809,7 @@ class ReturnValueExtractor {
     // case 3: get from GPRs
 
     // first, check if this is a packed struct or not
-    TypeSystemClang *ast =
-        llvm::dyn_cast<TypeSystemClang>(m_type.GetTypeSystem());
+    auto ast = m_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
     if (ast) {
       clang::RecordDecl *record_decl = TypeSystemClang::GetAsRecordDecl(m_type);
 

diff  --git a/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp b/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
index 0ced71eafd268..30ba463a81009 100644
--- a/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
+++ b/lldb/source/Plugins/ABI/X86/ABISysV_x86_64.cpp
@@ -638,12 +638,12 @@ ValueObjectSP ABISysV_x86_64::GetReturnValueObjectImpl(
     bool is_memory = true;
     std::vector<uint32_t> aggregate_field_offsets;
     std::vector<CompilerType> aggregate_compiler_types;
-    if (return_compiler_type.GetTypeSystem()->CanPassInRegisters(
-          return_compiler_type) &&
-      *bit_width <= 128 &&
-      FlattenAggregateType(thread, exe_ctx, return_compiler_type,
-                          0, aggregate_field_offsets,
-                          aggregate_compiler_types)) {
+    auto ts = return_compiler_type.GetTypeSystem();
+    if (ts && ts->CanPassInRegisters(return_compiler_type) &&
+        *bit_width <= 128 &&
+        FlattenAggregateType(thread, exe_ctx, return_compiler_type, 0,
+                             aggregate_field_offsets,
+                             aggregate_compiler_types)) {
       ByteOrder byte_order = target->GetArchitecture().GetByteOrder();
       WritableDataBufferSP data_sp(new DataBufferHeap(16, 0));
       DataExtractor return_ext(data_sp, byte_order,

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
index 9ef3c3671abf6..e945601a41f60 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTImporter.cpp
@@ -33,8 +33,7 @@ CompilerType ClangASTImporter::CopyType(TypeSystemClang &dst_ast,
                                         const CompilerType &src_type) {
   clang::ASTContext &dst_clang_ast = dst_ast.getASTContext();
 
-  TypeSystemClang *src_ast =
-      llvm::dyn_cast_or_null<TypeSystemClang>(src_type.GetTypeSystem());
+  auto src_ast = src_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
   if (!src_ast)
     return CompilerType();
 
@@ -59,7 +58,7 @@ CompilerType ClangASTImporter::CopyType(TypeSystemClang &dst_ast,
   lldb::opaque_compiler_type_t dst_clang_type = ret_or_error->getAsOpaquePtr();
 
   if (dst_clang_type)
-    return CompilerType(&dst_ast, dst_clang_type);
+    return CompilerType(dst_ast.weak_from_this(), dst_clang_type);
   return CompilerType();
 }
 
@@ -305,8 +304,9 @@ CompilerType ClangASTImporter::DeportType(TypeSystemClang &dst,
                                           const CompilerType &src_type) {
   Log *log = GetLog(LLDBLog::Expressions);
 
-  TypeSystemClang *src_ctxt =
-      llvm::cast<TypeSystemClang>(src_type.GetTypeSystem());
+  auto src_ctxt = src_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
+  if (!src_ctxt)
+    return {};
 
   LLDB_LOG(log,
            "    [ClangASTImporter] DeportType called on ({0}Type*){1} "

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
index 3187146b9ba5c..f50d52a910659 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangASTSource.cpp
@@ -1733,10 +1733,10 @@ ClangASTImporter::DeclOrigin ClangASTSource::GetDeclOrigin(const clang::Decl *de
 }
 
 CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
-  TypeSystemClang *src_ast =
-      llvm::dyn_cast_or_null<TypeSystemClang>(src_type.GetTypeSystem());
-  if (src_ast == nullptr)
-    return CompilerType();
+  auto ts = src_type.GetTypeSystem();
+  auto src_ast = ts.dyn_cast_or_null<TypeSystemClang>();
+  if (!src_ast)
+    return {};
 
   QualType copied_qual_type = ClangUtil::GetQualType(
       m_ast_importer_sp->CopyType(*m_clang_ast_context, src_type));
@@ -1745,7 +1745,7 @@ CompilerType ClangASTSource::GuardedCopyType(const CompilerType &src_type) {
       copied_qual_type->getCanonicalTypeInternal().isNull())
     // this shouldn't happen, but we're hardening because the AST importer
     // seems to be generating bad types on occasion.
-    return CompilerType();
+    return {};
 
   return m_clang_ast_context->GetType(copied_qual_type);
 }

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
index aca7d81bb67fd..4df9c3015c73c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionDeclMap.cpp
@@ -206,7 +206,8 @@ TypeFromUser ClangExpressionDeclMap::DeportType(TypeSystemClang &target,
                                                 TypeSystemClang &source,
                                                 TypeFromParser parser_type) {
   assert(&target == GetScratchContext(*m_target));
-  assert((TypeSystem *)&source == parser_type.GetTypeSystem());
+  assert((TypeSystem *)&source ==
+         parser_type.GetTypeSystem().GetSharedPointer().get());
   assert(&source.getASTContext() == m_ast_context);
 
   return TypeFromUser(m_ast_importer_sp->DeportType(target, parser_type));
@@ -218,9 +219,7 @@ bool ClangExpressionDeclMap::AddPersistentVariable(const NamedDecl *decl,
                                                    bool is_result,
                                                    bool is_lvalue) {
   assert(m_parser_vars.get());
-
-  TypeSystemClang *ast =
-      llvm::dyn_cast_or_null<TypeSystemClang>(parser_type.GetTypeSystem());
+  auto ast = parser_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
   if (ast == nullptr)
     return false;
 
@@ -847,8 +846,9 @@ void ClangExpressionDeclMap::LookUpLldbClass(NameSearchContext &context) {
 
     QualType class_qual_type(class_decl->getTypeForDecl(), 0);
 
-    TypeFromUser class_user_type(class_qual_type.getAsOpaquePtr(),
-                                 function_decl_ctx.GetTypeSystem());
+    TypeFromUser class_user_type(
+        class_qual_type.getAsOpaquePtr(),
+        function_decl_ctx.GetTypeSystem()->weak_from_this());
 
     LLDB_LOG(log, "  CEDM::FEVD Adding type for $__lldb_class: {0}",
              class_qual_type.getAsString());
@@ -936,8 +936,9 @@ void ClangExpressionDeclMap::LookUpLldbObjCClass(NameSearchContext &context) {
       return; // This is unlikely, but we have seen crashes where this
               // occurred
 
-    TypeFromUser class_user_type(QualType(interface_type, 0).getAsOpaquePtr(),
-                                 function_decl_ctx.GetTypeSystem());
+    TypeFromUser class_user_type(
+        QualType(interface_type, 0).getAsOpaquePtr(),
+        function_decl_ctx.GetTypeSystem()->weak_from_this());
 
     LLDB_LOG(log, "  FEVD[{0}] Adding type for $__lldb_objc_class: {1}",
              ClangUtil::ToString(interface_type));
@@ -1501,8 +1502,8 @@ bool ClangExpressionDeclMap::GetVariableValue(VariableSP &var,
     return false;
   }
 
-  TypeSystemClang *clang_ast = llvm::dyn_cast_or_null<TypeSystemClang>(
-      var_type->GetForwardCompilerType().GetTypeSystem());
+  auto ts = var_type->GetForwardCompilerType().GetTypeSystem();
+  auto clang_ast = ts.dyn_cast_or_null<TypeSystemClang>();
 
   if (!clang_ast) {
     LLDB_LOG(log, "Skipped a definition because it has no Clang AST");
@@ -1621,8 +1622,8 @@ void ClangExpressionDeclMap::AddOneVariable(
 
   TypeFromUser user_type = valobj->GetCompilerType();
 
-  TypeSystemClang *clang_ast =
-      llvm::dyn_cast_or_null<TypeSystemClang>(user_type.GetTypeSystem());
+  auto clang_ast =
+      user_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
 
   if (!clang_ast) {
     LLDB_LOG(log, "Skipped a definition because it has no Clang AST");

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
index 1273acf454d18..84ce21f5ddd1e 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.cpp
@@ -701,7 +701,7 @@ ClangExpressionParser::ClangExpressionParser(
   m_compiler->createASTContext();
   clang::ASTContext &ast_context = m_compiler->getASTContext();
 
-  m_ast_context = std::make_unique<TypeSystemClang>(
+  m_ast_context = std::make_shared<TypeSystemClang>(
       "Expression ASTContext for '" + m_filename + "'", ast_context);
 
   std::string module_name("$__lldb_module");

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
index 6afee22da8d14..185a5a381f23c 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangExpressionParser.h
@@ -177,7 +177,7 @@ class ClangExpressionParser : public ExpressionParser {
   class LLDBPreprocessorCallbacks;
   LLDBPreprocessorCallbacks *m_pp_callbacks; ///< Called when the preprocessor
                                              ///encounters module imports
-  std::unique_ptr<TypeSystemClang> m_ast_context;
+  std::shared_ptr<TypeSystemClang> m_ast_context;
 
   std::vector<std::string> m_include_directories;
   /// File name used for the user expression.

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
index 9ab3b647332dc..ec4e9f12fc974 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangModulesDeclVendor.cpp
@@ -125,7 +125,7 @@ class ClangModulesDeclVendorImpl : public ClangModulesDeclVendor {
   ImportedModuleSet m_user_imported_modules;
   // We assume that every ASTContext has an TypeSystemClang, so we also store
   // a custom TypeSystemClang for our internal ASTContext.
-  std::unique_ptr<TypeSystemClang> m_ast_context;
+  std::shared_ptr<TypeSystemClang> m_ast_context;
 };
 } // anonymous namespace
 
@@ -190,7 +190,7 @@ ClangModulesDeclVendorImpl::ClangModulesDeclVendorImpl(
 
   // Initialize our TypeSystemClang.
   m_ast_context =
-      std::make_unique<TypeSystemClang>("ClangModulesDeclVendor ASTContext",
+      std::make_shared<TypeSystemClang>("ClangModulesDeclVendor ASTContext",
                                         m_compiler_instance->getASTContext());
 }
 

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
index 13d6a37113b86..93a33edfae956 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
@@ -87,12 +87,12 @@ ClangPersistentVariables::GetCompilerTypeFromPersistentDecl(
 void ClangPersistentVariables::RegisterPersistentDecl(ConstString name,
                                                       clang::NamedDecl *decl,
                                                       TypeSystemClang *ctx) {
-  PersistentDecl p = {decl, ctx};
+  PersistentDecl p = {decl, ctx->weak_from_this()};
   m_persistent_decls.insert(std::make_pair(name.GetCString(), p));
 
   if (clang::EnumDecl *enum_decl = llvm::dyn_cast<clang::EnumDecl>(decl)) {
     for (clang::EnumConstantDecl *enumerator_decl : enum_decl->enumerators()) {
-      p = {enumerator_decl, ctx};
+      p = {enumerator_decl, ctx->weak_from_this()};
       m_persistent_decls.insert(std::make_pair(
           ConstString(enumerator_decl->getNameAsString()).GetCString(), p));
     }

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
index b8a359d05f75b..cc96fc71e6b26 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
@@ -97,7 +97,7 @@ class ClangPersistentVariables : public PersistentExpressionState {
     /// The persistent decl.
     clang::NamedDecl *m_decl = nullptr;
     /// The TypeSystemClang for the ASTContext of m_decl.
-    TypeSystemClang *m_context = nullptr;
+    lldb::TypeSystemWP m_context;
   };
 
   typedef llvm::DenseMap<const char *, PersistentDecl> PersistentDeclMap;

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp
index a7f5dce8558f1..2e0bb318cb507 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/ClangUtil.cpp
@@ -19,7 +19,7 @@ bool ClangUtil::IsClangType(const CompilerType &ct) {
   if (!ct)
     return false;
 
-  if (llvm::dyn_cast_or_null<TypeSystemClang>(ct.GetTypeSystem()) == nullptr)
+  if (!ct.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>())
     return false;
 
   if (!ct.GetOpaqueQualType())

diff  --git a/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
index a672045dfe314..a67cc8e10c175 100644
--- a/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
+++ b/lldb/source/Plugins/ExpressionParser/Clang/NameSearchContext.cpp
@@ -19,8 +19,7 @@ clang::NamedDecl *NameSearchContext::AddVarDecl(const CompilerType &type) {
   if (!type.IsValid())
     return nullptr;
 
-  TypeSystemClang *lldb_ast =
-      llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+  auto lldb_ast = type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
   if (!lldb_ast)
     return nullptr;
 
@@ -46,8 +45,7 @@ clang::NamedDecl *NameSearchContext::AddFunDecl(const CompilerType &type,
   if (m_function_types.count(type))
     return nullptr;
 
-  TypeSystemClang *lldb_ast =
-      llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+  auto lldb_ast = type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
   if (!lldb_ast)
     return nullptr;
 

diff  --git a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
index 1b3cf1ec09878..40ffe96737926 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -49,8 +49,10 @@ class BlockPointerSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
       return;
     }
 
-    TypeSystemClang *clang_ast_context =
-        llvm::cast<TypeSystemClang>(block_pointer_type.GetTypeSystem());
+    auto ts = block_pointer_type.GetTypeSystem();
+    auto clang_ast_context = ts.dyn_cast_or_null<TypeSystemClang>();
+    if (!clang_ast_context)
+      return;
 
     std::shared_ptr<ClangASTImporter> clang_ast_importer;
     auto *state = target_sp->GetPersistentExpressionStateForLanguage(

diff  --git a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
index 5427a7a2b7850..de5d1831c01ef 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/Coroutines.cpp
@@ -100,8 +100,8 @@ bool lldb_private::formatters::StdlibCoroutineHandleSyntheticFrontEnd::
   if (!ptr_sp)
     return false;
 
-  TypeSystemClang *ast_ctx = llvm::dyn_cast_or_null<TypeSystemClang>(
-      valobj_sp->GetCompilerType().GetTypeSystem());
+  auto ts = valobj_sp->GetCompilerType().GetTypeSystem();
+  auto ast_ctx = ts.dyn_cast_or_null<TypeSystemClang>();
   if (!ast_ctx)
     return false;
 

diff  --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index 2480dbf8a2a60..96c54834e24a9 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -291,8 +291,8 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
       auto addr(m_pair_ptr->GetValueAsUnsigned(LLDB_INVALID_ADDRESS));
       m_pair_ptr = nullptr;
       if (addr && addr != LLDB_INVALID_ADDRESS) {
-        TypeSystemClang *ast_ctx =
-            llvm::dyn_cast_or_null<TypeSystemClang>(pair_type.GetTypeSystem());
+        auto ts = pair_type.GetTypeSystem();
+        auto ast_ctx = ts.dyn_cast_or_null<TypeSystemClang>();
         if (!ast_ctx)
           return false;
 
@@ -460,8 +460,8 @@ bool lldb_private::formatters::LibCxxUnorderedMapIteratorSyntheticFrontEnd::
     if (addr == 0 || addr == LLDB_INVALID_ADDRESS)
       return false;
 
-    TypeSystemClang *ast_ctx =
-        llvm::dyn_cast_or_null<TypeSystemClang>(pair_type.GetTypeSystem());
+    auto ts = pair_type.GetTypeSystem();
+    auto ast_ctx = ts.dyn_cast_or_null<TypeSystemClang>();
     if (!ast_ctx)
       return false;
 

diff  --git a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index 04033df282b76..bf6c65c8d9c22 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -249,7 +249,7 @@ bool lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetDataType() {
   static ConstString g_tree_("__tree_");
   static ConstString g_pair3("__pair3_");
 
-  if (m_element_type.GetOpaqueQualType() && m_element_type.GetTypeSystem())
+  if (m_element_type.IsValid())
     return true;
   m_element_type.Clear();
   ValueObjectSP deref;
@@ -295,8 +295,7 @@ void lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetValueOffset(
       UINT32_MAX) {
     m_skip_size = bit_offset / 8u;
   } else {
-    TypeSystemClang *ast_ctx =
-        llvm::dyn_cast_or_null<TypeSystemClang>(node_type.GetTypeSystem());
+    auto ast_ctx = node_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
     if (!ast_ctx)
       return;
     CompilerType tree_node_type = ast_ctx->CreateStructForIdentifier(

diff  --git a/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp b/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
index 4b7fad08f00c2..1f4991bbfda28 100644
--- a/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
+++ b/lldb/source/Plugins/Language/ObjC/CoreMedia.cpp
@@ -25,7 +25,9 @@ bool lldb_private::formatters::CMTimeSummaryProvider(
   if (!type.IsValid())
     return false;
 
-  TypeSystem *type_system = type.GetTypeSystem();
+  auto type_system = type.GetTypeSystem();
+  if (!type_system)
+    return false;
   // fetch children by offset to compensate for potential lack of debug info
   auto int64_ty =
       type_system->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 64);

diff  --git a/lldb/source/Plugins/Language/ObjC/NSArray.cpp b/lldb/source/Plugins/Language/ObjC/NSArray.cpp
index 876efda9b988f..9b6f6851b2a87 100644
--- a/lldb/source/Plugins/Language/ObjC/NSArray.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSArray.cpp
@@ -467,7 +467,7 @@ lldb_private::formatters::NSArrayMSyntheticFrontEndBase::
         *valobj_sp->GetExecutionContextRef().GetTargetSP());
     if (clang_ast_context)
       m_id_type = CompilerType(
-          clang_ast_context,
+          clang_ast_context->weak_from_this(),
           clang_ast_context->getASTContext().ObjCBuiltinIdTy.getAsOpaquePtr());
     if (valobj_sp->GetProcessSP())
       m_ptr_size = valobj_sp->GetProcessSP()->GetAddressByteSize();

diff  --git a/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp b/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
index 429633e5e6b87..062115757d856 100644
--- a/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
+++ b/lldb/source/Plugins/Language/ObjC/NSIndexPath.cpp
@@ -49,7 +49,7 @@ class NSIndexPathSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
   bool Update() override {
     m_impl.Clear();
 
-    TypeSystem *type_system = m_backend.GetCompilerType().GetTypeSystem();
+    auto type_system = m_backend.GetCompilerType().GetTypeSystem();
     if (!type_system)
       return false;
 

diff  --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
index 5f3ae3b129758..4d6c86f7d28ce 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.cpp
@@ -120,7 +120,7 @@ class lldb_private::AppleObjCExternalASTSource
 
   void StartTranslationUnit(clang::ASTConsumer *Consumer) override {
     clang::TranslationUnitDecl *translation_unit_decl =
-        m_decl_vendor.m_ast_ctx.getASTContext().getTranslationUnitDecl();
+        m_decl_vendor.m_ast_ctx->getASTContext().getTranslationUnitDecl();
     translation_unit_decl->setHasExternalVisibleStorage();
     translation_unit_decl->setHasExternalLexicalStorage();
   }
@@ -131,14 +131,14 @@ class lldb_private::AppleObjCExternalASTSource
 
 AppleObjCDeclVendor::AppleObjCDeclVendor(ObjCLanguageRuntime &runtime)
     : ClangDeclVendor(eAppleObjCDeclVendor), m_runtime(runtime),
-      m_ast_ctx(
-          "AppleObjCDeclVendor AST",
-          runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple()),
       m_type_realizer_sp(m_runtime.GetEncodingToType()) {
+  m_ast_ctx = std::make_shared<TypeSystemClang>(
+      "AppleObjCDeclVendor AST",
+      runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple());
   m_external_source = new AppleObjCExternalASTSource(*this);
   llvm::IntrusiveRefCntPtr<clang::ExternalASTSource> external_source_owning_ptr(
       m_external_source);
-  m_ast_ctx.getASTContext().setExternalSource(external_source_owning_ptr);
+  m_ast_ctx->getASTContext().setExternalSource(external_source_owning_ptr);
 }
 
 clang::ObjCInterfaceDecl *
@@ -148,7 +148,7 @@ AppleObjCDeclVendor::GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa) {
   if (iter != m_isa_to_interface.end())
     return iter->second;
 
-  clang::ASTContext &ast_ctx = m_ast_ctx.getASTContext();
+  clang::ASTContext &ast_ctx = m_ast_ctx->getASTContext();
 
   ObjCLanguageRuntime::ClassDescriptorSP descriptor =
       m_runtime.GetClassDescriptorFromISA(isa);
@@ -167,7 +167,7 @@ AppleObjCDeclVendor::GetDeclForISA(ObjCLanguageRuntime::ObjCISA isa) {
 
   ClangASTMetadata meta_data;
   meta_data.SetISAPtr(isa);
-  m_ast_ctx.SetMetadata(new_iface_decl, meta_data);
+  m_ast_ctx->SetMetadata(new_iface_decl, meta_data);
 
   new_iface_decl->setHasExternalVisibleStorage();
   new_iface_decl->setHasExternalLexicalStorage();
@@ -398,7 +398,7 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
   Log *log(
       GetLog(LLDBLog::Expressions)); // FIXME - a more appropriate log channel?
 
-  ClangASTMetadata *metadata = m_ast_ctx.GetMetadata(interface_decl);
+  ClangASTMetadata *metadata = m_ast_ctx->GetMetadata(interface_decl);
   ObjCLanguageRuntime::ObjCISA objc_isa = 0;
   if (metadata)
     objc_isa = metadata->GetISAPtr();
@@ -428,7 +428,7 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
       return;
 
     FinishDecl(superclass_decl);
-    clang::ASTContext &context = m_ast_ctx.getASTContext();
+    clang::ASTContext &context = m_ast_ctx->getASTContext();
     interface_decl->setSuperClass(context.getTrivialTypeSourceInfo(
         context.getObjCInterfaceType(superclass_decl)));
   };
@@ -441,7 +441,7 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
     ObjCRuntimeMethodType method_type(types);
 
     clang::ObjCMethodDecl *method_decl = method_type.BuildMethod(
-        m_ast_ctx, interface_decl, name, true, m_type_realizer_sp);
+        *m_ast_ctx, interface_decl, name, true, m_type_realizer_sp);
 
     LLDB_LOGF(log, "[  AOTV::FD] Instance method [%s] [%s]", name, types);
 
@@ -459,7 +459,7 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
     ObjCRuntimeMethodType method_type(types);
 
     clang::ObjCMethodDecl *method_decl = method_type.BuildMethod(
-        m_ast_ctx, interface_decl, name, false, m_type_realizer_sp);
+        *m_ast_ctx, interface_decl, name, false, m_type_realizer_sp);
 
     LLDB_LOGF(log, "[  AOTV::FD] Class method [%s] [%s]", name, types);
 
@@ -482,14 +482,14 @@ bool AppleObjCDeclVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl) {
               name, type, offset_ptr);
 
     CompilerType ivar_type = m_runtime.GetEncodingToType()->RealizeType(
-        m_ast_ctx, type, for_expression);
+        *m_ast_ctx, type, for_expression);
 
     if (ivar_type.IsValid()) {
       clang::TypeSourceInfo *const type_source_info = nullptr;
       const bool is_synthesized = false;
       clang::ObjCIvarDecl *ivar_decl = clang::ObjCIvarDecl::Create(
-          m_ast_ctx.getASTContext(), interface_decl, clang::SourceLocation(),
-          clang::SourceLocation(), &m_ast_ctx.getASTContext().Idents.get(name),
+          m_ast_ctx->getASTContext(), interface_decl, clang::SourceLocation(),
+          clang::SourceLocation(), &m_ast_ctx->getASTContext().Idents.get(name),
           ClangUtil::GetQualType(ivar_type),
           type_source_info, // TypeSourceInfo *
           clang::ObjCIvarDecl::Public, nullptr, is_synthesized);
@@ -541,7 +541,7 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
   do {
     // See if the type is already in our ASTContext.
 
-    clang::ASTContext &ast_ctx = m_ast_ctx.getASTContext();
+    clang::ASTContext &ast_ctx = m_ast_ctx->getASTContext();
 
     clang::IdentifierInfo &identifier_info =
         ast_ctx.Idents.get(name.GetStringRef());
@@ -559,7 +559,7 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
               ast_ctx.getObjCInterfaceType(result_iface_decl);
 
           uint64_t isa_value = LLDB_INVALID_ADDRESS;
-          ClangASTMetadata *metadata = m_ast_ctx.GetMetadata(result_iface_decl);
+          ClangASTMetadata *metadata = m_ast_ctx->GetMetadata(result_iface_decl);
           if (metadata)
             isa_value = metadata->GetISAPtr();
 
@@ -568,7 +568,7 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
                    result_iface_type.getAsString(), isa_value);
         }
 
-        decls.push_back(m_ast_ctx.GetCompilerDecl(result_iface_decl));
+        decls.push_back(m_ast_ctx->GetCompilerDecl(result_iface_decl));
         ret++;
         break;
       } else {
@@ -609,7 +609,7 @@ uint32_t AppleObjCDeclVendor::FindDecls(ConstString name, bool append,
                new_iface_type.getAsString(), (uint64_t)isa);
     }
 
-    decls.push_back(m_ast_ctx.GetCompilerDecl(iface_decl));
+    decls.push_back(m_ast_ctx->GetCompilerDecl(iface_decl));
     ret++;
     break;
   } while (false);

diff  --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
index c1201b9858143..3bb0f77f6bde4 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCDeclVendor.h
@@ -37,7 +37,7 @@ class AppleObjCDeclVendor : public ClangDeclVendor {
   bool FinishDecl(clang::ObjCInterfaceDecl *decl);
 
   ObjCLanguageRuntime &m_runtime;
-  TypeSystemClang m_ast_ctx;
+  std::shared_ptr<TypeSystemClang> m_ast_ctx;
   ObjCLanguageRuntime::EncodingToTypeSP m_type_realizer_sp;
   AppleObjCExternalASTSource *m_external_source;
 

diff  --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
index 40a0ea3e97a48..9877263796232 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeEncodingParser.cpp
@@ -24,10 +24,12 @@ using namespace lldb_private;
 AppleObjCTypeEncodingParser::AppleObjCTypeEncodingParser(
     ObjCLanguageRuntime &runtime)
     : ObjCLanguageRuntime::EncodingToType(), m_runtime(runtime) {
-  if (!m_scratch_ast_ctx_up)
-    m_scratch_ast_ctx_up = std::make_unique<TypeSystemClang>(
-        "AppleObjCTypeEncodingParser ASTContext",
-        runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple());
+  if (m_scratch_ast_ctx_sp)
+    return;
+
+  m_scratch_ast_ctx_sp = std::make_shared<TypeSystemClang>(
+      "AppleObjCTypeEncodingParser ASTContext",
+      runtime.GetProcess()->GetTarget().GetArchitecture().GetTriple());
 }
 
 std::string AppleObjCTypeEncodingParser::ReadStructName(StringLexer &type) {
@@ -155,7 +157,8 @@ clang::QualType AppleObjCTypeEncodingParser::BuildArray(
   if (!type.NextIf(_C_ARY_E))
     return clang::QualType();
   CompilerType array_type(ast_ctx.CreateArrayType(
-      CompilerType(&ast_ctx, element_type.getAsOpaquePtr()), size, false));
+      CompilerType(ast_ctx.weak_from_this(), element_type.getAsOpaquePtr()),
+      size, false));
   return ClangUtil::GetQualType(array_type);
 }
 

diff  --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
index b387de38d3bf0..e2c3c17a946d8 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.cpp
@@ -330,8 +330,8 @@ ObjCLanguageRuntime::GetNonKVOClassDescriptor(ObjCISA isa) {
 CompilerType
 ObjCLanguageRuntime::EncodingToType::RealizeType(const char *name,
                                                  bool for_expression) {
-  if (m_scratch_ast_ctx_up)
-    return RealizeType(*m_scratch_ast_ctx_up, name, for_expression);
+  if (m_scratch_ast_ctx_sp)
+    return RealizeType(*m_scratch_ast_ctx_sp, name, for_expression);
   return CompilerType();
 }
 

diff  --git a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
index 9431b42502406..76561620b9d21 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/ObjCLanguageRuntime.h
@@ -158,7 +158,7 @@ class ObjCLanguageRuntime : public LanguageRuntime {
     virtual CompilerType RealizeType(const char *name, bool for_expression);
 
   protected:
-    std::unique_ptr<TypeSystemClang> m_scratch_ast_ctx_up;
+    std::shared_ptr<TypeSystemClang> m_scratch_ast_ctx_sp;
   };
 
   class ObjCExceptionPrecondition : public BreakpointPrecondition {

diff  --git a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
index 17c86a435aa8d..0c6831b77d875 100644
--- a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
+++ b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
@@ -187,9 +187,12 @@ MmapArgList PlatformFreeBSD::GetMmapArgumentList(const ArchSpec &arch,
 }
 
 CompilerType PlatformFreeBSD::GetSiginfoType(const llvm::Triple &triple) {
-  if (!m_type_system_up)
-    m_type_system_up.reset(new TypeSystemClang("siginfo", triple));
-  TypeSystemClang *ast = m_type_system_up.get();
+  {
+    std::lock_guard<std::mutex> guard(m_mutex);
+    if (!m_type_system)
+      m_type_system = std::make_shared<TypeSystemClang>("siginfo", triple);
+  }
+  TypeSystemClang *ast = m_type_system.get();
 
   // generic types
   CompilerType int_type = ast->GetBasicType(eBasicTypeInt);

diff  --git a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
index 4aeedb62931df..1e92bb4a1e147 100644
--- a/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
+++ b/lldb/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.h
@@ -60,7 +60,8 @@ class PlatformFreeBSD : public PlatformPOSIX {
   std::vector<ArchSpec> m_supported_architectures;
 
 private:
-  std::unique_ptr<TypeSystemClang> m_type_system_up;
+  std::mutex m_mutex;
+  std::shared_ptr<TypeSystemClang> m_type_system;
 };
 
 } // namespace platform_freebsd

diff  --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
index 9fdfe4c0dc140..bf226fabda5c9 100644
--- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
+++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.cpp
@@ -312,9 +312,12 @@ MmapArgList PlatformLinux::GetMmapArgumentList(const ArchSpec &arch,
 }
 
 CompilerType PlatformLinux::GetSiginfoType(const llvm::Triple &triple) {
-  if (!m_type_system_up)
-    m_type_system_up.reset(new TypeSystemClang("siginfo", triple));
-  TypeSystemClang *ast = m_type_system_up.get();
+  {
+    std::lock_guard<std::mutex> guard(m_mutex);
+    if (!m_type_system)
+      m_type_system = std::make_shared<TypeSystemClang>("siginfo", triple);
+  }
+  TypeSystemClang *ast = m_type_system.get();
 
   bool si_errno_then_code = true;
 

diff  --git a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h
index 26b53dbebd26b..89f0bd709ef60 100644
--- a/lldb/source/Plugins/Platform/Linux/PlatformLinux.h
+++ b/lldb/source/Plugins/Platform/Linux/PlatformLinux.h
@@ -65,7 +65,8 @@ class PlatformLinux : public PlatformPOSIX {
   std::vector<ArchSpec> m_supported_architectures;
 
 private:
-  std::unique_ptr<TypeSystemClang> m_type_system_up;
+  std::mutex m_mutex;
+  std::shared_ptr<TypeSystemClang> m_type_system;
 };
 
 } // namespace platform_linux

diff  --git a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
index d79fe664cb1c6..59bbc3f638af1 100644
--- a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
+++ b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.cpp
@@ -206,9 +206,12 @@ MmapArgList PlatformNetBSD::GetMmapArgumentList(const ArchSpec &arch,
 }
 
 CompilerType PlatformNetBSD::GetSiginfoType(const llvm::Triple &triple) {
-  if (!m_type_system_up)
-    m_type_system_up.reset(new TypeSystemClang("siginfo", triple));
-  TypeSystemClang *ast = m_type_system_up.get();
+  {
+    std::lock_guard<std::mutex> guard(m_mutex);
+    if (!m_type_system)
+      m_type_system = std::make_shared<TypeSystemClang>("siginfo", triple);
+  }
+  TypeSystemClang *ast = m_type_system.get();
 
   // generic types
   CompilerType int_type = ast->GetBasicType(eBasicTypeInt);

diff  --git a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
index 2613311790a34..3437d7e5eb511 100644
--- a/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
+++ b/lldb/source/Plugins/Platform/NetBSD/PlatformNetBSD.h
@@ -62,7 +62,8 @@ class PlatformNetBSD : public PlatformPOSIX {
   std::vector<ArchSpec> m_supported_architectures;
 
 private:
-  std::unique_ptr<TypeSystemClang> m_type_system_up;
+  std::mutex m_mutex;
+  std::shared_ptr<TypeSystemClang> m_type_system;
 };
 
 } // namespace platform_netbsd

diff  --git a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
index 5091f68a9acfe..0a1f34ec6b4e6 100644
--- a/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
+++ b/lldb/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
@@ -88,9 +88,11 @@ bool lldb_private::InferiorCallMmap(Process *process, addr_t &allocated_addr,
           llvm::consumeError(type_system_or_err.takeError());
           return false;
         }
+        auto ts = *type_system_or_err;
+        if (!ts)
+          return false;
         CompilerType void_ptr_type =
-            type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid)
-                .GetPointerType();
+            ts->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
         const ArchSpec arch = process->GetTarget().GetArchitecture();
         MmapArgList args =
             process->GetTarget().GetPlatform()->GetMmapArgumentList(

diff  --git a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
index 7c1f6fa421f00..39ed8e577ac9b 100644
--- a/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
+++ b/lldb/source/Plugins/SymbolFile/Breakpad/SymbolFileBreakpad.h
@@ -126,7 +126,7 @@ class SymbolFileBreakpad : public SymbolFileCommon {
                  llvm::DenseSet<SymbolFile *> &searched_symbol_files,
                  TypeMap &types) override;
 
-  llvm::Expected<TypeSystem &>
+  llvm::Expected<lldb::TypeSystemSP>
   GetTypeSystemForLanguage(lldb::LanguageType language) override {
     return llvm::make_error<llvm::StringError>(
         "SymbolFileBreakpad does not support GetTypeSystemForLanguage",

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
index 80709d1f0b0dd..a340f1d3d8fe6 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -223,8 +223,10 @@ static void ForcefullyCompleteType(CompilerType type) {
   lldbassert(started && "Unable to start a class type definition.");
   TypeSystemClang::CompleteTagDeclarationDefinition(type);
   const clang::TagDecl *td = ClangUtil::GetAsTagDecl(type);
-  auto &ts = llvm::cast<TypeSystemClang>(*type.GetTypeSystem());
-  ts.GetMetadata(td)->SetIsForcefullyCompleted();
+  auto ts_sp = type.GetTypeSystem();
+  auto ts = ts_sp.dyn_cast_or_null<TypeSystemClang>();
+  if (ts)
+    ts->GetMetadata(td)->SetIsForcefullyCompleted();
 }
 
 /// This function serves a similar purpose as RequireCompleteType above, but it
@@ -792,8 +794,9 @@ TypeSP DWARFASTParserClang::ParseEnum(const SymbolContext &sc,
 
   CompilerType enumerator_clang_type;
   CompilerType clang_type;
-  clang_type.SetCompilerType(
-      &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+  clang_type =
+      CompilerType(m_ast.weak_from_this(),
+                   dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
   if (!clang_type) {
     if (attrs.type.IsValid()) {
       Type *enumerator_type =
@@ -1361,9 +1364,8 @@ void DWARFASTParserClang::ParseInheritance(
     const lldb::ModuleSP &module_sp,
     std::vector<std::unique_ptr<clang::CXXBaseSpecifier>> &base_classes,
     ClangASTImporter::LayoutInfo &layout_info) {
-
-  TypeSystemClang *ast =
-      llvm::dyn_cast_or_null<TypeSystemClang>(class_clang_type.GetTypeSystem());
+  auto ast =
+      class_clang_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
   if (ast == nullptr)
     return;
 
@@ -1770,8 +1772,9 @@ DWARFASTParserClang::ParseStructureLikeDIE(const SymbolContext &sc,
   assert(tag_decl_kind != -1);
   (void)tag_decl_kind;
   bool clang_type_was_created = false;
-  clang_type.SetCompilerType(
-      &m_ast, dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
+  clang_type =
+      CompilerType(m_ast.weak_from_this(),
+                   dwarf->GetForwardDeclDieToClangType().lookup(die.GetDIE()));
   if (!clang_type) {
     clang::DeclContext *decl_ctx =
         GetClangDeclContextContainingDIE(die, nullptr);
@@ -2692,7 +2695,11 @@ llvm::Expected<llvm::APInt> DWARFASTParserClang::ExtractIntFromFormValue(
     const CompilerType &int_type, const DWARFFormValue &form_value) const {
   clang::QualType qt = ClangUtil::GetQualType(int_type);
   assert(qt->isIntegralOrEnumerationType());
-  TypeSystemClang &ts = *llvm::cast<TypeSystemClang>(int_type.GetTypeSystem());
+  auto ts_ptr = int_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
+  if (!ts_ptr)
+    return llvm::createStringError(llvm::inconvertibleErrorCode(),
+                                   "TypeSystem not clang");
+  TypeSystemClang &ts = *ts_ptr;
   clang::ASTContext &ast = ts.getASTContext();
 
   const unsigned type_bits = ast.getIntWidth(qt);
@@ -3022,8 +3029,8 @@ bool DWARFASTParserClang::ParseChildMembers(
   FieldInfo last_field_info;
 
   ModuleSP module_sp = parent_die.GetDWARF()->GetObjectFile()->GetModule();
-  TypeSystemClang *ast =
-      llvm::dyn_cast_or_null<TypeSystemClang>(class_clang_type.GetTypeSystem());
+  auto ts = class_clang_type.GetTypeSystem();
+  auto ast = ts.dyn_cast_or_null<TypeSystemClang>();
   if (ast == nullptr)
     return false;
 

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 066fc9f434cae..2447f93411e04 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -432,16 +432,16 @@ UniqueDWARFASTTypeMap &SymbolFileDWARF::GetUniqueDWARFASTTypeMap() {
     return m_unique_ast_type_map;
 }
 
-llvm::Expected<TypeSystem &>
+llvm::Expected<lldb::TypeSystemSP>
 SymbolFileDWARF::GetTypeSystemForLanguage(LanguageType language) {
   if (SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile())
     return debug_map_symfile->GetTypeSystemForLanguage(language);
 
   auto type_system_or_err =
       m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
-  if (type_system_or_err) {
-    type_system_or_err->SetSymbolFile(this);
-  }
+  if (type_system_or_err)
+    if (auto ts = *type_system_or_err)
+      ts->SetSymbolFile(this);
   return type_system_or_err;
 }
 
@@ -830,7 +830,10 @@ Function *SymbolFileDWARF::ParseFunction(CompileUnit &comp_unit,
                    "Unable to parse function");
     return nullptr;
   }
-  DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser();
+  auto ts = *type_system_or_err;
+  if (!ts)
+    return nullptr;
+  DWARFASTParser *dwarf_ast = ts->GetDWARFParser();
   if (!dwarf_ast)
     return nullptr;
 
@@ -876,7 +879,12 @@ SymbolFileDWARF::ConstructFunctionDemangledName(const DWARFDIE &die) {
     return ConstString();
   }
 
-  DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser();
+  auto ts = *type_system_or_err;
+  if (!ts) {
+    LLDB_LOG(GetLog(LLDBLog::Symbols), "Type system no longer live");
+    return ConstString();
+  }
+  DWARFASTParser *dwarf_ast = ts->GetDWARFParser();
   if (!dwarf_ast)
     return ConstString();
 
@@ -1556,10 +1564,8 @@ bool SymbolFileDWARF::HasForwardDeclForClangType(
           compiler_type_no_qualifiers.GetOpaqueQualType())) {
     return true;
   }
-  TypeSystem *type_system = compiler_type.GetTypeSystem();
-
-  TypeSystemClang *clang_type_system =
-      llvm::dyn_cast_or_null<TypeSystemClang>(type_system);
+  auto type_system = compiler_type.GetTypeSystem();
+  auto clang_type_system = type_system.dyn_cast_or_null<TypeSystemClang>();
   if (!clang_type_system)
     return false;
   DWARFASTParserClang *ast_parser =
@@ -1569,9 +1575,8 @@ bool SymbolFileDWARF::HasForwardDeclForClangType(
 
 bool SymbolFileDWARF::CompleteType(CompilerType &compiler_type) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
-
-  TypeSystemClang *clang_type_system =
-      llvm::dyn_cast_or_null<TypeSystemClang>(compiler_type.GetTypeSystem());
+  auto clang_type_system =
+      compiler_type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
   if (clang_type_system) {
     DWARFASTParserClang *ast_parser =
         static_cast<DWARFASTParserClang *>(clang_type_system->GetDWARFParser());
@@ -2150,7 +2155,7 @@ bool SymbolFileDWARF::DeclContextMatchesThisSymbolFile(
     return false;
   }
 
-  if (decl_ctx_type_system == &type_system_or_err.get())
+  if (decl_ctx_type_system == type_system_or_err->get())
     return true; // The type systems match, return true
 
   // The namespace AST was valid, and it does not match...
@@ -2965,7 +2970,7 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
       // use this to ensure any matches we find are in a language that this
       // type system supports
       const LanguageType language = dwarf_decl_ctx.GetLanguage();
-      TypeSystem *type_system = nullptr;
+      TypeSystemSP type_system = nullptr;
       if (language != eLanguageTypeUnknown) {
         auto type_system_or_err = GetTypeSystemForLanguage(language);
         if (auto err = type_system_or_err.takeError()) {
@@ -2973,7 +2978,7 @@ TypeSP SymbolFileDWARF::FindDefinitionTypeForDWARFDeclContext(
                          "Cannot get TypeSystem for language {}",
                          Language::GetNameForLanguageType(language));
         } else {
-          type_system = &type_system_or_err.get();
+          type_system = *type_system_or_err;
         }
       }
 
@@ -3069,8 +3074,11 @@ TypeSP SymbolFileDWARF::ParseType(const SymbolContext &sc, const DWARFDIE &die,
                    "Unable to parse type");
     return {};
   }
+  auto ts = *type_system_or_err;
+  if (!ts)
+    return {};
 
-  DWARFASTParser *dwarf_ast = type_system_or_err->GetDWARFParser();
+  DWARFASTParser *dwarf_ast = ts->GetDWARFParser();
   if (!dwarf_ast)
     return {};
 
@@ -4078,8 +4086,8 @@ void SymbolFileDWARF::DumpClangAST(Stream &s) {
   auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
   if (!ts_or_err)
     return;
-  TypeSystemClang *clang =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&ts_or_err.get());
+  auto ts = *ts_or_err;
+  TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang)
     return;
   clang->Dump(s.AsRawOstream());
@@ -4122,7 +4130,8 @@ const std::shared_ptr<SymbolFileDWARFDwo> &SymbolFileDWARF::GetDwpSymbolFile() {
   return m_dwp_symfile;
 }
 
-llvm::Expected<TypeSystem &> SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) {
+llvm::Expected<lldb::TypeSystemSP>
+SymbolFileDWARF::GetTypeSystem(DWARFUnit &unit) {
   return unit.GetSymbolFileDWARF().GetTypeSystemForLanguage(GetLanguage(unit));
 }
 
@@ -4133,7 +4142,9 @@ DWARFASTParser *SymbolFileDWARF::GetDWARFParser(DWARFUnit &unit) {
                    "Unable to get DWARFASTParser");
     return nullptr;
   }
-  return type_system_or_err->GetDWARFParser();
+  if (auto ts = *type_system_or_err)
+    return ts->GetDWARFParser();
+  return nullptr;
 }
 
 CompilerDecl SymbolFileDWARF::GetDecl(const DWARFDIE &die) {

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
index 7a939a0b58de4..410a95ddab5c1 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -210,7 +210,7 @@ class SymbolFileDWARF : public lldb_private::SymbolFileCommon,
                 lldb::TypeClass type_mask,
                 lldb_private::TypeList &type_list) override;
 
-  llvm::Expected<lldb_private::TypeSystem &>
+  llvm::Expected<lldb::TypeSystemSP>
   GetTypeSystemForLanguage(lldb::LanguageType language) override;
 
   lldb_private::CompilerDeclContext FindNamespace(
@@ -300,8 +300,7 @@ class SymbolFileDWARF : public lldb_private::SymbolFileCommon,
 
   lldb_private::FileSpec GetFile(DWARFUnit &unit, size_t file_idx);
 
-  static llvm::Expected<lldb_private::TypeSystem &>
-  GetTypeSystem(DWARFUnit &unit);
+  static llvm::Expected<lldb::TypeSystemSP> GetTypeSystem(DWARFUnit &unit);
 
   static DWARFASTParser *GetDWARFParser(DWARFUnit &unit);
 

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
index 2f98106af0c10..f0b0864fb1272 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.cpp
@@ -118,7 +118,7 @@ lldb::TypeSP SymbolFileDWARFDwo::FindCompleteObjCDefinitionTypeForDIE(
       die, type_name, must_be_implementation);
 }
 
-llvm::Expected<TypeSystem &>
+llvm::Expected<lldb::TypeSystemSP>
 SymbolFileDWARFDwo::GetTypeSystemForLanguage(LanguageType language) {
   return GetBaseSymbolFile().GetTypeSystemForLanguage(language);
 }

diff  --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
index 93538aac3c549..c8501037372b6 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDwo.h
@@ -34,7 +34,7 @@ class SymbolFileDWARFDwo : public SymbolFileDWARF {
   void GetObjCMethods(lldb_private::ConstString class_name,
                       llvm::function_ref<bool(DWARFDIE die)> callback) override;
 
-  llvm::Expected<lldb_private::TypeSystem &>
+  llvm::Expected<lldb::TypeSystemSP>
   GetTypeSystemForLanguage(lldb::LanguageType language) override;
 
   DWARFDIE

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
index 90684cf56a1ed..b3b05d47f2014 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/PdbAstBuilder.cpp
@@ -1428,7 +1428,7 @@ CompilerDecl PdbAstBuilder::ToCompilerDecl(clang::Decl &decl) {
 }
 
 CompilerType PdbAstBuilder::ToCompilerType(clang::QualType qt) {
-  return {&m_clang, qt.getAsOpaquePtr()};
+  return {m_clang.weak_from_this(), qt.getAsOpaquePtr()};
 }
 
 CompilerDeclContext

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
index 8fdd23d942d85..5b8176f84c64d 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.cpp
@@ -354,7 +354,8 @@ void SymbolFileNativePDB::InitializeObject() {
     LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
                    "Failed to initialize");
   } else {
-    ts_or_err->SetSymbolFile(this);
+    if (auto ts = *ts_or_err)
+      ts->SetSymbolFile(this);
     BuildParentMap();
   }
 }
@@ -383,7 +384,10 @@ Block &SymbolFileNativePDB::CreateBlock(PdbCompilandSymId block_id) {
   auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage());
   if (auto err = ts_or_err.takeError())
     return *child_block;
-  PdbAstBuilder* ast_builder = ts_or_err->GetNativePDBParser();
+  auto ts = *ts_or_err;
+  if (!ts)
+    return *child_block;
+  PdbAstBuilder* ast_builder = ts->GetNativePDBParser();
 
   switch (sym.kind()) {
   case S_GPROC32:
@@ -502,7 +506,10 @@ lldb::FunctionSP SymbolFileNativePDB::CreateFunction(PdbCompilandSymId func_id,
   auto ts_or_err = GetTypeSystemForLanguage(comp_unit.GetLanguage());
   if (auto err = ts_or_err.takeError())
     return func_sp;
-  ts_or_err->GetNativePDBParser()->GetOrCreateFunctionDecl(func_id);
+  auto ts = *ts_or_err;
+  if (!ts)
+    return func_sp;
+  ts->GetNativePDBParser()->GetOrCreateFunctionDecl(func_id);
 
   return func_sp;
 }
@@ -798,7 +805,11 @@ TypeSP SymbolFileNativePDB::CreateAndCacheType(PdbTypeSymId type_id) {
   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
   if (auto err = ts_or_err.takeError())
     return nullptr;
-  PdbAstBuilder* ast_builder = ts_or_err->GetNativePDBParser();
+  auto ts = *ts_or_err;
+  if (!ts)
+    return nullptr;
+
+  PdbAstBuilder* ast_builder = ts->GetNativePDBParser();
   clang::QualType qt = ast_builder->GetOrCreateType(best_decl_id);
   if (qt.isNull())
     return nullptr;
@@ -895,7 +906,11 @@ VariableSP SymbolFileNativePDB::CreateGlobalVariable(PdbGlobalSymId var_id) {
   auto ts_or_err = GetTypeSystemForLanguage(comp_unit->GetLanguage());
   if (auto err = ts_or_err.takeError())
     return nullptr;
-  ts_or_err->GetNativePDBParser()->GetOrCreateVariableDecl(var_id);
+  auto ts = *ts_or_err;
+  if (!ts)
+    return nullptr;
+
+  ts->GetNativePDBParser()->GetOrCreateVariableDecl(var_id);
 
   ModuleSP module_sp = GetObjectFile()->GetModule();
   DWARFExpressionList location(
@@ -1625,8 +1640,8 @@ void SymbolFileNativePDB::DumpClangAST(Stream &s) {
   auto ts_or_err = GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
   if (!ts_or_err)
     return;
-  TypeSystemClang *clang =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&ts_or_err.get());
+  auto ts = *ts_or_err;
+  TypeSystemClang *clang = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang)
     return;
   clang->GetNativePDBParser()->Dump(s);
@@ -1838,7 +1853,11 @@ VariableSP SymbolFileNativePDB::CreateLocalVariable(PdbCompilandSymId scope_id,
     auto ts_or_err = GetTypeSystemForLanguage(comp_unit_sp->GetLanguage());
     if (auto err = ts_or_err.takeError())
       return nullptr;
-    ts_or_err->GetNativePDBParser()->GetOrCreateVariableDecl(scope_id, var_id);
+    auto ts = *ts_or_err;
+    if (!ts)
+      return nullptr;
+
+    ts->GetNativePDBParser()->GetOrCreateVariableDecl(scope_id, var_id);
   }
   m_local_variables[toOpaqueUid(var_id)] = var_sp;
   return var_sp;
@@ -1864,7 +1883,11 @@ TypeSP SymbolFileNativePDB::CreateTypedef(PdbGlobalSymId id) {
   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
   if (auto err = ts_or_err.takeError())
     return nullptr;
-  ts_or_err->GetNativePDBParser()->GetOrCreateTypedefDecl(id);
+  auto ts = *ts_or_err;
+  if (!ts)
+    return nullptr;
+
+  ts->GetNativePDBParser()->GetOrCreateTypedefDecl(id);
 
   Declaration decl;
   return std::make_shared<lldb_private::Type>(
@@ -2016,7 +2039,11 @@ CompilerDecl SymbolFileNativePDB::GetDeclForUID(lldb::user_id_t uid) {
   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
   if (auto err = ts_or_err.takeError())
     return CompilerDecl();
-  if (auto decl = ts_or_err->GetNativePDBParser()->GetOrCreateDeclForUid(uid))
+  auto ts = *ts_or_err;
+  if (!ts)
+    return {};
+
+  if (auto decl = ts->GetNativePDBParser()->GetOrCreateDeclForUid(uid))
     return *decl;
   return CompilerDecl();
 }
@@ -2026,7 +2053,11 @@ SymbolFileNativePDB::GetDeclContextForUID(lldb::user_id_t uid) {
   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
   if (auto err = ts_or_err.takeError())
     return {};
-  PdbAstBuilder *ast_builder = ts_or_err->GetNativePDBParser();
+  auto ts = *ts_or_err;
+  if (!ts)
+    return {};
+
+  PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
   clang::DeclContext *context =
       ast_builder->GetOrCreateDeclContextForUid(PdbSymUid(uid));
   if (!context)
@@ -2040,7 +2071,11 @@ SymbolFileNativePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
   auto ts_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC_plus_plus);
   if (auto err = ts_or_err.takeError())
     return CompilerDeclContext();
-  PdbAstBuilder *ast_builder = ts_or_err->GetNativePDBParser();
+  auto ts = *ts_or_err;
+  if (!ts)
+    return {};
+
+  PdbAstBuilder *ast_builder = ts->GetNativePDBParser();
   clang::DeclContext *context = ast_builder->GetParentDeclContext(PdbSymUid(uid));
   if (!context)
     return CompilerDeclContext();
@@ -2078,9 +2113,8 @@ SymbolFileNativePDB::GetDynamicArrayInfoForUID(
 
 bool SymbolFileNativePDB::CompleteType(CompilerType &compiler_type) {
   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
-
-  TypeSystemClang *clang_type_system =
-      llvm::dyn_cast_or_null<TypeSystemClang>(compiler_type.GetTypeSystem());
+  auto ts = compiler_type.GetTypeSystem();
+  auto clang_type_system = ts.dyn_cast_or_null<TypeSystemClang>();
   if (!clang_type_system)
     return false;
 
@@ -2105,13 +2139,13 @@ SymbolFileNativePDB::FindNamespace(ConstString name,
   return {};
 }
 
-llvm::Expected<TypeSystem &>
+llvm::Expected<lldb::TypeSystemSP>
 SymbolFileNativePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
   auto type_system_or_err =
       m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
-  if (type_system_or_err) {
-    type_system_or_err->SetSymbolFile(this);
-  }
+  if (type_system_or_err)
+    if (auto ts = *type_system_or_err)
+      ts->SetSymbolFile(this);
   return type_system_or_err;
 }
 

diff  --git a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
index 7da4ffbbf4dd4..740331cac58dd 100644
--- a/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
+++ b/lldb/source/Plugins/SymbolFile/NativePDB/SymbolFileNativePDB.h
@@ -148,7 +148,7 @@ class SymbolFileNativePDB : public SymbolFileCommon {
                  llvm::DenseSet<SymbolFile *> &searched_symbol_files,
                  TypeMap &types) override;
 
-  llvm::Expected<TypeSystem &>
+  llvm::Expected<lldb::TypeSystemSP>
   GetTypeSystemForLanguage(lldb::LanguageType language) override;
 
   CompilerDeclContext

diff  --git a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
index 68d68b2780774..7dbc13c1f01fc 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/PDBASTParser.cpp
@@ -120,24 +120,31 @@ GetBuiltinTypeForPDBEncodingAndBitSize(TypeSystemClang &clang_ast,
     return clang_ast.GetBasicType(eBasicTypeBool);
   case PDB_BuiltinType::Long:
     if (width == ast.getTypeSize(ast.LongTy))
-      return CompilerType(&clang_ast, ast.LongTy.getAsOpaquePtr());
+      return CompilerType(clang_ast.weak_from_this(),
+                          ast.LongTy.getAsOpaquePtr());
     if (width == ast.getTypeSize(ast.LongLongTy))
-      return CompilerType(&clang_ast, ast.LongLongTy.getAsOpaquePtr());
+      return CompilerType(clang_ast.weak_from_this(),
+                          ast.LongLongTy.getAsOpaquePtr());
     break;
   case PDB_BuiltinType::ULong:
     if (width == ast.getTypeSize(ast.UnsignedLongTy))
-      return CompilerType(&clang_ast, ast.UnsignedLongTy.getAsOpaquePtr());
+      return CompilerType(clang_ast.weak_from_this(),
+                          ast.UnsignedLongTy.getAsOpaquePtr());
     if (width == ast.getTypeSize(ast.UnsignedLongLongTy))
-      return CompilerType(&clang_ast, ast.UnsignedLongLongTy.getAsOpaquePtr());
+      return CompilerType(clang_ast.weak_from_this(),
+                          ast.UnsignedLongLongTy.getAsOpaquePtr());
     break;
   case PDB_BuiltinType::WCharT:
     if (width == ast.getTypeSize(ast.WCharTy))
-      return CompilerType(&clang_ast, ast.WCharTy.getAsOpaquePtr());
+      return CompilerType(clang_ast.weak_from_this(),
+                          ast.WCharTy.getAsOpaquePtr());
     break;
   case PDB_BuiltinType::Char16:
-    return CompilerType(&clang_ast, ast.Char16Ty.getAsOpaquePtr());
+    return CompilerType(clang_ast.weak_from_this(),
+                        ast.Char16Ty.getAsOpaquePtr());
   case PDB_BuiltinType::Char32:
-    return CompilerType(&clang_ast, ast.Char32Ty.getAsOpaquePtr());
+    return CompilerType(clang_ast.weak_from_this(),
+                        ast.Char32Ty.getAsOpaquePtr());
   case PDB_BuiltinType::Float:
     // Note: types `long double` and `double` have same bit size in MSVC and
     // there is no information in the PDB to distinguish them. So when falling

diff  --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
index 36e3f4bf75910..3e0b733913af2 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.cpp
@@ -318,8 +318,9 @@ SymbolFilePDB::ParseCompileUnitFunctionForPDBFunc(const PDBSymbolFunc &pdb_func,
     return nullptr;
   }
 
+  auto ts = *type_system_or_err;
   TypeSystemClang *clang_type_system =
-    llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+    llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang_type_system)
     return nullptr;
   clang_type_system->GetPDBParser()->GetDeclForSymbol(pdb_func);
@@ -568,8 +569,9 @@ lldb_private::Type *SymbolFilePDB::ResolveTypeUID(lldb::user_id_t type_uid) {
     return nullptr;
   }
 
+  auto ts = *type_system_or_err;
   TypeSystemClang *clang_type_system =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+      llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang_type_system)
     return nullptr;
   PDBASTParser *pdb = clang_type_system->GetPDBParser();
@@ -604,9 +606,9 @@ bool SymbolFilePDB::CompleteType(lldb_private::CompilerType &compiler_type) {
                    "Unable to get dynamic array info for UID");
     return false;
   }
-
+  auto ts = *type_system_or_err;
   TypeSystemClang *clang_ast_ctx =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+      llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
 
   if (!clang_ast_ctx)
     return false;
@@ -626,9 +628,9 @@ lldb_private::CompilerDecl SymbolFilePDB::GetDeclForUID(lldb::user_id_t uid) {
                    "Unable to get decl for UID");
     return CompilerDecl();
   }
-
+  auto ts = *type_system_or_err;
   TypeSystemClang *clang_ast_ctx =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+      llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang_ast_ctx)
     return CompilerDecl();
 
@@ -657,8 +659,9 @@ SymbolFilePDB::GetDeclContextForUID(lldb::user_id_t uid) {
     return CompilerDeclContext();
   }
 
+  auto ts = *type_system_or_err;
   TypeSystemClang *clang_ast_ctx =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+      llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang_ast_ctx)
     return CompilerDeclContext();
 
@@ -687,8 +690,9 @@ SymbolFilePDB::GetDeclContextContainingUID(lldb::user_id_t uid) {
     return CompilerDeclContext();
   }
 
+  auto ts = *type_system_or_err;
   TypeSystemClang *clang_ast_ctx =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+      llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang_ast_ctx)
     return CompilerDeclContext();
 
@@ -716,8 +720,9 @@ void SymbolFilePDB::ParseDeclsForContext(
     return;
   }
 
+  auto ts = *type_system_or_err;
   TypeSystemClang *clang_ast_ctx =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+      llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang_ast_ctx)
     return;
 
@@ -1464,8 +1469,9 @@ void SymbolFilePDB::DumpClangAST(Stream &s) {
     return;
   }
 
-  auto *clang_type_system =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+  auto ts = *type_system_or_err;
+  TypeSystemClang *clang_type_system =
+      llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang_type_system)
     return;
   clang_type_system->Dump(s.AsRawOstream());
@@ -1656,12 +1662,13 @@ void SymbolFilePDB::GetTypes(lldb_private::SymbolContextScope *sc_scope,
   }
 }
 
-llvm::Expected<lldb_private::TypeSystem &>
+llvm::Expected<lldb::TypeSystemSP>
 SymbolFilePDB::GetTypeSystemForLanguage(lldb::LanguageType language) {
   auto type_system_or_err =
       m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
   if (type_system_or_err) {
-    type_system_or_err->SetSymbolFile(this);
+    if (auto ts = *type_system_or_err)
+      ts->SetSymbolFile(this);
   }
   return type_system_or_err;
 }
@@ -1675,8 +1682,9 @@ PDBASTParser *SymbolFilePDB::GetPDBAstParser() {
     return nullptr;
   }
 
+  auto ts = *type_system_or_err;
   auto *clang_type_system =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+      llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang_type_system)
     return nullptr;
 
@@ -1694,9 +1702,9 @@ SymbolFilePDB::FindNamespace(lldb_private::ConstString name,
                    "Unable to find namespace {}", name.AsCString());
     return CompilerDeclContext();
   }
-
+  auto ts = *type_system_or_err;
   auto *clang_type_system =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+      llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang_type_system)
     return CompilerDeclContext();
 
@@ -1990,7 +1998,7 @@ bool SymbolFilePDB::DeclContextMatchesThisSymbolFile(
     return false;
   }
 
-  if (decl_ctx_type_system == &type_system_or_err.get())
+  if (decl_ctx_type_system == type_system_or_err->get())
     return true; // The type systems match, return true
 
   return false;

diff  --git a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
index 1292bbee91712..2f45a4615585e 100644
--- a/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
+++ b/lldb/source/Plugins/SymbolFile/PDB/SymbolFilePDB.h
@@ -153,7 +153,7 @@ class SymbolFilePDB : public lldb_private::SymbolFileCommon {
                 lldb::TypeClass type_mask,
                 lldb_private::TypeList &type_list) override;
 
-  llvm::Expected<lldb_private::TypeSystem &>
+  llvm::Expected<lldb::TypeSystemSP>
   GetTypeSystemForLanguage(lldb::LanguageType language) override;
 
   lldb_private::CompilerDeclContext FindNamespace(

diff  --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
index c27295ad9720f..d838c4c68fff1 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AppleGetItemInfoHandler.cpp
@@ -162,11 +162,15 @@ lldb::addr_t AppleGetItemInfoHandler::SetupGetItemInfoFunction(
               eLanguageTypeC);
       if (auto err = type_system_or_err.takeError()) {
         LLDB_LOG_ERROR(log, std::move(err),
-                       "Error inseting get-item-info function");
+                       "Error inserting get-item-info function");
         return args_addr;
       }
+      auto ts = *type_system_or_err;
+      if (!ts)
+        return args_addr;
+      
       CompilerType get_item_info_return_type =
-          type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid)
+          ts->GetBasicTypeFromAST(eBasicTypeVoid)
               .GetPointerType();
 
       Status error;
@@ -174,7 +178,7 @@ lldb::addr_t AppleGetItemInfoHandler::SetupGetItemInfoFunction(
           get_item_info_return_type, get_item_info_arglist,
           thread.shared_from_this(), error);
       if (error.Fail() || get_item_info_caller == nullptr) {
-        LLDB_LOGF(log, "Error Inserting get-item-info function: \"%s\".",
+        LLDB_LOGF(log, "Error inserting get-item-info function: \"%s\".",
                   error.AsCString());
         return args_addr;
       }

diff  --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
index 2993b98f967e5..c265a43729d12 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.cpp
@@ -1,4 +1,4 @@
-//===-- TypeSystemClang.cpp -----------------------------------------------===//
+//===-- TypeSystemClang.cpp -----------------------------------------------==='//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -935,7 +935,7 @@ CompilerType TypeSystemClang::GetBasicType(lldb::BasicType basic_type) {
       GetOpaqueCompilerType(&ast, basic_type);
 
   if (clang_type)
-    return CompilerType(this, clang_type);
+    return CompilerType(weak_from_this(), clang_type);
   return CompilerType();
 }
 
@@ -1169,9 +1169,8 @@ CompilerType TypeSystemClang::GetCStringType(bool is_const) {
 
 bool TypeSystemClang::AreTypesSame(CompilerType type1, CompilerType type2,
                                    bool ignore_qualifiers) {
-  TypeSystemClang *ast =
-      llvm::dyn_cast_or_null<TypeSystemClang>(type1.GetTypeSystem());
-  if (!ast || ast != type2.GetTypeSystem())
+  auto ast = type1.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
+  if (!ast || type1.GetTypeSystem() != type2.GetTypeSystem())
     return false;
 
   if (type1.GetOpaqueQualType() == type2.GetOpaqueQualType())
@@ -2858,9 +2857,9 @@ bool TypeSystemClang::IsArrayType(lldb::opaque_compiler_type_t type,
   case clang::Type::ConstantArray:
     if (element_type_ptr)
       element_type_ptr->SetCompilerType(
-          this, llvm::cast<clang::ConstantArrayType>(qual_type)
-                    ->getElementType()
-                    .getAsOpaquePtr());
+          weak_from_this(), llvm::cast<clang::ConstantArrayType>(qual_type)
+                                ->getElementType()
+                                .getAsOpaquePtr());
     if (size)
       *size = llvm::cast<clang::ConstantArrayType>(qual_type)
                   ->getSize()
@@ -2872,9 +2871,9 @@ bool TypeSystemClang::IsArrayType(lldb::opaque_compiler_type_t type,
   case clang::Type::IncompleteArray:
     if (element_type_ptr)
       element_type_ptr->SetCompilerType(
-          this, llvm::cast<clang::IncompleteArrayType>(qual_type)
-                    ->getElementType()
-                    .getAsOpaquePtr());
+          weak_from_this(), llvm::cast<clang::IncompleteArrayType>(qual_type)
+                                ->getElementType()
+                                .getAsOpaquePtr());
     if (size)
       *size = 0;
     if (is_incomplete)
@@ -2884,9 +2883,9 @@ bool TypeSystemClang::IsArrayType(lldb::opaque_compiler_type_t type,
   case clang::Type::VariableArray:
     if (element_type_ptr)
       element_type_ptr->SetCompilerType(
-          this, llvm::cast<clang::VariableArrayType>(qual_type)
-                    ->getElementType()
-                    .getAsOpaquePtr());
+          weak_from_this(), llvm::cast<clang::VariableArrayType>(qual_type)
+                                ->getElementType()
+                                .getAsOpaquePtr());
     if (size)
       *size = 0;
     if (is_incomplete)
@@ -2896,9 +2895,10 @@ bool TypeSystemClang::IsArrayType(lldb::opaque_compiler_type_t type,
   case clang::Type::DependentSizedArray:
     if (element_type_ptr)
       element_type_ptr->SetCompilerType(
-          this, llvm::cast<clang::DependentSizedArrayType>(qual_type)
-                    ->getElementType()
-                    .getAsOpaquePtr());
+          weak_from_this(),
+          llvm::cast<clang::DependentSizedArrayType>(qual_type)
+              ->getElementType()
+              .getAsOpaquePtr());
     if (size)
       *size = 0;
     if (is_incomplete)
@@ -2939,7 +2939,8 @@ bool TypeSystemClang::IsVectorType(lldb::opaque_compiler_type_t type,
         *size = ext_vector_type->getNumElements();
       if (element_type)
         *element_type =
-            CompilerType(this, ext_vector_type->getElementType().getAsOpaquePtr());
+            CompilerType(weak_from_this(),
+                         ext_vector_type->getElementType().getAsOpaquePtr());
     }
     return true;
   }
@@ -3106,7 +3107,8 @@ TypeSystemClang::IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
             ++num_fields;
           }
           if (base_type_ptr)
-            *base_type_ptr = CompilerType(this, base_qual_type.getAsOpaquePtr());
+            *base_type_ptr =
+                CompilerType(weak_from_this(), base_qual_type.getAsOpaquePtr());
           return num_fields;
         }
       }
@@ -3140,7 +3142,7 @@ TypeSystemClang::GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
         llvm::dyn_cast<clang::FunctionProtoType>(qual_type.getTypePtr());
     if (func) {
       if (index < func->getNumParams())
-        return CompilerType(this, func->getParamType(index).getAsOpaquePtr());
+        return CompilerType(weak_from_this(), func->getParamType(index).getAsOpaquePtr());
     }
   }
   return CompilerType();
@@ -3183,8 +3185,8 @@ bool TypeSystemClang::IsBlockPointerType(
             qual_type->castAs<clang::BlockPointerType>();
         QualType pointee_type = block_pointer_type->getPointeeType();
         QualType function_pointer_type = m_ast_up->getPointerType(pointee_type);
-        *function_pointer_type_ptr =
-            CompilerType(this, function_pointer_type.getAsOpaquePtr());
+        *function_pointer_type_ptr = CompilerType(
+            weak_from_this(), function_pointer_type.getAsOpaquePtr());
       }
       return true;
     }
@@ -3275,20 +3277,21 @@ bool TypeSystemClang::IsPointerType(lldb::opaque_compiler_type_t type,
     case clang::Type::ObjCObjectPointer:
       if (pointee_type)
         pointee_type->SetCompilerType(
-            this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
-                      ->getPointeeType()
-                      .getAsOpaquePtr());
+            weak_from_this(),
+            llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+                ->getPointeeType()
+                .getAsOpaquePtr());
       return true;
     case clang::Type::BlockPointer:
       if (pointee_type)
         pointee_type->SetCompilerType(
-            this, llvm::cast<clang::BlockPointerType>(qual_type)
-                      ->getPointeeType()
-                      .getAsOpaquePtr());
+            weak_from_this(), llvm::cast<clang::BlockPointerType>(qual_type)
+                                  ->getPointeeType()
+                                  .getAsOpaquePtr());
       return true;
     case clang::Type::Pointer:
       if (pointee_type)
-        pointee_type->SetCompilerType(this,
+        pointee_type->SetCompilerType(weak_from_this(),
                                       llvm::cast<clang::PointerType>(qual_type)
                                           ->getPointeeType()
                                           .getAsOpaquePtr());
@@ -3296,9 +3299,9 @@ bool TypeSystemClang::IsPointerType(lldb::opaque_compiler_type_t type,
     case clang::Type::MemberPointer:
       if (pointee_type)
         pointee_type->SetCompilerType(
-            this, llvm::cast<clang::MemberPointerType>(qual_type)
-                      ->getPointeeType()
-                      .getAsOpaquePtr());
+            weak_from_this(), llvm::cast<clang::MemberPointerType>(qual_type)
+                                  ->getPointeeType()
+                                  .getAsOpaquePtr());
       return true;
     default:
       break;
@@ -3327,19 +3330,21 @@ bool TypeSystemClang::IsPointerOrReferenceType(
     case clang::Type::ObjCObjectPointer:
       if (pointee_type)
         pointee_type->SetCompilerType(
-            this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
-                                 ->getPointeeType().getAsOpaquePtr());
+            weak_from_this(),
+            llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+                ->getPointeeType()
+                .getAsOpaquePtr());
       return true;
     case clang::Type::BlockPointer:
       if (pointee_type)
         pointee_type->SetCompilerType(
-            this, llvm::cast<clang::BlockPointerType>(qual_type)
-                      ->getPointeeType()
-                      .getAsOpaquePtr());
+            weak_from_this(), llvm::cast<clang::BlockPointerType>(qual_type)
+                                  ->getPointeeType()
+                                  .getAsOpaquePtr());
       return true;
     case clang::Type::Pointer:
       if (pointee_type)
-        pointee_type->SetCompilerType(this,
+        pointee_type->SetCompilerType(weak_from_this(),
                                       llvm::cast<clang::PointerType>(qual_type)
                                           ->getPointeeType()
                                           .getAsOpaquePtr());
@@ -3347,23 +3352,23 @@ bool TypeSystemClang::IsPointerOrReferenceType(
     case clang::Type::MemberPointer:
       if (pointee_type)
         pointee_type->SetCompilerType(
-            this, llvm::cast<clang::MemberPointerType>(qual_type)
-                      ->getPointeeType()
-                      .getAsOpaquePtr());
+            weak_from_this(), llvm::cast<clang::MemberPointerType>(qual_type)
+                                  ->getPointeeType()
+                                  .getAsOpaquePtr());
       return true;
     case clang::Type::LValueReference:
       if (pointee_type)
         pointee_type->SetCompilerType(
-            this, llvm::cast<clang::LValueReferenceType>(qual_type)
-                      ->desugar()
-                      .getAsOpaquePtr());
+            weak_from_this(), llvm::cast<clang::LValueReferenceType>(qual_type)
+                                  ->desugar()
+                                  .getAsOpaquePtr());
       return true;
     case clang::Type::RValueReference:
       if (pointee_type)
         pointee_type->SetCompilerType(
-            this, llvm::cast<clang::RValueReferenceType>(qual_type)
-                      ->desugar()
-                      .getAsOpaquePtr());
+            weak_from_this(), llvm::cast<clang::RValueReferenceType>(qual_type)
+                                  ->desugar()
+                                  .getAsOpaquePtr());
       return true;
     default:
       break;
@@ -3385,18 +3390,18 @@ bool TypeSystemClang::IsReferenceType(lldb::opaque_compiler_type_t type,
     case clang::Type::LValueReference:
       if (pointee_type)
         pointee_type->SetCompilerType(
-            this, llvm::cast<clang::LValueReferenceType>(qual_type)
-                      ->desugar()
-                      .getAsOpaquePtr());
+            weak_from_this(), llvm::cast<clang::LValueReferenceType>(qual_type)
+                                  ->desugar()
+                                  .getAsOpaquePtr());
       if (is_rvalue)
         *is_rvalue = false;
       return true;
     case clang::Type::RValueReference:
       if (pointee_type)
         pointee_type->SetCompilerType(
-            this, llvm::cast<clang::RValueReferenceType>(qual_type)
-                      ->desugar()
-                      .getAsOpaquePtr());
+            weak_from_this(), llvm::cast<clang::RValueReferenceType>(qual_type)
+                                  ->desugar()
+                                  .getAsOpaquePtr());
       if (is_rvalue)
         *is_rvalue = true;
       return true;
@@ -3550,7 +3555,7 @@ bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
           llvm::cast<clang::BuiltinType>(qual_type)->getKind() ==
               clang::BuiltinType::ObjCId) {
         if (dynamic_pointee_type)
-          dynamic_pointee_type->SetCompilerType(this, type);
+          dynamic_pointee_type->SetCompilerType(weak_from_this(), type);
         return true;
       }
       break;
@@ -3568,9 +3573,10 @@ bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
         }
         if (dynamic_pointee_type)
           dynamic_pointee_type->SetCompilerType(
-              this, llvm::cast<clang::ObjCObjectPointerType>(qual_type)
-                        ->getPointeeType()
-                        .getAsOpaquePtr());
+              weak_from_this(),
+              llvm::cast<clang::ObjCObjectPointerType>(qual_type)
+                  ->getPointeeType()
+                  .getAsOpaquePtr());
         return true;
       }
       break;
@@ -3605,7 +3611,7 @@ bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
         case clang::BuiltinType::Void:
           if (dynamic_pointee_type)
             dynamic_pointee_type->SetCompilerType(
-                this, pointee_qual_type.getAsOpaquePtr());
+                weak_from_this(), pointee_qual_type.getAsOpaquePtr());
           return true;
         default:
           break;
@@ -3637,7 +3643,7 @@ bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
             if (success) {
               if (dynamic_pointee_type)
                 dynamic_pointee_type->SetCompilerType(
-                    this, pointee_qual_type.getAsOpaquePtr());
+                    weak_from_this(), pointee_qual_type.getAsOpaquePtr());
               return true;
             }
           }
@@ -3649,7 +3655,7 @@ bool TypeSystemClang::IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
         if (check_objc) {
           if (dynamic_pointee_type)
             dynamic_pointee_type->SetCompilerType(
-                this, pointee_qual_type.getAsOpaquePtr());
+                weak_from_this(), pointee_qual_type.getAsOpaquePtr());
           return true;
         }
         break;
@@ -3843,14 +3849,15 @@ TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type,
     case clang::BuiltinType::ObjCClass:
       if (pointee_or_element_clang_type)
         pointee_or_element_clang_type->SetCompilerType(
-            this, getASTContext().ObjCBuiltinClassTy.getAsOpaquePtr());
+            weak_from_this(),
+            getASTContext().ObjCBuiltinClassTy.getAsOpaquePtr());
       builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
       break;
 
     case clang::BuiltinType::ObjCSel:
       if (pointee_or_element_clang_type)
         pointee_or_element_clang_type->SetCompilerType(
-            this, getASTContext().CharTy.getAsOpaquePtr());
+            weak_from_this(), getASTContext().CharTy.getAsOpaquePtr());
       builtin_type_flags |= eTypeIsPointer | eTypeIsObjC;
       break;
 
@@ -3893,7 +3900,7 @@ TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type,
   case clang::Type::BlockPointer:
     if (pointee_or_element_clang_type)
       pointee_or_element_clang_type->SetCompilerType(
-          this, qual_type->getPointeeType().getAsOpaquePtr());
+          weak_from_this(), qual_type->getPointeeType().getAsOpaquePtr());
     return eTypeIsPointer | eTypeHasChildren | eTypeIsBlock;
 
   case clang::Type::Complex: {
@@ -3917,9 +3924,9 @@ TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type,
   case clang::Type::VariableArray:
     if (pointee_or_element_clang_type)
       pointee_or_element_clang_type->SetCompilerType(
-          this, llvm::cast<clang::ArrayType>(qual_type.getTypePtr())
-                    ->getElementType()
-                    .getAsOpaquePtr());
+          weak_from_this(), llvm::cast<clang::ArrayType>(qual_type.getTypePtr())
+                                ->getElementType()
+                                .getAsOpaquePtr());
     return eTypeHasChildren | eTypeIsArray;
 
   case clang::Type::DependentName:
@@ -3932,10 +3939,10 @@ TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type,
   case clang::Type::Enum:
     if (pointee_or_element_clang_type)
       pointee_or_element_clang_type->SetCompilerType(
-          this, llvm::cast<clang::EnumType>(qual_type)
-                    ->getDecl()
-                    ->getIntegerType()
-                    .getAsOpaquePtr());
+          weak_from_this(), llvm::cast<clang::EnumType>(qual_type)
+                                ->getDecl()
+                                ->getIntegerType()
+                                .getAsOpaquePtr());
     return eTypeIsEnumeration | eTypeHasValue;
 
   case clang::Type::FunctionProto:
@@ -3949,9 +3956,10 @@ TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type,
   case clang::Type::RValueReference:
     if (pointee_or_element_clang_type)
       pointee_or_element_clang_type->SetCompilerType(
-          this, llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())
-                    ->getPointeeType()
-                    .getAsOpaquePtr());
+          weak_from_this(),
+          llvm::cast<clang::ReferenceType>(qual_type.getTypePtr())
+              ->getPointeeType()
+              .getAsOpaquePtr());
     return eTypeHasChildren | eTypeIsReference | eTypeHasValue;
 
   case clang::Type::MemberPointer:
@@ -3960,7 +3968,7 @@ TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type,
   case clang::Type::ObjCObjectPointer:
     if (pointee_or_element_clang_type)
       pointee_or_element_clang_type->SetCompilerType(
-          this, qual_type->getPointeeType().getAsOpaquePtr());
+          weak_from_this(), qual_type->getPointeeType().getAsOpaquePtr());
     return eTypeHasChildren | eTypeIsObjC | eTypeIsClass | eTypeIsPointer |
            eTypeHasValue;
 
@@ -3972,7 +3980,7 @@ TypeSystemClang::GetTypeInfo(lldb::opaque_compiler_type_t type,
   case clang::Type::Pointer:
     if (pointee_or_element_clang_type)
       pointee_or_element_clang_type->SetCompilerType(
-          this, qual_type->getPointeeType().getAsOpaquePtr());
+          weak_from_this(), qual_type->getPointeeType().getAsOpaquePtr());
     return eTypeHasChildren | eTypeIsPointer | eTypeHasValue;
 
   case clang::Type::Record:
@@ -5776,9 +5784,10 @@ CompilerType TypeSystemClang::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
           objc_interface_type->getDecl();
       if (class_interface_decl) {
         return CompilerType(
-            this, GetObjCFieldAtIndex(&getASTContext(), class_interface_decl,
-                                      idx, name, bit_offset_ptr,
-                                      bitfield_bit_size_ptr, is_bitfield_ptr));
+            weak_from_this(),
+            GetObjCFieldAtIndex(&getASTContext(), class_interface_decl, idx,
+                                name, bit_offset_ptr, bitfield_bit_size_ptr,
+                                is_bitfield_ptr));
       }
     }
     break;
@@ -5794,9 +5803,10 @@ CompilerType TypeSystemClang::GetFieldAtIndex(lldb::opaque_compiler_type_t type,
         clang::ObjCInterfaceDecl *class_interface_decl =
             objc_class_type->getInterface();
         return CompilerType(
-            this, GetObjCFieldAtIndex(&getASTContext(), class_interface_decl,
-                                      idx, name, bit_offset_ptr,
-                                      bitfield_bit_size_ptr, is_bitfield_ptr));
+            weak_from_this(),
+            GetObjCFieldAtIndex(&getASTContext(), class_interface_decl, idx,
+                                name, bit_offset_ptr, bitfield_bit_size_ptr,
+                                is_bitfield_ptr));
       }
     }
     break;
@@ -7279,7 +7289,7 @@ TypeSystemClang::GetIntegralTemplateArgument(lldb::opaque_compiler_type_t type,
 
 CompilerType TypeSystemClang::GetTypeForFormatters(void *type) {
   if (type)
-    return ClangUtil::RemoveFastQualifiers(CompilerType(this, type));
+    return ClangUtil::RemoveFastQualifiers(CompilerType(weak_from_this(), type));
   return CompilerType();
 }
 
@@ -7333,8 +7343,8 @@ clang::FieldDecl *TypeSystemClang::AddFieldToRecordType(
     uint32_t bitfield_bit_size) {
   if (!type.IsValid() || !field_clang_type.IsValid())
     return nullptr;
-  TypeSystemClang *ast =
-      llvm::dyn_cast_or_null<TypeSystemClang>(type.GetTypeSystem());
+  auto ts = type.GetTypeSystem();
+  auto ast = ts.dyn_cast_or_null<TypeSystemClang>();
   if (!ast)
     return nullptr;
   clang::ASTContext &clang_ast = ast->getASTContext();
@@ -7427,7 +7437,8 @@ void TypeSystemClang::BuildIndirectFields(const CompilerType &type) {
   if (!type)
     return;
 
-  TypeSystemClang *ast = llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+  auto ts = type.GetTypeSystem();
+  auto ast = ts.dyn_cast_or_null<TypeSystemClang>();
   if (!ast)
     return;
 
@@ -7533,8 +7544,8 @@ void TypeSystemClang::BuildIndirectFields(const CompilerType &type) {
 
 void TypeSystemClang::SetIsPacked(const CompilerType &type) {
   if (type) {
-    TypeSystemClang *ast =
-        llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+    auto ts = type.GetTypeSystem();
+    auto ast = ts.dyn_cast_or_null<TypeSystemClang>();
     if (ast) {
       clang::RecordDecl *record_decl = GetAsRecordDecl(type);
 
@@ -7553,7 +7564,8 @@ clang::VarDecl *TypeSystemClang::AddVariableToRecordType(
   if (!type.IsValid() || !var_type.IsValid())
     return nullptr;
 
-  TypeSystemClang *ast = llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+  auto ts = type.GetTypeSystem();
+  auto ast = ts.dyn_cast_or_null<TypeSystemClang>();
   if (!ast)
     return nullptr;
 
@@ -7860,8 +7872,8 @@ bool TypeSystemClang::TransferBaseClasses(
 
 bool TypeSystemClang::SetObjCSuperClass(
     const CompilerType &type, const CompilerType &superclass_clang_type) {
-  TypeSystemClang *ast =
-      llvm::dyn_cast_or_null<TypeSystemClang>(type.GetTypeSystem());
+  auto ts = type.GetTypeSystem();
+  auto ast = ts.dyn_cast_or_null<TypeSystemClang>();
   if (!ast)
     return false;
   clang::ASTContext &clang_ast = ast->getASTContext();
@@ -7889,7 +7901,8 @@ bool TypeSystemClang::AddObjCClassProperty(
   if (!type || !property_clang_type.IsValid() || property_name == nullptr ||
       property_name[0] == '\0')
     return false;
-  TypeSystemClang *ast = llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+  auto ts = type.GetTypeSystem();
+  auto ast = ts.dyn_cast_or_null<TypeSystemClang>();
   if (!ast)
     return false;
   clang::ASTContext &clang_ast = ast->getASTContext();
@@ -8108,8 +8121,8 @@ clang::ObjCMethodDecl *TypeSystemClang::AddMethodToObjCObjectType(
 
   if (class_interface_decl == nullptr)
     return nullptr;
-  TypeSystemClang *lldb_ast =
-      llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+  auto ts = type.GetTypeSystem();
+  auto lldb_ast = ts.dyn_cast_or_null<TypeSystemClang>();
   if (lldb_ast == nullptr)
     return nullptr;
   clang::ASTContext &ast = lldb_ast->getASTContext();
@@ -8312,8 +8325,8 @@ bool TypeSystemClang::CompleteTagDeclarationDefinition(
   if (qual_type.isNull())
     return false;
 
-  TypeSystemClang *lldb_ast =
-      llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+  auto ts = type.GetTypeSystem();
+  auto lldb_ast = ts.dyn_cast_or_null<TypeSystemClang>();
   if (lldb_ast == nullptr)
     return false;
 
@@ -8397,7 +8410,8 @@ clang::EnumConstantDecl *TypeSystemClang::AddEnumerationValueToEnumerationType(
   if (!enum_type || ConstString(name).IsEmpty())
     return nullptr;
 
-  lldbassert(enum_type.GetTypeSystem() == static_cast<TypeSystem *>(this));
+  lldbassert(enum_type.GetTypeSystem().GetSharedPointer().get() ==
+             static_cast<TypeSystem *>(this));
 
   lldb::opaque_compiler_type_t enum_opaque_compiler_type =
       enum_type.GetOpaqueQualType();
@@ -8464,8 +8478,8 @@ TypeSystemClang::CreateMemberPointerType(const CompilerType &type,
                                          const CompilerType &pointee_type) {
   if (type && pointee_type.IsValid() &&
       type.GetTypeSystem() == pointee_type.GetTypeSystem()) {
-    TypeSystemClang *ast =
-        llvm::dyn_cast<TypeSystemClang>(type.GetTypeSystem());
+    auto ts = type.GetTypeSystem();
+    auto ast = ts.dyn_cast_or_null<TypeSystemClang>();
     if (!ast)
       return CompilerType();
     return ast->GetType(ast->getASTContext().getMemberPointerType(
@@ -9161,7 +9175,7 @@ void TypeSystemClang::DumpTypeDescription(lldb::opaque_compiler_type_t type,
   StreamFile s(stdout, false);
   DumpTypeDescription(type, &s, level);
 
-  CompilerType ct(this, type);
+  CompilerType ct(weak_from_this(), type);
   const clang::Type *clang_type = ClangUtil::GetQualType(ct).getTypePtr();
   ClangASTMetadata *metadata = GetMetadata(clang_type);
   if (metadata) {
@@ -9831,8 +9845,9 @@ void TypeSystemClang::RequireCompleteType(CompilerType type) {
   lldbassert(started && "Unable to start a class type definition.");
   TypeSystemClang::CompleteTagDeclarationDefinition(type);
   const clang::TagDecl *td = ClangUtil::GetAsTagDecl(type);
-  auto &ts = llvm::cast<TypeSystemClang>(*type.GetTypeSystem());
-  ts.GetMetadata(td)->SetIsForcefullyCompleted();
+  auto ts = type.GetTypeSystem().dyn_cast_or_null<TypeSystemClang>();
+  if (ts)
+    ts->GetMetadata(td)->SetIsForcefullyCompleted();
 }
 
 namespace {
@@ -9894,13 +9909,16 @@ ScratchTypeSystemClang::GetForTarget(Target &target,
                    "Couldn't get scratch TypeSystemClang");
     return nullptr;
   }
-  ScratchTypeSystemClang &scratch_ast =
-      llvm::cast<ScratchTypeSystemClang>(type_system_or_err.get());
+  auto ts = *type_system_or_err;
+  ScratchTypeSystemClang *scratch_ast =
+      llvm::dyn_cast_or_null<ScratchTypeSystemClang>(ts.get());
+  if (!scratch_ast)
+    return nullptr;
   // If no dedicated sub-AST was requested, just return the main AST.
   if (ast_kind == DefaultAST)
-    return &scratch_ast;
+    return scratch_ast;
   // Search the sub-ASTs.
-  return &scratch_ast.GetIsolatedAST(*ast_kind);
+  return &scratch_ast->GetIsolatedAST(*ast_kind);
 }
 
 /// Returns a human-readable name that uniquely identifiers the sub-AST kind.
@@ -10010,9 +10028,9 @@ TypeSystemClang &ScratchTypeSystemClang::GetIsolatedAST(
     return *found_ast->second;
 
   // Couldn't find the requested sub-AST, so create it now.
-  std::unique_ptr<TypeSystemClang> new_ast;
-  new_ast.reset(new SpecializedScratchAST(GetSpecializedASTName(feature),
-                                          m_triple, CreateASTSource()));
-  m_isolated_asts[feature] = std::move(new_ast);
-  return *m_isolated_asts[feature];
+  std::shared_ptr<TypeSystemClang> new_ast_sp =
+      std::make_shared<SpecializedScratchAST>(GetSpecializedASTName(feature),
+                                              m_triple, CreateASTSource());
+  m_isolated_asts.insert({feature, new_ast_sp});
+  return *new_ast_sp;
 }

diff  --git a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
index 1a5ec3075a8ac..6bd39f307f7dd 100644
--- a/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
+++ b/lldb/source/Plugins/TypeSystem/Clang/TypeSystemClang.h
@@ -13,7 +13,6 @@
 
 #include <functional>
 #include <initializer_list>
-#include <map>
 #include <memory>
 #include <set>
 #include <string>
@@ -241,7 +240,7 @@ class TypeSystemClang : public TypeSystem {
     // Check that the type actually belongs to this TypeSystemClang.
     assert(qt->getAsTagDecl() == nullptr ||
            &qt->getAsTagDecl()->getASTContext() == &getASTContext());
-    return CompilerType(this, qt.getAsOpaquePtr());
+    return CompilerType(weak_from_this(), qt.getAsOpaquePtr());
   }
 
   CompilerType GetTypeForDecl(clang::NamedDecl *decl);
@@ -271,9 +270,10 @@ class TypeSystemClang : public TypeSystem {
         clang::NamedDecl *named_decl = *result.begin();
         if (const RecordDeclType *record_decl =
                 llvm::dyn_cast<RecordDeclType>(named_decl))
-          compiler_type.SetCompilerType(
-              this, clang::QualType(record_decl->getTypeForDecl(), 0)
-                        .getAsOpaquePtr());
+          compiler_type =
+              CompilerType(weak_from_this(),
+                           clang::QualType(record_decl->getTypeForDecl(), 0)
+                               .getAsOpaquePtr());
       }
     }
 
@@ -1238,7 +1238,7 @@ class ScratchTypeSystemClang : public TypeSystemClang {
   /// Map from IsolatedASTKind to their actual TypeSystemClang instance.
   /// This map is lazily filled with sub-ASTs and should be accessed via
   /// `GetSubAST` (which lazily fills this map).
-  std::unordered_map<IsolatedASTKey, std::unique_ptr<TypeSystemClang>>
+  llvm::DenseMap<IsolatedASTKey, std::shared_ptr<TypeSystemClang>>
       m_isolated_asts;
 };
 

diff  --git a/lldb/source/Symbol/CompilerType.cpp b/lldb/source/Symbol/CompilerType.cpp
index 1bf2e7d189bb8..1ae5cc3337604 100644
--- a/lldb/source/Symbol/CompilerType.cpp
+++ b/lldb/source/Symbol/CompilerType.cpp
@@ -30,26 +30,30 @@ using namespace lldb_private;
 
 bool CompilerType::IsAggregateType() const {
   if (IsValid())
-    return m_type_system->IsAggregateType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsAggregateType(m_type);
   return false;
 }
 
 bool CompilerType::IsAnonymousType() const {
   if (IsValid())
-    return m_type_system->IsAnonymousType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsAnonymousType(m_type);
   return false;
 }
 
 bool CompilerType::IsScopedEnumerationType() const {
   if (IsValid())
-    return m_type_system->IsScopedEnumerationType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsScopedEnumerationType(m_type);
   return false;
 }
 
 bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size,
                                bool *is_incomplete) const {
   if (IsValid())
-    return m_type_system->IsArrayType(m_type, element_type_ptr, size,
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsArrayType(m_type, element_type_ptr, size,
                                       is_incomplete);
 
   if (element_type_ptr)
@@ -64,43 +68,50 @@ bool CompilerType::IsArrayType(CompilerType *element_type_ptr, uint64_t *size,
 bool CompilerType::IsVectorType(CompilerType *element_type,
                                 uint64_t *size) const {
   if (IsValid())
-    return m_type_system->IsVectorType(m_type, element_type, size);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsVectorType(m_type, element_type, size);
   return false;
 }
 
 bool CompilerType::IsRuntimeGeneratedType() const {
   if (IsValid())
-    return m_type_system->IsRuntimeGeneratedType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsRuntimeGeneratedType(m_type);
   return false;
 }
 
 bool CompilerType::IsCharType() const {
   if (IsValid())
-    return m_type_system->IsCharType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsCharType(m_type);
   return false;
 }
 
 bool CompilerType::IsCompleteType() const {
   if (IsValid())
-    return m_type_system->IsCompleteType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsCompleteType(m_type);
   return false;
 }
 
 bool CompilerType::IsConst() const {
   if (IsValid())
-    return m_type_system->IsConst(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsConst(m_type);
   return false;
 }
 
 bool CompilerType::IsCStringType(uint32_t &length) const {
   if (IsValid())
-    return m_type_system->IsCStringType(m_type, length);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsCStringType(m_type, length);
   return false;
 }
 
 bool CompilerType::IsFunctionType() const {
   if (IsValid())
-    return m_type_system->IsFunctionType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsFunctionType(m_type);
   return false;
 }
 
@@ -108,45 +119,52 @@ bool CompilerType::IsFunctionType() const {
 uint32_t
 CompilerType::IsHomogeneousAggregate(CompilerType *base_type_ptr) const {
   if (IsValid())
-    return m_type_system->IsHomogeneousAggregate(m_type, base_type_ptr);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsHomogeneousAggregate(m_type, base_type_ptr);
   return 0;
 }
 
 size_t CompilerType::GetNumberOfFunctionArguments() const {
   if (IsValid())
-    return m_type_system->GetNumberOfFunctionArguments(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetNumberOfFunctionArguments(m_type);
   return 0;
 }
 
 CompilerType
 CompilerType::GetFunctionArgumentAtIndex(const size_t index) const {
   if (IsValid())
-    return m_type_system->GetFunctionArgumentAtIndex(m_type, index);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetFunctionArgumentAtIndex(m_type, index);
   return CompilerType();
 }
 
 bool CompilerType::IsFunctionPointerType() const {
   if (IsValid())
-    return m_type_system->IsFunctionPointerType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsFunctionPointerType(m_type);
   return false;
 }
 
 bool CompilerType::IsBlockPointerType(
     CompilerType *function_pointer_type_ptr) const {
   if (IsValid())
-    return m_type_system->IsBlockPointerType(m_type, function_pointer_type_ptr);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsBlockPointerType(m_type, function_pointer_type_ptr);
   return false;
 }
 
 bool CompilerType::IsIntegerType(bool &is_signed) const {
   if (IsValid())
-    return m_type_system->IsIntegerType(m_type, is_signed);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsIntegerType(m_type, is_signed);
   return false;
 }
 
 bool CompilerType::IsEnumerationType(bool &is_signed) const {
   if (IsValid())
-    return m_type_system->IsEnumerationType(m_type, is_signed);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsEnumerationType(m_type, is_signed);
   return false;
 }
 
@@ -156,7 +174,8 @@ bool CompilerType::IsIntegerOrEnumerationType(bool &is_signed) const {
 
 bool CompilerType::IsPointerType(CompilerType *pointee_type) const {
   if (IsValid()) {
-    return m_type_system->IsPointerType(m_type, pointee_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsPointerType(m_type, pointee_type);
   }
   if (pointee_type)
     pointee_type->Clear();
@@ -165,7 +184,8 @@ bool CompilerType::IsPointerType(CompilerType *pointee_type) const {
 
 bool CompilerType::IsPointerOrReferenceType(CompilerType *pointee_type) const {
   if (IsValid()) {
-    return m_type_system->IsPointerOrReferenceType(m_type, pointee_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsPointerOrReferenceType(m_type, pointee_type);
   }
   if (pointee_type)
     pointee_type->Clear();
@@ -175,7 +195,8 @@ bool CompilerType::IsPointerOrReferenceType(CompilerType *pointee_type) const {
 bool CompilerType::IsReferenceType(CompilerType *pointee_type,
                                    bool *is_rvalue) const {
   if (IsValid()) {
-    return m_type_system->IsReferenceType(m_type, pointee_type, is_rvalue);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsReferenceType(m_type, pointee_type, is_rvalue);
   }
   if (pointee_type)
     pointee_type->Clear();
@@ -184,14 +205,16 @@ bool CompilerType::IsReferenceType(CompilerType *pointee_type,
 
 bool CompilerType::ShouldTreatScalarValueAsAddress() const {
   if (IsValid())
-    return m_type_system->ShouldTreatScalarValueAsAddress(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->ShouldTreatScalarValueAsAddress(m_type);
   return false;
 }
 
 bool CompilerType::IsFloatingPointType(uint32_t &count,
                                        bool &is_complex) const {
   if (IsValid()) {
-    return m_type_system->IsFloatingPointType(m_type, count, is_complex);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsFloatingPointType(m_type, count, is_complex);
   }
   count = 0;
   is_complex = false;
@@ -200,13 +223,15 @@ bool CompilerType::IsFloatingPointType(uint32_t &count,
 
 bool CompilerType::IsDefined() const {
   if (IsValid())
-    return m_type_system->IsDefined(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsDefined(m_type);
   return true;
 }
 
 bool CompilerType::IsPolymorphicClass() const {
   if (IsValid()) {
-    return m_type_system->IsPolymorphicClass(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsPolymorphicClass(m_type);
   }
   return false;
 }
@@ -215,28 +240,31 @@ bool CompilerType::IsPossibleDynamicType(CompilerType *dynamic_pointee_type,
                                          bool check_cplusplus,
                                          bool check_objc) const {
   if (IsValid())
-    return m_type_system->IsPossibleDynamicType(m_type, dynamic_pointee_type,
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsPossibleDynamicType(m_type, dynamic_pointee_type,
                                                 check_cplusplus, check_objc);
   return false;
 }
 
 bool CompilerType::IsScalarType() const {
-  if (!IsValid())
-    return false;
-
-  return m_type_system->IsScalarType(m_type);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsScalarType(m_type);
+  return false;
 }
 
 bool CompilerType::IsTypedefType() const {
-  if (!IsValid())
-    return false;
-  return m_type_system->IsTypedefType(m_type);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsTypedefType(m_type);
+  return false;
 }
 
 bool CompilerType::IsVoidType() const {
-  if (!IsValid())
-    return false;
-  return m_type_system->IsVoidType(m_type);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsVoidType(m_type);
+  return false;
 }
 
 bool CompilerType::IsPointerToScalarType() const {
@@ -254,70 +282,82 @@ bool CompilerType::IsArrayOfScalarType() const {
 }
 
 bool CompilerType::IsBeingDefined() const {
-  if (!IsValid())
-    return false;
-  return m_type_system->IsBeingDefined(m_type);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsBeingDefined(m_type);
+  return false;
 }
 
 // Type Completion
 
 bool CompilerType::GetCompleteType() const {
-  if (!IsValid())
-    return false;
-  return m_type_system->GetCompleteType(m_type);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetCompleteType(m_type);
+  return false;
 }
 
 // AST related queries
 size_t CompilerType::GetPointerByteSize() const {
-  if (m_type_system)
-    return m_type_system->GetPointerByteSize();
+  if (auto type_system_sp = GetTypeSystem())
+    return type_system_sp->GetPointerByteSize();
   return 0;
 }
 
 ConstString CompilerType::GetTypeName(bool BaseOnly) const {
   if (IsValid()) {
-    return m_type_system->GetTypeName(m_type, BaseOnly);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetTypeName(m_type, BaseOnly);
   }
   return ConstString("<invalid>");
 }
 
 ConstString CompilerType::GetDisplayTypeName() const {
   if (IsValid())
-    return m_type_system->GetDisplayTypeName(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetDisplayTypeName(m_type);
   return ConstString("<invalid>");
 }
 
 uint32_t CompilerType::GetTypeInfo(
     CompilerType *pointee_or_element_compiler_type) const {
-  if (!IsValid())
-    return 0;
-
-  return m_type_system->GetTypeInfo(m_type, pointee_or_element_compiler_type);
+  if (IsValid())
+  if (auto type_system_sp = GetTypeSystem())
+    return type_system_sp->GetTypeInfo(m_type,
+                                       pointee_or_element_compiler_type);
+  return 0;
 }
 
 lldb::LanguageType CompilerType::GetMinimumLanguage() {
-  if (!IsValid())
-    return lldb::eLanguageTypeC;
-
-  return m_type_system->GetMinimumLanguage(m_type);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetMinimumLanguage(m_type);
+  return lldb::eLanguageTypeC;
 }
 
 lldb::TypeClass CompilerType::GetTypeClass() const {
-  if (!IsValid())
-    return lldb::eTypeClassInvalid;
-
-  return m_type_system->GetTypeClass(m_type);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetTypeClass(m_type);
+  return lldb::eTypeClassInvalid;
 }
 
-void CompilerType::SetCompilerType(TypeSystem *type_system,
+void CompilerType::SetCompilerType(lldb::TypeSystemWP type_system,
                                    lldb::opaque_compiler_type_t type) {
   m_type_system = type_system;
   m_type = type;
 }
 
+void CompilerType::SetCompilerType(CompilerType::TypeSystemSPWrapper type_system,
+                                   lldb::opaque_compiler_type_t type) {
+  m_type_system = type_system.GetSharedPointer();
+  m_type = type;
+}
+
 unsigned CompilerType::GetTypeQualifiers() const {
   if (IsValid())
-    return m_type_system->GetTypeQualifiers(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetTypeQualifiers(m_type);
   return 0;
 }
 
@@ -326,146 +366,160 @@ unsigned CompilerType::GetTypeQualifiers() const {
 CompilerType
 CompilerType::GetArrayElementType(ExecutionContextScope *exe_scope) const {
   if (IsValid()) {
-    return m_type_system->GetArrayElementType(m_type, exe_scope);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetArrayElementType(m_type, exe_scope);
   }
   return CompilerType();
 }
 
 CompilerType CompilerType::GetArrayType(uint64_t size) const {
   if (IsValid()) {
-    return m_type_system->GetArrayType(m_type, size);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetArrayType(m_type, size);
   }
   return CompilerType();
 }
 
 CompilerType CompilerType::GetCanonicalType() const {
   if (IsValid())
-    return m_type_system->GetCanonicalType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetCanonicalType(m_type);
   return CompilerType();
 }
 
 CompilerType CompilerType::GetFullyUnqualifiedType() const {
   if (IsValid())
-    return m_type_system->GetFullyUnqualifiedType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetFullyUnqualifiedType(m_type);
   return CompilerType();
 }
 
 CompilerType CompilerType::GetEnumerationIntegerType() const {
   if (IsValid())
-    return m_type_system->GetEnumerationIntegerType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetEnumerationIntegerType(m_type);
   return CompilerType();
 }
 
 int CompilerType::GetFunctionArgumentCount() const {
   if (IsValid()) {
-    return m_type_system->GetFunctionArgumentCount(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetFunctionArgumentCount(m_type);
   }
   return -1;
 }
 
 CompilerType CompilerType::GetFunctionArgumentTypeAtIndex(size_t idx) const {
   if (IsValid()) {
-    return m_type_system->GetFunctionArgumentTypeAtIndex(m_type, idx);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetFunctionArgumentTypeAtIndex(m_type, idx);
   }
   return CompilerType();
 }
 
 CompilerType CompilerType::GetFunctionReturnType() const {
   if (IsValid()) {
-    return m_type_system->GetFunctionReturnType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetFunctionReturnType(m_type);
   }
   return CompilerType();
 }
 
 size_t CompilerType::GetNumMemberFunctions() const {
   if (IsValid()) {
-    return m_type_system->GetNumMemberFunctions(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetNumMemberFunctions(m_type);
   }
   return 0;
 }
 
 TypeMemberFunctionImpl CompilerType::GetMemberFunctionAtIndex(size_t idx) {
   if (IsValid()) {
-    return m_type_system->GetMemberFunctionAtIndex(m_type, idx);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetMemberFunctionAtIndex(m_type, idx);
   }
   return TypeMemberFunctionImpl();
 }
 
 CompilerType CompilerType::GetNonReferenceType() const {
   if (IsValid())
-    return m_type_system->GetNonReferenceType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetNonReferenceType(m_type);
   return CompilerType();
 }
 
 CompilerType CompilerType::GetPointeeType() const {
   if (IsValid()) {
-    return m_type_system->GetPointeeType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetPointeeType(m_type);
   }
   return CompilerType();
 }
 
 CompilerType CompilerType::GetPointerType() const {
   if (IsValid()) {
-    return m_type_system->GetPointerType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetPointerType(m_type);
   }
   return CompilerType();
 }
 
 CompilerType CompilerType::GetLValueReferenceType() const {
   if (IsValid())
-    return m_type_system->GetLValueReferenceType(m_type);
-  else
-    return CompilerType();
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetLValueReferenceType(m_type);
+  return CompilerType();
 }
 
 CompilerType CompilerType::GetRValueReferenceType() const {
   if (IsValid())
-    return m_type_system->GetRValueReferenceType(m_type);
-  else
-    return CompilerType();
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetRValueReferenceType(m_type);
+  return CompilerType();
 }
 
 CompilerType CompilerType::GetAtomicType() const {
   if (IsValid())
-    return m_type_system->GetAtomicType(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetAtomicType(m_type);
   return CompilerType();
 }
 
 CompilerType CompilerType::AddConstModifier() const {
   if (IsValid())
-    return m_type_system->AddConstModifier(m_type);
-  else
-    return CompilerType();
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->AddConstModifier(m_type);
+  return CompilerType();
 }
 
 CompilerType CompilerType::AddVolatileModifier() const {
   if (IsValid())
-    return m_type_system->AddVolatileModifier(m_type);
-  else
-    return CompilerType();
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->AddVolatileModifier(m_type);
+  return CompilerType();
 }
 
 CompilerType CompilerType::AddRestrictModifier() const {
   if (IsValid())
-    return m_type_system->AddRestrictModifier(m_type);
-  else
-    return CompilerType();
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->AddRestrictModifier(m_type);
+  return CompilerType();
 }
 
 CompilerType CompilerType::CreateTypedef(const char *name,
                                          const CompilerDeclContext &decl_ctx,
                                          uint32_t payload) const {
   if (IsValid())
-    return m_type_system->CreateTypedef(m_type, name, decl_ctx, payload);
-  else
-    return CompilerType();
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->CreateTypedef(m_type, name, decl_ctx, payload);
+  return CompilerType();
 }
 
 CompilerType CompilerType::GetTypedefedType() const {
   if (IsValid())
-    return m_type_system->GetTypedefedType(m_type);
-  else
-    return CompilerType();
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetTypedefedType(m_type);
+  return CompilerType();
 }
 
 // Create related types using the current type's AST
@@ -473,7 +527,8 @@ CompilerType CompilerType::GetTypedefedType() const {
 CompilerType
 CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const {
   if (IsValid())
-    return m_type_system->GetBasicTypeFromAST(basic_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetBasicTypeFromAST(basic_type);
   return CompilerType();
 }
 // Exploring the type
@@ -481,7 +536,8 @@ CompilerType::GetBasicTypeFromAST(lldb::BasicType basic_type) const {
 llvm::Optional<uint64_t>
 CompilerType::GetBitSize(ExecutionContextScope *exe_scope) const {
   if (IsValid())
-    return m_type_system->GetBitSize(m_type, exe_scope);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetBitSize(m_type, exe_scope);
   return {};
 }
 
@@ -494,35 +550,38 @@ CompilerType::GetByteSize(ExecutionContextScope *exe_scope) const {
 
 llvm::Optional<size_t> CompilerType::GetTypeBitAlign(ExecutionContextScope *exe_scope) const {
   if (IsValid())
-    return m_type_system->GetTypeBitAlign(m_type, exe_scope);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetTypeBitAlign(m_type, exe_scope);
   return {};
 }
 
 lldb::Encoding CompilerType::GetEncoding(uint64_t &count) const {
-  if (!IsValid())
-    return lldb::eEncodingInvalid;
-
-  return m_type_system->GetEncoding(m_type, count);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetEncoding(m_type, count);
+  return lldb::eEncodingInvalid;
 }
 
 lldb::Format CompilerType::GetFormat() const {
-  if (!IsValid())
-    return lldb::eFormatDefault;
-
-  return m_type_system->GetFormat(m_type);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetFormat(m_type);
+  return lldb::eFormatDefault;
 }
 
 uint32_t CompilerType::GetNumChildren(bool omit_empty_base_classes,
                                       const ExecutionContext *exe_ctx) const {
-  if (!IsValid())
-    return 0;
-  return m_type_system->GetNumChildren(m_type, omit_empty_base_classes,
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetNumChildren(m_type, omit_empty_base_classes,
                                        exe_ctx);
+  return 0;
 }
 
 lldb::BasicType CompilerType::GetBasicTypeEnumeration() const {
   if (IsValid())
-    return m_type_system->GetBasicTypeEnumeration(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetBasicTypeEnumeration(m_type);
   return eBasicTypeInvalid;
 }
 
@@ -531,34 +590,39 @@ void CompilerType::ForEachEnumerator(
                        ConstString name,
                        const llvm::APSInt &value)> const &callback) const {
   if (IsValid())
-    return m_type_system->ForEachEnumerator(m_type, callback);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->ForEachEnumerator(m_type, callback);
 }
 
 uint32_t CompilerType::GetNumFields() const {
-  if (!IsValid())
-    return 0;
-  return m_type_system->GetNumFields(m_type);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetNumFields(m_type);
+  return 0;
 }
 
 CompilerType CompilerType::GetFieldAtIndex(size_t idx, std::string &name,
                                            uint64_t *bit_offset_ptr,
                                            uint32_t *bitfield_bit_size_ptr,
                                            bool *is_bitfield_ptr) const {
-  if (!IsValid())
-    return CompilerType();
-  return m_type_system->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetFieldAtIndex(m_type, idx, name, bit_offset_ptr,
                                         bitfield_bit_size_ptr, is_bitfield_ptr);
+  return CompilerType();
 }
 
 uint32_t CompilerType::GetNumDirectBaseClasses() const {
   if (IsValid())
-    return m_type_system->GetNumDirectBaseClasses(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetNumDirectBaseClasses(m_type);
   return 0;
 }
 
 uint32_t CompilerType::GetNumVirtualBaseClasses() const {
   if (IsValid())
-    return m_type_system->GetNumVirtualBaseClasses(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetNumVirtualBaseClasses(m_type);
   return 0;
 }
 
@@ -566,7 +630,8 @@ CompilerType
 CompilerType::GetDirectBaseClassAtIndex(size_t idx,
                                         uint32_t *bit_offset_ptr) const {
   if (IsValid())
-    return m_type_system->GetDirectBaseClassAtIndex(m_type, idx,
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetDirectBaseClassAtIndex(m_type, idx,
                                                     bit_offset_ptr);
   return CompilerType();
 }
@@ -575,7 +640,8 @@ CompilerType
 CompilerType::GetVirtualBaseClassAtIndex(size_t idx,
                                          uint32_t *bit_offset_ptr) const {
   if (IsValid())
-    return m_type_system->GetVirtualBaseClassAtIndex(m_type, idx,
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetVirtualBaseClassAtIndex(m_type, idx,
                                                      bit_offset_ptr);
   return CompilerType();
 }
@@ -607,13 +673,15 @@ CompilerType CompilerType::GetChildCompilerTypeAtIndex(
     uint32_t &child_bitfield_bit_offset, bool &child_is_base_class,
     bool &child_is_deref_of_parent, ValueObject *valobj,
     uint64_t &language_flags) const {
-  if (!IsValid())
-    return CompilerType();
-  return m_type_system->GetChildCompilerTypeAtIndex(
-      m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
-      ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
-      child_bitfield_bit_size, child_bitfield_bit_offset, child_is_base_class,
-      child_is_deref_of_parent, valobj, language_flags);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetChildCompilerTypeAtIndex(
+          m_type, exe_ctx, idx, transparent_pointers, omit_empty_base_classes,
+          ignore_array_bounds, child_name, child_byte_size, child_byte_offset,
+          child_bitfield_bit_size, child_bitfield_bit_offset,
+          child_is_base_class, child_is_deref_of_parent, valobj,
+          language_flags);
+  return CompilerType();
 }
 
 // Look for a child member (doesn't include base classes, but it does include
@@ -653,7 +721,8 @@ size_t CompilerType::GetIndexOfChildMemberWithName(
     const char *name, bool omit_empty_base_classes,
     std::vector<uint32_t> &child_indexes) const {
   if (IsValid() && name && name[0]) {
-    return m_type_system->GetIndexOfChildMemberWithName(
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetIndexOfChildMemberWithName(
         m_type, name, omit_empty_base_classes, child_indexes);
   }
   return 0;
@@ -661,7 +730,8 @@ size_t CompilerType::GetIndexOfChildMemberWithName(
 
 size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
   if (IsValid()) {
-    return m_type_system->GetNumTemplateArguments(m_type, expand_pack);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetNumTemplateArguments(m_type, expand_pack);
   }
   return 0;
 }
@@ -669,14 +739,16 @@ size_t CompilerType::GetNumTemplateArguments(bool expand_pack) const {
 TemplateArgumentKind
 CompilerType::GetTemplateArgumentKind(size_t idx, bool expand_pack) const {
   if (IsValid())
-    return m_type_system->GetTemplateArgumentKind(m_type, idx, expand_pack);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetTemplateArgumentKind(m_type, idx, expand_pack);
   return eTemplateArgumentKindNull;
 }
 
 CompilerType CompilerType::GetTypeTemplateArgument(size_t idx,
                                                    bool expand_pack) const {
   if (IsValid()) {
-    return m_type_system->GetTypeTemplateArgument(m_type, idx, expand_pack);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetTypeTemplateArgument(m_type, idx, expand_pack);
   }
   return CompilerType();
 }
@@ -684,25 +756,29 @@ CompilerType CompilerType::GetTypeTemplateArgument(size_t idx,
 llvm::Optional<CompilerType::IntegralTemplateArgument>
 CompilerType::GetIntegralTemplateArgument(size_t idx, bool expand_pack) const {
   if (IsValid())
-    return m_type_system->GetIntegralTemplateArgument(m_type, idx, expand_pack);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetIntegralTemplateArgument(m_type, idx, expand_pack);
   return llvm::None;
 }
 
 CompilerType CompilerType::GetTypeForFormatters() const {
   if (IsValid())
-    return m_type_system->GetTypeForFormatters(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetTypeForFormatters(m_type);
   return CompilerType();
 }
 
 LazyBool CompilerType::ShouldPrintAsOneLiner(ValueObject *valobj) const {
   if (IsValid())
-    return m_type_system->ShouldPrintAsOneLiner(m_type, valobj);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->ShouldPrintAsOneLiner(m_type, valobj);
   return eLazyBoolCalculate;
 }
 
 bool CompilerType::IsMeaninglessWithoutDynamicResolution() const {
   if (IsValid())
-    return m_type_system->IsMeaninglessWithoutDynamicResolution(m_type);
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->IsMeaninglessWithoutDynamicResolution(m_type);
   return false;
 }
 
@@ -714,7 +790,8 @@ uint32_t
 CompilerType::GetIndexOfChildWithName(const char *name,
                                       bool omit_empty_base_classes) const {
   if (IsValid() && name && name[0]) {
-    return m_type_system->GetIndexOfChildWithName(m_type, name,
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->GetIndexOfChildWithName(m_type, name,
                                                   omit_empty_base_classes);
   }
   return UINT32_MAX;
@@ -729,11 +806,11 @@ void CompilerType::DumpValue(ExecutionContext *exe_ctx, Stream *s,
                              uint32_t bitfield_bit_offset, bool show_types,
                              bool show_summary, bool verbose, uint32_t depth) {
   if (!IsValid())
-    return;
-  m_type_system->DumpValue(m_type, exe_ctx, s, format, data, data_byte_offset,
-                           data_byte_size, bitfield_bit_size,
-                           bitfield_bit_offset, show_types, show_summary,
-                           verbose, depth);
+    if (auto type_system_sp = GetTypeSystem())
+      type_system_sp->DumpValue(m_type, exe_ctx, s, format, data,
+                                data_byte_offset, data_byte_size,
+                                bitfield_bit_size, bitfield_bit_offset,
+                                show_types, show_summary, verbose, depth);
 }
 
 bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format,
@@ -742,11 +819,12 @@ bool CompilerType::DumpTypeValue(Stream *s, lldb::Format format,
                                  uint32_t bitfield_bit_size,
                                  uint32_t bitfield_bit_offset,
                                  ExecutionContextScope *exe_scope) {
-  if (!IsValid())
-    return false;
-  return m_type_system->DumpTypeValue(m_type, s, format, data, byte_offset,
-                                      byte_size, bitfield_bit_size,
-                                      bitfield_bit_offset, exe_scope);
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->DumpTypeValue(m_type, s, format, data, byte_offset,
+                                           byte_size, bitfield_bit_size,
+                                           bitfield_bit_offset, exe_scope);
+  return false;
 }
 
 void CompilerType::DumpSummary(ExecutionContext *exe_ctx, Stream *s,
@@ -754,28 +832,30 @@ void CompilerType::DumpSummary(ExecutionContext *exe_ctx, Stream *s,
                                lldb::offset_t data_byte_offset,
                                size_t data_byte_size) {
   if (IsValid())
-    m_type_system->DumpSummary(m_type, exe_ctx, s, data, data_byte_offset,
-                               data_byte_size);
+    if (auto type_system_sp = GetTypeSystem())
+      type_system_sp->DumpSummary(m_type, exe_ctx, s, data, data_byte_offset,
+                                  data_byte_size);
 }
 
 void CompilerType::DumpTypeDescription(lldb::DescriptionLevel level) const {
   if (IsValid())
-    m_type_system->DumpTypeDescription(m_type, level);
+    if (auto type_system_sp = GetTypeSystem())
+      type_system_sp->DumpTypeDescription(m_type, level);
 }
 
 void CompilerType::DumpTypeDescription(Stream *s,
                                        lldb::DescriptionLevel level) const {
-  if (IsValid()) {
-    m_type_system->DumpTypeDescription(m_type, s, level);
-  }
+  if (IsValid())
+    if (auto type_system_sp = GetTypeSystem())
+      type_system_sp->DumpTypeDescription(m_type, s, level);
 }
 
 #ifndef NDEBUG
 LLVM_DUMP_METHOD void CompilerType::dump() const {
   if (IsValid())
-    m_type_system->dump(m_type);
-  else
-    llvm::errs() << "<invalid>\n";
+    if (auto type_system_sp = GetTypeSystem())
+      return type_system_sp->dump(m_type);
+  llvm::errs() << "<invalid>\n";
 }
 #endif
 
@@ -882,10 +962,32 @@ bool CompilerType::GetValueAsScalar(const lldb_private::DataExtractor &data,
 
 #ifndef NDEBUG
 bool CompilerType::Verify() const {
-  return !IsValid() || m_type_system->Verify(m_type);
+  if (!IsValid())
+    return true;
+  if (auto type_system_sp = GetTypeSystem())
+    return type_system_sp->Verify(m_type);
+  return true;
 }
 #endif
 
+CompilerType::TypeSystemSPWrapper CompilerType::GetTypeSystem() const {
+  return {m_type_system.lock()};
+}
+
+bool CompilerType::TypeSystemSPWrapper::operator==(
+    const CompilerType::TypeSystemSPWrapper &other) const {
+  if (!m_typesystem_sp && !other.m_typesystem_sp)
+    return true;
+  if (m_typesystem_sp && other.m_typesystem_sp)
+    return m_typesystem_sp.get() == other.m_typesystem_sp.get();
+  return false;
+}
+
+TypeSystem *CompilerType::TypeSystemSPWrapper::operator->() const {
+  assert(m_typesystem_sp);
+  return m_typesystem_sp.get();
+}
+
 bool lldb_private::operator==(const lldb_private::CompilerType &lhs,
                               const lldb_private::CompilerType &rhs) {
   return lhs.GetTypeSystem() == rhs.GetTypeSystem() &&

diff  --git a/lldb/source/Symbol/SymbolFile.cpp b/lldb/source/Symbol/SymbolFile.cpp
index 362f6ba20bf31..c7af908543e88 100644
--- a/lldb/source/Symbol/SymbolFile.cpp
+++ b/lldb/source/Symbol/SymbolFile.cpp
@@ -227,12 +227,13 @@ void SymbolFileCommon::SetCompileUnitAtIndex(uint32_t idx,
   (*m_compile_units)[idx] = cu_sp;
 }
 
-llvm::Expected<TypeSystem &>
+llvm::Expected<TypeSystemSP>
 SymbolFileCommon::GetTypeSystemForLanguage(lldb::LanguageType language) {
   auto type_system_or_err =
       m_objfile_sp->GetModule()->GetTypeSystemForLanguage(language);
   if (type_system_or_err) {
-    type_system_or_err->SetSymbolFile(this);
+    if (auto ts = *type_system_or_err)
+      ts->SetSymbolFile(this);
   }
   return type_system_or_err;
 }

diff  --git a/lldb/source/Symbol/SymbolFileOnDemand.cpp b/lldb/source/Symbol/SymbolFileOnDemand.cpp
index 737cb1042ca76..7f8a2bc146adb 100644
--- a/lldb/source/Symbol/SymbolFileOnDemand.cpp
+++ b/lldb/source/Symbol/SymbolFileOnDemand.cpp
@@ -467,7 +467,7 @@ void SymbolFileOnDemand::GetTypes(SymbolContextScope *sc_scope,
   return m_sym_file_impl->GetTypes(sc_scope, type_mask, type_list);
 }
 
-llvm::Expected<TypeSystem &>
+llvm::Expected<lldb::TypeSystemSP>
 SymbolFileOnDemand::GetTypeSystemForLanguage(LanguageType language) {
   if (!m_debug_info_enabled) {
     Log *log = GetLog();

diff  --git a/lldb/source/Symbol/Type.cpp b/lldb/source/Symbol/Type.cpp
index 3bf2c817dcff2..da9eeadc0ecd2 100644
--- a/lldb/source/Symbol/Type.cpp
+++ b/lldb/source/Symbol/Type.cpp
@@ -543,8 +543,10 @@ bool Type::ResolveCompilerType(ResolveState compiler_type_resolve_state) {
         LLDB_LOG_ERROR(GetLog(LLDBLog::Symbols), std::move(err),
                        "Unable to construct void type from TypeSystemClang");
       } else {
-        CompilerType void_compiler_type =
-            type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid);
+        CompilerType void_compiler_type;
+        auto ts = *type_system_or_err;
+        if (ts)
+          void_compiler_type = ts->GetBasicTypeFromAST(eBasicTypeVoid);
         switch (m_encoding_uid_type) {
         case eEncodingIsUID:
           m_compiler_type = void_compiler_type;
@@ -730,11 +732,14 @@ ModuleSP Type::GetModule() {
 
 ModuleSP Type::GetExeModule() {
   if (m_compiler_type) {
-    SymbolFile *symbol_file = m_compiler_type.GetTypeSystem()->GetSymbolFile();
+    auto ts = m_compiler_type.GetTypeSystem();
+    if (!ts)
+      return {};
+    SymbolFile *symbol_file = ts->GetSymbolFile();
     if (symbol_file)
       return symbol_file->GetObjectFile()->GetModule();
   }
-  return ModuleSP();
+  return {};
 }
 
 TypeAndOrName::TypeAndOrName(TypeSP &in_type_sp) {
@@ -1042,7 +1047,7 @@ CompilerType TypeImpl::GetCompilerType(bool prefer_dynamic) {
   return CompilerType();
 }
 
-TypeSystem *TypeImpl::GetTypeSystem(bool prefer_dynamic) {
+CompilerType::TypeSystemSPWrapper TypeImpl::GetTypeSystem(bool prefer_dynamic) {
   ModuleSP module_sp;
   if (CheckModule(module_sp)) {
     if (prefer_dynamic) {
@@ -1051,7 +1056,7 @@ TypeSystem *TypeImpl::GetTypeSystem(bool prefer_dynamic) {
     }
     return m_static_type.GetTypeSystem();
   }
-  return nullptr;
+  return {};
 }
 
 bool TypeImpl::GetDescription(lldb_private::Stream &strm,

diff  --git a/lldb/source/Symbol/TypeSystem.cpp b/lldb/source/Symbol/TypeSystem.cpp
index ae5ae5cbd659a..7671f11847f45 100644
--- a/lldb/source/Symbol/TypeSystem.cpp
+++ b/lldb/source/Symbol/TypeSystem.cpp
@@ -12,7 +12,7 @@
 #include "lldb/Symbol/CompilerType.h"
 #include "lldb/Target/Language.h"
 
-#include <set>
+#include "llvm/ADT/DenseSet.h"
 
 using namespace lldb_private;
 using namespace lldb;
@@ -37,19 +37,17 @@ bool LanguageSet::operator[](unsigned i) const { return bitvector[i]; }
 
 TypeSystem::~TypeSystem() = default;
 
-static lldb::TypeSystemSP CreateInstanceHelper(lldb::LanguageType language,
-                                               Module *module, Target *target) {
+static TypeSystemSP CreateInstanceHelper(lldb::LanguageType language,
+                                         Module *module, Target *target) {
   uint32_t i = 0;
   TypeSystemCreateInstance create_callback;
   while ((create_callback = PluginManager::GetTypeSystemCreateCallbackAtIndex(
               i++)) != nullptr) {
-    lldb::TypeSystemSP type_system_sp =
-        create_callback(language, module, target);
-    if (type_system_sp)
+    if (auto type_system_sp = create_callback(language, module, target))
       return type_system_sp;
   }
 
-  return lldb::TypeSystemSP();
+  return {};
 }
 
 lldb::TypeSystemSP TypeSystem::CreateInstance(lldb::LanguageType language,
@@ -115,7 +113,7 @@ CompilerType TypeSystem::GetBuiltinTypeByName(ConstString name) {
 }
 
 CompilerType TypeSystem::GetTypeForFormatters(void *type) {
-  return CompilerType(this, type);
+  return CompilerType(weak_from_this(), type);
 }
 
 size_t TypeSystem::GetNumTemplateArguments(lldb::opaque_compiler_type_t type,
@@ -195,13 +193,13 @@ void TypeSystemMap::Clear() {
     map = m_map;
     m_clear_in_progress = true;
   }
-  std::set<TypeSystem *> visited;
-  for (auto pair : map) {
-    TypeSystem *type_system = pair.second.get();
-    if (type_system && !visited.count(type_system)) {
-      visited.insert(type_system);
+  llvm::DenseSet<TypeSystem *> visited;
+  for (auto &pair : map) {
+    if (visited.count(pair.second.get()))
+      continue;
+    visited.insert(pair.second.get());
+    if (lldb::TypeSystemSP type_system = pair.second)
       type_system->Finalize();
-    }
   }
   map.clear();
   {
@@ -211,22 +209,24 @@ void TypeSystemMap::Clear() {
   }
 }
 
-void TypeSystemMap::ForEach(std::function<bool(TypeSystem *)> const &callback) {
+void TypeSystemMap::ForEach(
+    std::function<bool(lldb::TypeSystemSP)> const &callback) {
   std::lock_guard<std::mutex> guard(m_mutex);
   // Use a std::set so we only call the callback once for each unique
-  // TypeSystem instance
-  std::set<TypeSystem *> visited;
-  for (auto pair : m_map) {
+  // TypeSystem instance.
+  llvm::DenseSet<TypeSystem *> visited;
+  for (auto &pair : m_map) {
     TypeSystem *type_system = pair.second.get();
-    if (type_system && !visited.count(type_system)) {
-      visited.insert(type_system);
-      if (!callback(type_system))
-        break;
-    }
+    if (!type_system || visited.count(type_system))
+      continue;
+    visited.insert(type_system);
+    assert(type_system);
+    if (!callback(pair.second))
+      break;
   }
 }
 
-llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage(
+llvm::Expected<lldb::TypeSystemSP> TypeSystemMap::GetTypeSystemForLanguage(
     lldb::LanguageType language,
     llvm::Optional<CreateCallback> create_callback) {
   std::lock_guard<std::mutex> guard(m_mutex);
@@ -237,9 +237,10 @@ llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage(
 
   collection::iterator pos = m_map.find(language);
   if (pos != m_map.end()) {
-    auto *type_system = pos->second.get();
-    if (type_system)
-      return *type_system;
+    if (pos->second) {
+      assert(!pos->second->weak_from_this().expired());
+      return pos->second;
+    }
     return llvm::make_error<llvm::StringError>(
         "TypeSystem for language " +
             llvm::StringRef(Language::GetNameForLanguageType(language)) +
@@ -252,8 +253,8 @@ llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage(
       // Add a new mapping for "language" to point to an already existing
       // TypeSystem that supports this language
       m_map[language] = pair.second;
-      if (pair.second.get())
-        return *pair.second.get();
+      if (pair.second)
+        return pair.second;
       return llvm::make_error<llvm::StringError>(
           "TypeSystem for language " +
               llvm::StringRef(Language::GetNameForLanguageType(language)) +
@@ -269,11 +270,11 @@ llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage(
         llvm::inconvertibleErrorCode());
 
   // Cache even if we get a shared pointer that contains a null type system
-  // back
+  // back.
   TypeSystemSP type_system_sp = (*create_callback)();
   m_map[language] = type_system_sp;
-  if (type_system_sp.get())
-    return *type_system_sp.get();
+  if (type_system_sp)
+    return type_system_sp;
   return llvm::make_error<llvm::StringError>(
       "TypeSystem for language " +
           llvm::StringRef(Language::GetNameForLanguageType(language)) +
@@ -281,7 +282,7 @@ llvm::Expected<TypeSystem &> TypeSystemMap::GetTypeSystemForLanguage(
       llvm::inconvertibleErrorCode());
 }
 
-llvm::Expected<TypeSystem &>
+llvm::Expected<lldb::TypeSystemSP>
 TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
                                         Module *module, bool can_create) {
   if (can_create) {
@@ -293,7 +294,7 @@ TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
   return GetTypeSystemForLanguage(language);
 }
 
-llvm::Expected<TypeSystem &>
+llvm::Expected<lldb::TypeSystemSP>
 TypeSystemMap::GetTypeSystemForLanguage(lldb::LanguageType language,
                                         Target *target, bool can_create) {
   if (can_create) {

diff  --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index a0dd4c54a01a3..694e5dc93e675 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -6072,8 +6072,11 @@ bool Process::CallVoidArgVoidPtrReturn(const Address *address,
     llvm::consumeError(type_system_or_err.takeError());
     return false;
   }
+  auto ts = *type_system_or_err;
+  if (!ts)
+    return false;
   CompilerType void_ptr_type =
-      type_system_or_err->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
+      ts->GetBasicTypeFromAST(eBasicTypeVoid).GetPointerType();
   lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallFunction(
       *thread, *address, void_ptr_type, llvm::ArrayRef<addr_t>(), options));
   if (call_plan_sp) {

diff  --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp
index 6ef0cc83bab36..b600ffe9520d4 100644
--- a/lldb/source/Target/StackFrame.cpp
+++ b/lldb/source/Target/StackFrame.cpp
@@ -1368,9 +1368,11 @@ lldb::ValueObjectSP StackFrame::GuessValueForAddress(lldb::addr_t addr) {
                          "Unable to guess value for given address");
           return ValueObjectSP();
         } else {
+          auto ts = *c_type_system_or_err;
+          if (!ts)
+            return {};
           CompilerType void_ptr_type =
-              c_type_system_or_err
-                  ->GetBasicTypeFromAST(lldb::BasicType::eBasicTypeChar)
+              ts->GetBasicTypeFromAST(lldb::BasicType::eBasicTypeChar)
                   .GetPointerType();
           return ValueObjectMemory::Create(this, "", addr, void_ptr_type);
         }

diff  --git a/lldb/source/Target/Statistics.cpp b/lldb/source/Target/Statistics.cpp
index 118d6c396172c..e0ac00e321fb9 100644
--- a/lldb/source/Target/Statistics.cpp
+++ b/lldb/source/Target/Statistics.cpp
@@ -267,7 +267,7 @@ llvm::json::Value DebuggerStats::ReportStatistics(Debugger &debugger,
     debug_parse_time += module_stat.debug_parse_time;
     debug_index_time += module_stat.debug_index_time;
     debug_info_size += module_stat.debug_info_size;
-    module->ForEachTypeSystem([&](TypeSystem *ts) {
+    module->ForEachTypeSystem([&](lldb::TypeSystemSP ts) {
       if (auto stats = ts->ReportStatistics())
         module_stat.type_system_stats.insert({ts->GetPluginName(), *stats});
       return true;

diff  --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp
index 33a792b683ca4..9e252c4dbb047 100644
--- a/lldb/source/Target/Target.cpp
+++ b/lldb/source/Target/Target.cpp
@@ -2301,7 +2301,7 @@ void Target::ImageSearchPathsChanged(const PathMappingList &path_list,
     target->SetExecutableModule(exe_module_sp, eLoadDependentsYes);
 }
 
-llvm::Expected<TypeSystem &>
+llvm::Expected<lldb::TypeSystemSP>
 Target::GetScratchTypeSystemForLanguage(lldb::LanguageType language,
                                         bool create_on_demand) {
   if (!m_valid)
@@ -2330,14 +2330,15 @@ Target::GetScratchTypeSystemForLanguage(lldb::LanguageType language,
                                                             create_on_demand);
 }
 
-std::vector<TypeSystem *> Target::GetScratchTypeSystems(bool create_on_demand) {
+std::vector<lldb::TypeSystemSP>
+Target::GetScratchTypeSystems(bool create_on_demand) {
   if (!m_valid)
     return {};
 
   // Some TypeSystem instances are associated with several LanguageTypes so
   // they will show up several times in the loop below. The SetVector filters
   // out all duplicates as they serve no use for the caller.
-  llvm::SetVector<TypeSystem *> scratch_type_systems;
+  std::vector<lldb::TypeSystemSP> scratch_type_systems;
 
   LanguageSet languages_for_expressions =
       Language::GetLanguagesSupportingTypeSystemsForExpressions();
@@ -2352,10 +2353,16 @@ std::vector<TypeSystem *> Target::GetScratchTypeSystems(bool create_on_demand) {
                      "system available",
                      Language::GetNameForLanguageType(language));
     else
-      scratch_type_systems.insert(&type_system_or_err.get());
+      if (auto ts = *type_system_or_err)
+        scratch_type_systems.push_back(ts);
   }
-
-  return scratch_type_systems.takeVector();
+  std::sort(scratch_type_systems.begin(), scratch_type_systems.end(),
+            [](lldb::TypeSystemSP a, lldb::TypeSystemSP b) {
+              return a.get() <= b.get();
+            });
+  scratch_type_systems.erase(
+      std::unique(scratch_type_systems.begin(), scratch_type_systems.end()));
+  return scratch_type_systems;
 }
 
 PersistentExpressionState *
@@ -2369,7 +2376,13 @@ Target::GetPersistentExpressionStateForLanguage(lldb::LanguageType language) {
     return nullptr;
   }
 
-  return type_system_or_err->GetPersistentExpressionState();
+  if (auto ts = *type_system_or_err)
+    return ts->GetPersistentExpressionState();
+
+  LLDB_LOG(GetLog(LLDBLog::Target),
+           "Unable to get persistent expression state for language {}",
+           Language::GetNameForLanguageType(language));
+  return nullptr;
 }
 
 UserExpression *Target::GetUserExpressionForLanguage(
@@ -2386,8 +2399,16 @@ UserExpression *Target::GetUserExpressionForLanguage(
     return nullptr;
   }
 
-  auto *user_expr = type_system_or_err->GetUserExpression(
-      expr, prefix, language, desired_type, options, ctx_obj);
+  auto ts = *type_system_or_err;
+  if (!ts) {
+    error.SetErrorStringWithFormat(
+        "Type system for language %s is no longer live",
+        Language::GetNameForLanguageType(language));
+    return nullptr;
+  }
+
+  auto *user_expr = ts->GetUserExpression(expr, prefix, language, desired_type,
+                                          options, ctx_obj);
   if (!user_expr)
     error.SetErrorStringWithFormat(
         "Could not create an expression for language %s",
@@ -2408,9 +2429,15 @@ FunctionCaller *Target::GetFunctionCallerForLanguage(
         llvm::toString(std::move(err)).c_str());
     return nullptr;
   }
-
-  auto *persistent_fn = type_system_or_err->GetFunctionCaller(
-      return_type, function_address, arg_value_list, name);
+  auto ts = *type_system_or_err;
+  if (!ts) {
+    error.SetErrorStringWithFormat(
+        "Type system for language %s is no longer live",
+        Language::GetNameForLanguageType(language));
+    return nullptr;
+  }
+  auto *persistent_fn = ts->GetFunctionCaller(return_type, function_address,
+                                              arg_value_list, name);
   if (!persistent_fn)
     error.SetErrorStringWithFormat(
         "Could not create an expression for language %s",
@@ -2426,10 +2453,15 @@ Target::CreateUtilityFunction(std::string expression, std::string name,
   auto type_system_or_err = GetScratchTypeSystemForLanguage(language);
   if (!type_system_or_err)
     return type_system_or_err.takeError();
-
+  auto ts = *type_system_or_err;
+  if (!ts)
+    return llvm::make_error<llvm::StringError>(
+        llvm::StringRef("Type system for language ") +
+            Language::GetNameForLanguageType(language) +
+            llvm::StringRef(" is no longer live"),
+        llvm::inconvertibleErrorCode());
   std::unique_ptr<UtilityFunction> utility_fn =
-      type_system_or_err->CreateUtilityFunction(std::move(expression),
-                                                std::move(name));
+      ts->CreateUtilityFunction(std::move(expression), std::move(name));
   if (!utility_fn)
     return llvm::make_error<llvm::StringError>(
         llvm::StringRef("Could not create an expression for language") +
@@ -2523,8 +2555,13 @@ ExpressionResults Target::EvaluateExpression(
       LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),
                      "Unable to get scratch type system");
     } else {
-      persistent_var_sp =
-          type_system_or_err->GetPersistentExpressionState()->GetVariable(expr);
+      auto ts = *type_system_or_err;
+      if (!ts)
+        LLDB_LOG_ERROR(GetLog(LLDBLog::Target), std::move(err),
+                       "Scratch type system is no longer live");
+      else
+        persistent_var_sp =
+            ts->GetPersistentExpressionState()->GetVariable(expr);
     }
   }
   if (persistent_var_sp) {
@@ -2552,9 +2589,12 @@ ExpressionResults Target::EvaluateExpression(
 lldb::ExpressionVariableSP Target::GetPersistentVariable(ConstString name) {
   lldb::ExpressionVariableSP variable_sp;
   m_scratch_type_system_map.ForEach(
-      [name, &variable_sp](TypeSystem *type_system) -> bool {
+      [name, &variable_sp](TypeSystemSP type_system) -> bool {
+        auto ts = type_system.get();
+        if (!ts)
+          return true;
         if (PersistentExpressionState *persistent_state =
-                type_system->GetPersistentExpressionState()) {
+                ts->GetPersistentExpressionState()) {
           variable_sp = persistent_state->GetVariable(name);
 
           if (variable_sp)
@@ -2569,9 +2609,13 @@ lldb::addr_t Target::GetPersistentSymbol(ConstString name) {
   lldb::addr_t address = LLDB_INVALID_ADDRESS;
 
   m_scratch_type_system_map.ForEach(
-      [name, &address](TypeSystem *type_system) -> bool {
+      [name, &address](lldb::TypeSystemSP type_system) -> bool {
+        auto ts = type_system.get();
+        if (!ts)
+          return true;
+
         if (PersistentExpressionState *persistent_state =
-                type_system->GetPersistentExpressionState()) {
+                ts->GetPersistentExpressionState()) {
           address = persistent_state->LookupSymbol(name);
           if (address != LLDB_INVALID_ADDRESS)
             return false; // Stop iterating the ForEach

diff  --git a/lldb/source/Target/ThreadPlanTracer.cpp b/lldb/source/Target/ThreadPlanTracer.cpp
index 7e09253076443..82927ef648775 100644
--- a/lldb/source/Target/ThreadPlanTracer.cpp
+++ b/lldb/source/Target/ThreadPlanTracer.cpp
@@ -110,10 +110,10 @@ TypeFromUser ThreadPlanAssemblyTracer::GetIntPointerType() {
         LLDB_LOG_ERROR(GetLog(LLDBLog::Types), std::move(err),
                        "Unable to get integer pointer type from TypeSystem");
       } else {
-        m_intptr_type = TypeFromUser(
-            type_system_or_err->GetBuiltinTypeForEncodingAndBitSize(
-                eEncodingUint,
-                target_sp->GetArchitecture().GetAddressByteSize() * 8));
+        if (auto ts = *type_system_or_err)
+          m_intptr_type = TypeFromUser(ts->GetBuiltinTypeForEncodingAndBitSize(
+              eEncodingUint,
+              target_sp->GetArchitecture().GetAddressByteSize() * 8));
       }
     }
   }

diff  --git a/lldb/tools/lldb-test/lldb-test.cpp b/lldb/tools/lldb-test/lldb-test.cpp
index b3651314b7f22..887cd14ffb63c 100644
--- a/lldb/tools/lldb-test/lldb-test.cpp
+++ b/lldb/tools/lldb-test/lldb-test.cpp
@@ -658,13 +658,13 @@ Error opts::symbols::dumpAST(lldb_private::Module &Module) {
   if (!symfile)
     return make_string_error("Module has no symbol file.");
 
-  llvm::Expected<TypeSystem &> type_system_or_err =
+  auto type_system_or_err =
       symfile->GetTypeSystemForLanguage(eLanguageTypeC_plus_plus);
   if (!type_system_or_err)
     return make_string_error("Can't retrieve TypeSystemClang");
 
-  auto *clang_ast_ctx =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+  auto ts = *type_system_or_err;
+  auto *clang_ast_ctx = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang_ast_ctx)
     return make_string_error("Retrieved TypeSystem was not a TypeSystemClang");
 
@@ -686,13 +686,12 @@ Error opts::symbols::dumpEntireClangAST(lldb_private::Module &Module) {
   if (!symfile)
     return make_string_error("Module has no symbol file.");
 
-  llvm::Expected<TypeSystem &> type_system_or_err =
+  auto type_system_or_err =
       symfile->GetTypeSystemForLanguage(eLanguageTypeObjC_plus_plus);
   if (!type_system_or_err)
     return make_string_error("Can't retrieve TypeSystemClang");
-
-  auto *clang_ast_ctx =
-      llvm::dyn_cast_or_null<TypeSystemClang>(&type_system_or_err.get());
+  auto ts = *type_system_or_err;
+  auto *clang_ast_ctx = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
   if (!clang_ast_ctx)
     return make_string_error("Retrieved TypeSystem was not a TypeSystemClang");
 

diff  --git a/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp b/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp
index ecee35ff46eb4..77bd85bcb942c 100644
--- a/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp
+++ b/lldb/unittests/Expression/ClangExpressionDeclMapTest.cpp
@@ -24,9 +24,11 @@ struct FakeClangExpressionDeclMap : public ClangExpressionDeclMap {
   FakeClangExpressionDeclMap(const std::shared_ptr<ClangASTImporter> &importer)
       : ClangExpressionDeclMap(false, nullptr, lldb::TargetSP(), importer,
                                nullptr) {
-    m_scratch_context = clang_utils::createAST();
+    m_holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
+    m_scratch_context = m_holder->GetAST();
   }
-  std::unique_ptr<TypeSystemClang> m_scratch_context;
+  std::unique_ptr<clang_utils::TypeSystemClangHolder> m_holder;
+  TypeSystemClang *m_scratch_context;
   /// Adds a persistent decl that can be found by the ClangExpressionDeclMap
   /// via GetPersistentDecl.
   void AddPersistentDeclForTest(clang::NamedDecl *d) {
@@ -62,20 +64,23 @@ struct ClangExpressionDeclMapTest : public testing::Test {
   /// The ExpressionDeclMap for the current test case.
   std::unique_ptr<FakeClangExpressionDeclMap> decl_map;
 
+  std::unique_ptr<clang_utils::TypeSystemClangHolder> holder;
+  
   /// The target AST that lookup results should be imported to.
-  std::unique_ptr<TypeSystemClang> target_ast;
+  TypeSystemClang *target_ast;
 
   void SetUp() override {
     importer = std::make_shared<ClangASTImporter>();
     decl_map = std::make_unique<FakeClangExpressionDeclMap>(importer);
-    target_ast = clang_utils::createAST();
+    holder = std::make_unique<clang_utils::TypeSystemClangHolder>("target ast");
+    target_ast = holder->GetAST();
     decl_map->InstallASTContext(*target_ast);
   }
 
   void TearDown() override {
     importer.reset();
     decl_map.reset();
-    target_ast.reset();
+    holder.reset();
   }
 };
 } // namespace

diff  --git a/lldb/unittests/Symbol/TestClangASTImporter.cpp b/lldb/unittests/Symbol/TestClangASTImporter.cpp
index c8ffd099716a7..de59efe533eb9 100644
--- a/lldb/unittests/Symbol/TestClangASTImporter.cpp
+++ b/lldb/unittests/Symbol/TestClangASTImporter.cpp
@@ -42,7 +42,9 @@ TEST_F(TestClangASTImporter, CopyDeclTagDecl) {
   // Tests that the ClangASTImporter::CopyDecl can copy TagDecls.
   clang_utils::SourceASTWithRecord source;
 
-  std::unique_ptr<TypeSystemClang> target_ast = clang_utils::createAST();
+  auto holder =
+      std::make_unique<clang_utils::TypeSystemClangHolder>("target ast");
+  auto *target_ast = holder->GetAST();
 
   ClangASTImporter importer;
   clang::Decl *imported =
@@ -67,7 +69,9 @@ TEST_F(TestClangASTImporter, CopyTypeTagDecl) {
   // Tests that the ClangASTImporter::CopyType can copy TagDecls types.
   clang_utils::SourceASTWithRecord source;
 
-  std::unique_ptr<TypeSystemClang> target_ast = clang_utils::createAST();
+  auto holder =
+      std::make_unique<clang_utils::TypeSystemClangHolder>("target ast");
+  auto *target_ast = holder->GetAST();
 
   ClangASTImporter importer;
   CompilerType imported = importer.CopyType(*target_ast, source.record_type);
@@ -94,12 +98,16 @@ TEST_F(TestClangASTImporter, CompleteFwdDeclWithOtherOrigin) {
 
   // Create an AST with a type thst is only a forward declaration with the
   // same name as the one in the other source.
-  std::unique_ptr<TypeSystemClang> fwd_decl_source = clang_utils::createAST();
+  auto holder =
+      std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
+  auto *fwd_decl_source = holder->GetAST();
   CompilerType fwd_decl_type = clang_utils::createRecord(
       *fwd_decl_source, source_with_definition.record_decl->getName());
 
   // Create a target and import the forward decl.
-  std::unique_ptr<TypeSystemClang> target = clang_utils::createAST();
+  auto target_holder =
+      std::make_unique<clang_utils::TypeSystemClangHolder>("target ast");
+  auto *target = target_holder->GetAST();
   ClangASTImporter importer;
   CompilerType imported = importer.CopyType(*target, fwd_decl_type);
   ASSERT_TRUE(imported.IsValid());
@@ -119,7 +127,9 @@ TEST_F(TestClangASTImporter, DeportDeclTagDecl) {
   // Tests that the ClangASTImporter::DeportDecl completely copies TagDecls.
   clang_utils::SourceASTWithRecord source;
 
-  std::unique_ptr<TypeSystemClang> target_ast = clang_utils::createAST();
+  auto holder =
+      std::make_unique<clang_utils::TypeSystemClangHolder>("target ast");
+  auto *target_ast = holder->GetAST();
 
   ClangASTImporter importer;
   clang::Decl *imported =
@@ -141,7 +151,9 @@ TEST_F(TestClangASTImporter, DeportTypeTagDecl) {
   // Tests that the ClangASTImporter::CopyType can deport TagDecl types.
   clang_utils::SourceASTWithRecord source;
 
-  std::unique_ptr<TypeSystemClang> target_ast = clang_utils::createAST();
+  auto holder =
+      std::make_unique<clang_utils::TypeSystemClangHolder>("target ast");
+  auto *target_ast = holder->GetAST();
 
   ClangASTImporter importer;
   CompilerType imported = importer.DeportType(*target_ast, source.record_type);
@@ -166,7 +178,9 @@ TEST_F(TestClangASTImporter, MetadataPropagation) {
   const lldb::user_id_t metadata = 123456;
   source.ast->SetMetadataAsUserID(source.record_decl, metadata);
 
-  std::unique_ptr<TypeSystemClang> target_ast = clang_utils::createAST();
+  auto holder =
+      std::make_unique<clang_utils::TypeSystemClangHolder>("target ast");
+  auto *target_ast = holder->GetAST();
 
   ClangASTImporter importer;
   clang::Decl *imported =
@@ -188,14 +202,18 @@ TEST_F(TestClangASTImporter, MetadataPropagationIndirectImport) {
   const lldb::user_id_t metadata = 123456;
   source.ast->SetMetadataAsUserID(source.record_decl, metadata);
 
-  std::unique_ptr<TypeSystemClang> temporary_ast = clang_utils::createAST();
+  auto tmp_holder =
+      std::make_unique<clang_utils::TypeSystemClangHolder>("tmp ast");
+  auto *temporary_ast = tmp_holder->GetAST();
 
   ClangASTImporter importer;
   clang::Decl *temporary_imported =
       importer.CopyDecl(&temporary_ast->getASTContext(), source.record_decl);
   ASSERT_NE(nullptr, temporary_imported);
 
-  std::unique_ptr<TypeSystemClang> target_ast = clang_utils::createAST();
+  auto holder =
+      std::make_unique<clang_utils::TypeSystemClangHolder>("target ast");
+  auto *target_ast = holder->GetAST();
   clang::Decl *imported =
       importer.CopyDecl(&target_ast->getASTContext(), temporary_imported);
   ASSERT_NE(nullptr, imported);
@@ -212,7 +230,9 @@ TEST_F(TestClangASTImporter, MetadataPropagationAfterCopying) {
   clang_utils::SourceASTWithRecord source;
   const lldb::user_id_t metadata = 123456;
 
-  std::unique_ptr<TypeSystemClang> target_ast = clang_utils::createAST();
+  auto holder =
+      std::make_unique<clang_utils::TypeSystemClangHolder>("target ast");
+  auto *target_ast = holder->GetAST();
 
   ClangASTImporter importer;
   clang::Decl *imported =

diff  --git a/lldb/unittests/Symbol/TestTypeSystemClang.cpp b/lldb/unittests/Symbol/TestTypeSystemClang.cpp
index 23594340e71b3..db92aaf8887c7 100644
--- a/lldb/unittests/Symbol/TestTypeSystemClang.cpp
+++ b/lldb/unittests/Symbol/TestTypeSystemClang.cpp
@@ -27,14 +27,20 @@ class TestTypeSystemClang : public testing::Test {
   SubsystemRAII<FileSystem, HostInfo> subsystems;
 
   void SetUp() override {
-    m_ast.reset(
-        new TypeSystemClang("test ASTContext", HostInfo::GetTargetTriple()));
+    m_holder =
+        std::make_unique<clang_utils::TypeSystemClangHolder>("test ASTContext");
+    m_ast = m_holder->GetAST();
   }
 
-  void TearDown() override { m_ast.reset(); }
+  void TearDown() override {
+    m_ast = nullptr;
+    m_holder.reset();
+  }
 
 protected:
-  std::unique_ptr<TypeSystemClang> m_ast;
+  
+  TypeSystemClang *m_ast = nullptr;
+  std::unique_ptr<clang_utils::TypeSystemClangHolder> m_holder;
 
   QualType GetBasicQualType(BasicType type) const {
     return ClangUtil::GetQualType(m_ast->GetBasicTypeFromAST(type));
@@ -257,7 +263,10 @@ TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) {
     for (lldb::BasicType basic_type : types_to_test) {
       SCOPED_TRACE(std::to_string(basic_type));
 
-      TypeSystemClang ast("enum_ast", HostInfo::GetTargetTriple());
+      auto holder =
+          std::make_unique<clang_utils::TypeSystemClangHolder>("enum_ast");
+      auto &ast = *holder->GetAST();
+
       CompilerType basic_compiler_type = ast.GetBasicType(basic_type);
       EXPECT_TRUE(basic_compiler_type.IsValid());
 
@@ -273,7 +282,9 @@ TEST_F(TestTypeSystemClang, TestGetEnumIntegerTypeBasicTypes) {
 }
 
 TEST_F(TestTypeSystemClang, TestOwningModule) {
-  TypeSystemClang ast("module_ast", HostInfo::GetTargetTriple());
+  auto holder =
+      std::make_unique<clang_utils::TypeSystemClangHolder>("module_ast");
+  auto &ast = *holder->GetAST();
   CompilerType basic_compiler_type = ast.GetBasicType(BasicType::eBasicTypeInt);
   CompilerType enum_type = ast.CreateEnumerationType(
       "my_enum", ast.GetTranslationUnitDecl(), OptionalClangModuleID(100),
@@ -301,7 +312,7 @@ TEST_F(TestTypeSystemClang, TestIsClangType) {
   clang::ASTContext &context = m_ast->getASTContext();
   lldb::opaque_compiler_type_t bool_ctype =
       TypeSystemClang::GetOpaqueCompilerType(&context, lldb::eBasicTypeBool);
-  CompilerType bool_type(m_ast.get(), bool_ctype);
+  CompilerType bool_type(m_ast->weak_from_this(), bool_ctype);
   CompilerType record_type = m_ast->CreateRecordType(
       nullptr, OptionalClangModuleID(100), lldb::eAccessPublic, "FooRecord",
       clang::TTK_Struct, lldb::eLanguageTypeC_plus_plus, nullptr);
@@ -489,13 +500,13 @@ TEST_F(TestTypeSystemClang, TemplateArguments) {
       "foo_def", m_ast->CreateDeclContext(m_ast->GetTranslationUnitDecl()), 0);
 
   CompilerType auto_type(
-      m_ast.get(),
+      m_ast->weak_from_this(),
       m_ast->getASTContext()
           .getAutoType(ClangUtil::GetCanonicalQualType(typedef_type),
                        clang::AutoTypeKeyword::Auto, false)
           .getAsOpaquePtr());
 
-  CompilerType int_type(m_ast.get(),
+  CompilerType int_type(m_ast->weak_from_this(),
                         m_ast->getASTContext().IntTy.getAsOpaquePtr());
   for (CompilerType t : {type, typedef_type, auto_type}) {
     SCOPED_TRACE(t.GetTypeName().AsCString());

diff  --git a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
index 3903aa75f1ce5..4d1c2aefb0a44 100644
--- a/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
+++ b/lldb/unittests/SymbolFile/DWARF/DWARFASTParserClangTests.cpp
@@ -9,6 +9,7 @@
 #include "Plugins/SymbolFile/DWARF/DWARFASTParserClang.h"
 #include "Plugins/SymbolFile/DWARF/DWARFCompileUnit.h"
 #include "Plugins/SymbolFile/DWARF/DWARFDIE.h"
+#include "TestingSupport/Symbol/ClangTestUtils.h"
 #include "TestingSupport/Symbol/YAMLModuleTester.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
@@ -93,7 +94,9 @@ TEST_F(DWARFASTParserClangTests,
   YAMLModuleTester t(yamldata);
   ASSERT_TRUE((bool)t.GetDwarfUnit());
 
-  TypeSystemClang ast_ctx("dummy ASTContext", HostInfoBase::GetTargetTriple());
+  auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
+  auto &ast_ctx = *holder->GetAST();
+
   DWARFASTParserClangStub ast_parser(ast_ctx);
 
   DWARFUnit *unit = t.GetDwarfUnit();
@@ -244,7 +247,8 @@ TEST_F(DWARFASTParserClangTests, TestCallingConventionParsing) {
   ASSERT_EQ(cu_entry->Tag(), DW_TAG_compile_unit);
   DWARFDIE cu_die(unit, cu_entry);
 
-  TypeSystemClang ast_ctx("dummy ASTContext", HostInfoBase::GetTargetTriple());
+  auto holder = std::make_unique<clang_utils::TypeSystemClangHolder>("ast");
+  auto &ast_ctx = *holder->GetAST();
   DWARFASTParserClangStub ast_parser(ast_ctx);
 
   std::vector<std::string> found_function_types;
@@ -276,10 +280,12 @@ TEST_F(DWARFASTParserClangTests, TestCallingConventionParsing) {
 
 struct ExtractIntFromFormValueTest : public testing::Test {
   SubsystemRAII<FileSystem, HostInfo> subsystems;
-  TypeSystemClang ts;
+  clang_utils::TypeSystemClangHolder holder;
+  TypeSystemClang &ts;
+
   DWARFASTParserClang parser;
   ExtractIntFromFormValueTest()
-      : ts("dummy ASTContext", HostInfoBase::GetTargetTriple()), parser(ts) {}
+      : holder("dummy ASTContext"), ts(*holder.GetAST()), parser(ts) {}
 
   /// Takes the given integer value, stores it in a DWARFFormValue and then
   /// tries to extract the value back via

diff  --git a/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h b/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
index 6524f093ab957..21525266119b4 100644
--- a/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
+++ b/lldb/unittests/TestingSupport/Symbol/ClangTestUtils.h
@@ -21,11 +21,6 @@ inline clang::DeclarationName getDeclarationName(TypeSystemClang &ast,
   return ast.getASTContext().DeclarationNames.getIdentifier(&II);
 }
 
-inline std::unique_ptr<TypeSystemClang> createAST() {
-  return std::make_unique<TypeSystemClang>("test ASTContext",
-                                           HostInfo::GetTargetTriple());
-}
-
 inline CompilerType createRecord(TypeSystemClang &ast, llvm::StringRef name) {
   return ast.CreateRecordType(ast.getASTContext().getTranslationUnitDecl(),
                               OptionalClangModuleID(),
@@ -49,16 +44,28 @@ inline CompilerType createRecordWithField(TypeSystemClang &ast,
   return t;
 }
 
+/// Simulates a Clang type system owned by a TypeSystemMap.
+class TypeSystemClangHolder {
+  std::shared_ptr<TypeSystemClang> m_ast;
+public:
+  TypeSystemClangHolder(const char *name)
+      : m_ast(std::make_shared<TypeSystemClang>(name,
+                                                HostInfo::GetTargetTriple())) {}
+  TypeSystemClang *GetAST() const { return m_ast.get(); }
+};
+  
 /// Constructs a TypeSystemClang that contains a single RecordDecl that contains
 /// a single FieldDecl. Utility class as this setup is a common starting point
 /// for unit test that exercise the ASTImporter.
 struct SourceASTWithRecord {
-  std::unique_ptr<TypeSystemClang> ast;
+  std::unique_ptr<TypeSystemClangHolder> holder;
+  TypeSystemClang *ast;
   CompilerType record_type;
   clang::RecordDecl *record_decl = nullptr;
   clang::FieldDecl *field_decl = nullptr;
   SourceASTWithRecord() {
-    ast = createAST();
+    holder = std::make_unique<TypeSystemClangHolder>("test ASTContext");
+    ast = holder->GetAST();
     record_type = createRecordWithField(
         *ast, "Source", ast->GetBasicType(lldb::BasicType::eBasicTypeChar),
         "a_field");


        


More information about the lldb-commits mailing list