diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td
index 60cc6ec..1a99c6c 100644
--- a/include/clang/Driver/CC1Options.td
+++ b/include/clang/Driver/CC1Options.td
@@ -369,6 +369,9 @@ def fmodules_local_submodule_visibility :
   Flag<["-"], "fmodules-local-submodule-visibility">,
   HelpText<"Enforce name visibility rules across submodules of the same "
            "top-level module.">;
+def fmodule_format_EQ : Joined<["-"], "fmodule-format=">,
+  HelpText<"Select the container format for clang modules and PCH. "
+           "Supported options are `raw' and `obj'.">;
 def fno_modules_hide_internal_linkage :
   Flag<["-"], "fno-modules-hide-internal-linkage">,
   HelpText<"Make all declarations visible to redeclaration lookup, "
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 803d023..a810bfb 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -156,6 +156,9 @@ VALUE_CODEGENOPT(StackProbeSize    , 32, 4096) ///< Overrides default stack
 CODEGENOPT(DebugColumnInfo, 1, 0) ///< Whether or not to use column information
                                   ///< in debug info.
 
+CODEGENOPT(RawPCHContainer, 1, 0) ///< Whether to use object files containers
+                                  ///< for clang modules or just raw asts.
+
 CODEGENOPT(EmitLLVMUseLists, 1, 0) ///< Control whether to serialize use-lists.
 
 /// The user specified number of registers to be used for integral arguments,
diff --git a/include/clang/Frontend/CompilerInstance.h b/include/clang/Frontend/CompilerInstance.h
index 2f3e1b6..49f4688 100644
--- a/include/clang/Frontend/CompilerInstance.h
+++ b/include/clang/Frontend/CompilerInstance.h
@@ -505,6 +505,11 @@ public:
       std::shared_ptr<ModuleDependencyCollector> Collector);
 
   std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
+    if (1 || (hasInvocation() && getCodeGenOpts().RawPCHContainer)) {
+      // Raw PCH format was requested on the command line.
+      return std::make_shared<RawPCHContainerOperations>();
+    }
+
     return ThePCHContainerOperations;
   }
 
@@ -621,7 +626,7 @@ public:
   static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
       StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
       bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
-      const PCHContainerOperations &PCHContainerOps,
+      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
       void *DeserializationListener, bool OwnDeserializationListener,
       bool Preamble, bool UseGlobalModuleIndex);
 
diff --git a/include/clang/Frontend/Utils.h b/include/clang/Frontend/Utils.h
index 6399653..982456a 100644
--- a/include/clang/Frontend/Utils.h
+++ b/include/clang/Frontend/Utils.h
@@ -62,9 +62,10 @@ void ApplyHeaderSearchOptions(HeaderSearch &HS,
 
 /// InitializePreprocessor - Initialize the preprocessor getting it and the
 /// environment ready to process a single file.
-void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts,
-                            const PCHContainerOperations &PCHContainerOps,
-                            const FrontendOptions &FEOpts);
+void InitializePreprocessor(
+    Preprocessor &PP, const PreprocessorOptions &PPOpts,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    const FrontendOptions &FEOpts);
 
 /// DoPrintPreprocessedInput - Implement -E mode.
 void DoPrintPreprocessedInput(Preprocessor &PP, raw_ostream* OS,
diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h
index 9377dfa..2351d92 100644
--- a/include/clang/Serialization/ASTReader.h
+++ b/include/clang/Serialization/ASTReader.h
@@ -362,7 +362,7 @@ private:
 
   SourceManager &SourceMgr;
   FileManager &FileMgr;
-  const PCHContainerOperations &PCHContainerOps;
+  std::shared_ptr<PCHContainerOperations> PCHContainerOps;
   DiagnosticsEngine &Diags;
 
   /// \brief The semantic analysis object that will be processing the
@@ -1289,7 +1289,7 @@ public:
   /// \param ReadTimer If non-null, a timer used to track the time spent
   /// deserializing.
   ASTReader(Preprocessor &PP, ASTContext &Context,
-            const PCHContainerOperations &PCHContainerOps,
+            std::shared_ptr<PCHContainerOperations> PCHContainerOps,
             StringRef isysroot = "", bool DisableValidation = false,
             bool AllowASTWithCompilerErrors = false,
             bool AllowConfigurationMismatch = false,
@@ -1458,25 +1458,24 @@ public:
   /// the AST file, without actually loading the AST file.
   static std::string
   getOriginalSourceFile(const std::string &ASTFileName, FileManager &FileMgr,
-                        const PCHContainerOperations &PCHContainerOps,
+                        std::shared_ptr<PCHContainerOperations> PCHContainerOps,
                         DiagnosticsEngine &Diags);
 
   /// \brief Read the control block for the named AST file.
   ///
   /// \returns true if an error occurred, false otherwise.
-  static bool
-  readASTFileControlBlock(StringRef Filename, FileManager &FileMgr,
-                          const PCHContainerOperations &PCHContainerOps,
-                          ASTReaderListener &Listener);
+  static bool readASTFileControlBlock(
+      StringRef Filename, FileManager &FileMgr,
+      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+      ASTReaderListener &Listener);
 
   /// \brief Determine whether the given AST file is acceptable to load into a
   /// translation unit with the given language and target options.
-  static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
-                                  const PCHContainerOperations &PCHContainerOps,
-                                  const LangOptions &LangOpts,
-                                  const TargetOptions &TargetOpts,
-                                  const PreprocessorOptions &PPOpts,
-                                  std::string ExistingModuleCachePath);
+  static bool isAcceptableASTFile(
+      StringRef Filename, FileManager &FileMgr,
+      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+      const LangOptions &LangOpts, const TargetOptions &TargetOpts,
+      const PreprocessorOptions &PPOpts, std::string ExistingModuleCachePath);
 
   /// \brief Returns the suggested contents of the predefines buffer,
   /// which contains a (typically-empty) subset of the predefines
diff --git a/include/clang/Serialization/GlobalModuleIndex.h b/include/clang/Serialization/GlobalModuleIndex.h
index 7e20510..cf5ea55 100644
--- a/include/clang/Serialization/GlobalModuleIndex.h
+++ b/include/clang/Serialization/GlobalModuleIndex.h
@@ -197,11 +197,11 @@ public:
   /// creating modules.
   /// \param Path The path to the directory containing module files, into
   /// which the global index will be written.
-  static ErrorCode writeIndex(FileManager &FileMgr,
-                              const PCHContainerOperations &PCHContainerOps,
-                              StringRef Path);
+  static ErrorCode
+  writeIndex(FileManager &FileMgr,
+             std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+             StringRef Path);
 };
-
 }
 
 #endif
diff --git a/include/clang/Serialization/ModuleManager.h b/include/clang/Serialization/ModuleManager.h
index ea4b57f..585f8dc 100644
--- a/include/clang/Serialization/ModuleManager.h
+++ b/include/clang/Serialization/ModuleManager.h
@@ -52,7 +52,7 @@ class ModuleManager {
   FileManager &FileMgr;
 
   /// \brief Knows how to unwrap module containers.
-  const PCHContainerOperations &PCHContainerOps;
+  std::shared_ptr<PCHContainerOperations> PCHContainerOps;
 
   /// \brief A lookup of in-memory (virtual file) buffers
   llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>>
@@ -117,10 +117,11 @@ public:
   typedef SmallVectorImpl<ModuleFile*>::reverse_iterator ModuleReverseIterator;
   typedef std::pair<uint32_t, StringRef> ModuleOffset;
 
-  explicit ModuleManager(FileManager &FileMgr,
-                         const PCHContainerOperations &PCHContainerOps);
+  explicit ModuleManager(
+      FileManager &FileMgr,
+      std::shared_ptr<PCHContainerOperations> PCHContainerOps);
   ~ModuleManager();
-  
+
   /// \brief Forward iterator to traverse all loaded modules.  This is reverse
   /// source-order.
   ModuleIterator begin() { return Chain.begin(); }
diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp
index f33ad21..1e2c603 100644
--- a/lib/ARCMigrate/ARCMT.cpp
+++ b/lib/ARCMigrate/ARCMT.cpp
@@ -165,9 +165,9 @@ static bool HasARCRuntime(CompilerInvocation &origCI) {
   return false;
 }
 
-static CompilerInvocation *
-createInvocationForMigration(CompilerInvocation &origCI,
-                             const PCHContainerOperations &PCHContainerOps) {
+static CompilerInvocation *createInvocationForMigration(
+    CompilerInvocation &origCI,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
   std::unique_ptr<CompilerInvocation> CInvok;
   CInvok.reset(new CompilerInvocation(origCI));
   PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
@@ -247,7 +247,7 @@ bool arcmt::checkForManualIssues(
   assert(!transforms.empty());
 
   std::unique_ptr<CompilerInvocation> CInvok;
-  CInvok.reset(createInvocationForMigration(origCI, *PCHContainerOps));
+  CInvok.reset(createInvocationForMigration(origCI, PCHContainerOps));
   CInvok->getFrontendOpts().Inputs.clear();
   CInvok->getFrontendOpts().Inputs.push_back(Input);
 
@@ -517,7 +517,7 @@ MigrationProcess::MigrationProcess(
 bool MigrationProcess::applyTransform(TransformFn trans,
                                       RewriteListener *listener) {
   std::unique_ptr<CompilerInvocation> CInvok;
-  CInvok.reset(createInvocationForMigration(OrigCI, *PCHContainerOps));
+  CInvok.reset(createInvocationForMigration(OrigCI, PCHContainerOps));
   CInvok->getDiagnosticOpts().IgnoreWarnings = true;
 
   Remapper.applyMappings(CInvok->getPreprocessorOpts());
diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp
index 8c11992..f34a434 100644
--- a/lib/Driver/Tools.cpp
+++ b/lib/Driver/Tools.cpp
@@ -3588,6 +3588,12 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
     CmdArgs.push_back("-split-dwarf=Enable");
   }
 
+  // On platforms that default to a global shared module cache rather
+  // than building modules explicitly, default to the object file
+  // pch container format, which can also hold debug info.
+  if (getToolChain().getTriple().isOSDarwin())
+    CmdArgs.push_back("-fmodule-format=obj");
+
   // -ggnu-pubnames turns on gnu style pubnames in the backend.
   if (Args.hasArg(options::OPT_ggnu_pubnames)) {
     CmdArgs.push_back("-backend-option");
diff --git a/lib/Frontend/ASTUnit.cpp b/lib/Frontend/ASTUnit.cpp
index 57c97d0..8bee1c3 100644
--- a/lib/Frontend/ASTUnit.cpp
+++ b/lib/Frontend/ASTUnit.cpp
@@ -708,7 +708,7 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
   bool disableValid = false;
   if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
     disableValid = true;
-  AST->Reader = new ASTReader(PP, Context, *PCHContainerOps,
+  AST->Reader = new ASTReader(PP, Context, PCHContainerOps,
                               /*isysroot=*/"",
                               /*DisableValidation=*/disableValid,
                               AllowPCHWithCompilerErrors);
diff --git a/lib/Frontend/ChainedIncludesSource.cpp b/lib/Frontend/ChainedIncludesSource.cpp
index be30d43..ca6a036 100644
--- a/lib/Frontend/ChainedIncludesSource.cpp
+++ b/lib/Frontend/ChainedIncludesSource.cpp
@@ -81,7 +81,7 @@ createASTReader(CompilerInstance &CI, StringRef pchFile,
   Preprocessor &PP = CI.getPreprocessor();
   std::unique_ptr<ASTReader> Reader;
   Reader.reset(new ASTReader(PP, CI.getASTContext(),
-                             *CI.getPCHContainerOperations(),
+                             CI.getPCHContainerOperations(),
                              /*isysroot=*/"", /*DisableValidation=*/true));
   for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
     StringRef sr(bufNames[ti]);
diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp
index ff041a8..c855e54 100644
--- a/lib/Frontend/CompilerInstance.cpp
+++ b/lib/Frontend/CompilerInstance.cpp
@@ -322,7 +322,7 @@ void CompilerInstance::createPreprocessor(TranslationUnitKind TUKind) {
                           PP->getFileManager(), PPOpts);
 
   // Predefine macros and configure the preprocessor.
-  InitializePreprocessor(*PP, PPOpts, *getPCHContainerOperations(),
+  InitializePreprocessor(*PP, PPOpts, getPCHContainerOperations(),
                          getFrontendOpts());
 
   // Initialize the header search object.
@@ -399,7 +399,7 @@ void CompilerInstance::createPCHExternalASTSource(
   ModuleManager = createPCHExternalASTSource(
       Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,
       AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(),
-      *getPCHContainerOperations(), DeserializationListener,
+      getPCHContainerOperations(), DeserializationListener,
       OwnDeserializationListener, Preamble,
       getFrontendOpts().UseGlobalModuleIndex);
 }
@@ -407,7 +407,7 @@ void CompilerInstance::createPCHExternalASTSource(
 IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
     StringRef Path, StringRef Sysroot, bool DisablePCHValidation,
     bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
-    const PCHContainerOperations &PCHContainerOps,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     void *DeserializationListener, bool OwnDeserializationListener,
     bool Preamble, bool UseGlobalModuleIndex) {
   HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
@@ -1244,7 +1244,7 @@ void CompilerInstance::createModuleManager() {
       ReadTimer = llvm::make_unique<llvm::Timer>("Reading modules",
                                                  *FrontendTimerGroup);
     ModuleManager = new ASTReader(
-        getPreprocessor(), *Context, *getPCHContainerOperations(),
+        getPreprocessor(), *Context, getPCHContainerOperations(),
         Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation,
         /*AllowASTWithCompilerErrors=*/false,
         /*AllowConfigurationMismatch=*/false,
@@ -1296,7 +1296,7 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) {
       ModuleFileStack.push_back(FileName);
       ModuleNameStack.push_back(StringRef());
       if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),
-                                             *CI.getPCHContainerOperations(),
+                                             CI.getPCHContainerOperations(),
                                              *this)) {
         CI.getDiagnostics().Report(
             SourceLocation(), CI.getFileManager().getBufferForFile(FileName)
@@ -1667,7 +1667,7 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
     llvm::sys::fs::create_directories(
       getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
     GlobalModuleIndex::writeIndex(
-        getFileManager(), *getPCHContainerOperations(),
+        getFileManager(), getPCHContainerOperations(),
         getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
     ModuleManager->resetForReload();
     ModuleManager->loadGlobalIndex();
@@ -1695,7 +1695,7 @@ GlobalModuleIndex *CompilerInstance::loadGlobalModuleIndex(
     }
     if (RecreateIndex) {
       GlobalModuleIndex::writeIndex(
-          getFileManager(), *getPCHContainerOperations(),
+          getFileManager(), getPCHContainerOperations(),
           getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
       ModuleManager->resetForReload();
       ModuleManager->loadGlobalIndex();
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 6f13faf..c9c0d36 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -421,6 +421,18 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
     // Default Dwarf version is 4 if we are generating debug information.
     Opts.DwarfVersion = 4;
 
+  if (const Arg *A = Args.getLastArg(OPT_fmodule_format_EQ)) {
+    StringRef Format = A->getValue();
+    if (Format == "obj")
+      Opts.RawPCHContainer = false;
+    else if (Format == "raw")
+      Opts.RawPCHContainer = true;
+    else {
+      Diags.Report(diag::err_drv_invalid_value) << "-fmodule-format="
+                                                << A->getValue();
+    }
+  }
+
   if (const Arg *A =
           Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists))
     Opts.EmitLLVMUseLists = A->getOption().getID() == OPT_emit_llvm_uselists;
diff --git a/lib/Frontend/FrontendAction.cpp b/lib/Frontend/FrontendAction.cpp
index db9dd3b..25d2a4c 100644
--- a/lib/Frontend/FrontendAction.cpp
+++ b/lib/Frontend/FrontendAction.cpp
@@ -273,7 +273,7 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
            Dir != DirEnd && !EC; Dir.increment(EC)) {
         // Check whether this is an acceptable AST file.
         if (ASTReader::isAcceptableASTFile(
-                Dir->path(), FileMgr, *CI.getPCHContainerOperations(),
+                Dir->path(), FileMgr, CI.getPCHContainerOperations(),
                 CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(),
                 SpecificModuleCachePath)) {
           PPOpts.ImplicitPCHInclude = Dir->path();
@@ -443,7 +443,7 @@ bool FrontendAction::Execute() {
   if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() &&
       CI.hasPreprocessor()) {
     GlobalModuleIndex::writeIndex(
-        CI.getFileManager(), *CI.getPCHContainerOperations(),
+        CI.getFileManager(), CI.getPCHContainerOperations(),
         CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
   }
 
diff --git a/lib/Frontend/FrontendActions.cpp b/lib/Frontend/FrontendActions.cpp
index 4997764..66b4378 100644
--- a/lib/Frontend/FrontendActions.cpp
+++ b/lib/Frontend/FrontendActions.cpp
@@ -415,7 +415,7 @@ void VerifyPCHAction::ExecuteAction() {
   bool Preamble = CI.getPreprocessorOpts().PrecompiledPreambleBytes.first != 0;
   const std::string &Sysroot = CI.getHeaderSearchOpts().Sysroot;
   std::unique_ptr<ASTReader> Reader(new ASTReader(
-      CI.getPreprocessor(), CI.getASTContext(), *CI.getPCHContainerOperations(),
+      CI.getPreprocessor(), CI.getASTContext(), CI.getPCHContainerOperations(),
       Sysroot.empty() ? "" : Sysroot.c_str(),
       /*DisableValidation*/ false,
       /*AllowPCHWithCompilerErrors*/ false,
@@ -578,7 +578,7 @@ void DumpModuleInfoAction::ExecuteAction() {
   DumpModuleInfoListener Listener(Out);
   ASTReader::readASTFileControlBlock(
       getCurrentFile(), getCompilerInstance().getFileManager(),
-      *getCompilerInstance().getPCHContainerOperations(), Listener);
+      getCompilerInstance().getPCHContainerOperations(), Listener);
 }
 
 //===----------------------------------------------------------------------===//
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 025c8b9..bf42f73 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -96,9 +96,10 @@ static void AddImplicitIncludePTH(MacroBuilder &Builder, Preprocessor &PP,
 
 /// \brief Add an implicit \#include using the original file used to generate
 /// a PCH file.
-static void AddImplicitIncludePCH(MacroBuilder &Builder, Preprocessor &PP,
-                                  const PCHContainerOperations &PCHContainerOps,
-                                  StringRef ImplicitIncludePCH) {
+static void
+AddImplicitIncludePCH(MacroBuilder &Builder, Preprocessor &PP,
+                      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+                      StringRef ImplicitIncludePCH) {
   std::string OriginalFile =
       ASTReader::getOriginalSourceFile(ImplicitIncludePCH, PP.getFileManager(),
                                        PCHContainerOps, PP.getDiagnostics());
@@ -902,7 +903,7 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
 ///
 void clang::InitializePreprocessor(
     Preprocessor &PP, const PreprocessorOptions &InitOpts,
-    const PCHContainerOperations &PCHContainerOps,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     const FrontendOptions &FEOpts) {
   const LangOptions &LangOpts = PP.getLangOpts();
   std::string PredefineBuffer;
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 3045629..8145733 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -3601,7 +3601,7 @@ ASTReader::ReadASTCore(StringRef FileName,
 
   ModuleFile &F = *M;
   BitstreamCursor &Stream = F.Stream;
-  PCHContainerOps.ExtractPCH(F.Buffer->getMemBufferRef(), F.StreamFile);
+  PCHContainerOps->ExtractPCH(F.Buffer->getMemBufferRef(), F.StreamFile);
   Stream.init(&F.StreamFile);
   F.SizeInBits = F.Buffer->getBufferSize() * 8;
   
@@ -3872,7 +3872,8 @@ static ASTFileSignature readASTFileSignature(llvm::BitstreamReader &StreamFile){
 /// file.
 std::string ASTReader::getOriginalSourceFile(
     const std::string &ASTFileName, FileManager &FileMgr,
-    const PCHContainerOperations &PCHContainerOps, DiagnosticsEngine &Diags) {
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    DiagnosticsEngine &Diags) {
   // Open the AST file.
   auto Buffer = FileMgr.getBufferForFile(ASTFileName);
   if (!Buffer) {
@@ -3883,7 +3884,7 @@ std::string ASTReader::getOriginalSourceFile(
 
   // Initialize the stream
   llvm::BitstreamReader StreamFile;
-  PCHContainerOps.ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile);
+  PCHContainerOps->ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile);
   BitstreamCursor Stream(StreamFile);
 
   // Sniff for the signature.
@@ -3967,7 +3968,7 @@ namespace {
 
 bool ASTReader::readASTFileControlBlock(
     StringRef Filename, FileManager &FileMgr,
-    const PCHContainerOperations &PCHContainerOps,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     ASTReaderListener &Listener) {
   // Open the AST file.
   // FIXME: This allows use of the VFS; we do not allow use of the
@@ -3979,7 +3980,7 @@ bool ASTReader::readASTFileControlBlock(
 
   // Initialize the stream
   llvm::BitstreamReader StreamFile;
-  PCHContainerOps.ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile);
+  PCHContainerOps->ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile);
   BitstreamCursor Stream(StreamFile);
 
   // Sniff for the signature.
@@ -4160,9 +4161,9 @@ bool ASTReader::readASTFileControlBlock(
 
 bool ASTReader::isAcceptableASTFile(
     StringRef Filename, FileManager &FileMgr,
-    const PCHContainerOperations &PCHContainerOps, const LangOptions &LangOpts,
-    const TargetOptions &TargetOpts, const PreprocessorOptions &PPOpts,
-    std::string ExistingModuleCachePath) {
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    const LangOptions &LangOpts, const TargetOptions &TargetOpts,
+    const PreprocessorOptions &PPOpts, std::string ExistingModuleCachePath) {
   SimplePCHValidator validator(LangOpts, TargetOpts, PPOpts,
                                ExistingModuleCachePath, FileMgr);
   return !readASTFileControlBlock(Filename, FileMgr, PCHContainerOps,
@@ -8472,7 +8473,7 @@ void ASTReader::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
 }
 
 ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
-                     const PCHContainerOperations &PCHContainerOps,
+                     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
                      StringRef isysroot, bool DisableValidation,
                      bool AllowASTWithCompilerErrors,
                      bool AllowConfigurationMismatch, bool ValidateSystemInputs,
diff --git a/lib/Serialization/GlobalModuleIndex.cpp b/lib/Serialization/GlobalModuleIndex.cpp
index 2c7da3e..94f1ccc 100644
--- a/lib/Serialization/GlobalModuleIndex.cpp
+++ b/lib/Serialization/GlobalModuleIndex.cpp
@@ -385,7 +385,7 @@ namespace {
   /// \brief Builder that generates the global module index file.
   class GlobalModuleIndexBuilder {
     FileManager &FileMgr;
-    const PCHContainerOperations &PCHContainerOps;
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps;
 
     /// \brief Mapping from files to module file information.
     typedef llvm::MapVector<const FileEntry *, ModuleFileInfo> ModuleFilesMap;
@@ -419,7 +419,8 @@ namespace {
 
   public:
     explicit GlobalModuleIndexBuilder(
-        FileManager &FileMgr, const PCHContainerOperations &PCHContainerOps)
+        FileManager &FileMgr,
+        std::shared_ptr<PCHContainerOperations> PCHContainerOps)
         : FileMgr(FileMgr), PCHContainerOps(PCHContainerOps) {}
 
     /// \brief Load the contents of the given module file into the builder.
@@ -505,7 +506,7 @@ bool GlobalModuleIndexBuilder::loadModuleFile(const FileEntry *File) {
 
   // Initialize the input stream
   llvm::BitstreamReader InStreamFile;
-  PCHContainerOps.ExtractPCH((*Buffer)->getMemBufferRef(), InStreamFile);
+  PCHContainerOps->ExtractPCH((*Buffer)->getMemBufferRef(), InStreamFile);
   llvm::BitstreamCursor InStream(InStreamFile);
 
   // Sniff for the signature.
@@ -766,10 +767,9 @@ void GlobalModuleIndexBuilder::writeIndex(llvm::BitstreamWriter &Stream) {
   Stream.ExitBlock();
 }
 
-GlobalModuleIndex::ErrorCode
-GlobalModuleIndex::writeIndex(FileManager &FileMgr,
-                              const PCHContainerOperations &PCHContainerOps,
-                              StringRef Path) {
+GlobalModuleIndex::ErrorCode GlobalModuleIndex::writeIndex(
+    FileManager &FileMgr,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps, StringRef Path) {
   llvm::SmallString<128> IndexPath;
   IndexPath += Path;
   llvm::sys::path::append(IndexPath, IndexFileName);
diff --git a/lib/Serialization/ModuleManager.cpp b/lib/Serialization/ModuleManager.cpp
index 03d8ed0..75a42ed 100644
--- a/lib/Serialization/ModuleManager.cpp
+++ b/lib/Serialization/ModuleManager.cpp
@@ -139,7 +139,8 @@ ModuleManager::addModule(StringRef FileName, ModuleKind Type,
     }
 
     // Initialize the stream.
-    PCHContainerOps.ExtractPCH(New->Buffer->getMemBufferRef(), New->StreamFile);
+    PCHContainerOps->ExtractPCH(New->Buffer->getMemBufferRef(),
+                                New->StreamFile);
   }
 
   if (ExpectedSignature) {
@@ -289,8 +290,9 @@ void ModuleManager::moduleFileAccepted(ModuleFile *MF) {
   ModulesInCommonWithGlobalIndex.push_back(MF);
 }
 
-ModuleManager::ModuleManager(FileManager &FileMgr,
-                             const PCHContainerOperations &PCHContainerOps)
+ModuleManager::ModuleManager(
+    FileManager &FileMgr,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps)
     : FileMgr(FileMgr), PCHContainerOps(PCHContainerOps), GlobalIndex(),
       FirstVisitState(nullptr) {}
 
diff --git a/test/Modules/pch_container.m b/test/Modules/pch_container.m
index 095245b..bc02c3a 100644
--- a/test/Modules/pch_container.m
+++ b/test/Modules/pch_container.m
@@ -1,9 +1,9 @@
 @import DependsOnModule;
 // REQUIRES: x86-registered-target
 // RUN: rm -rf %t-MachO %t-ELF %t-ELF_SPLIT %t-COFF
-// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-MachO -F %S/Inputs %s
-// RUN: %clang_cc1 -triple=x86_64-linux-elf -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-ELF -F %S/Inputs %s
-// RUN: %clang_cc1 -triple=x86_64-windows-coff -fmodules -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-COFF -F %S/Inputs %s
+// RUN: %clang_cc1 -triple=x86_64-apple-darwin -fmodules -fmodule-format=obj -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-MachO -F %S/Inputs %s
+// RUN: %clang_cc1 -triple=x86_64-linux-elf -fmodules -fmodule-format=obj -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-ELF -F %S/Inputs %s
+// RUN: %clang_cc1 -triple=x86_64-windows-coff -fmodules -fmodule-format=obj -fimplicit-module-maps -fdisable-module-hash -fmodules-cache-path=%t-COFF -F %S/Inputs %s
 
 // RUN: llvm-objdump -section-headers %t-MachO/DependsOnModule.pcm %t-ELF/DependsOnModule.pcm %t-COFF/DependsOnModule.pcm | FileCheck %s
 // CHECK: file format Mach-O 64-bit x86-64
