r240225 - Introduce a PCHContainerOperations interface (NFC).

Adrian Prantl aprantl at apple.com
Sat Jun 20 11:53:08 PDT 2015


Author: adrian
Date: Sat Jun 20 13:53:08 2015
New Revision: 240225

URL: http://llvm.org/viewvc/llvm-project?rev=240225&view=rev
Log:
Introduce a PCHContainerOperations interface (NFC).

A PCHContainerOperations abstract interface provides operations for
creating and unwrapping containers for serialized ASTs (precompiled
headers and clang modules). The default implementation is
RawPCHContainerOperations, which uses a flat file for the output.

The main application for this interface will be an
ObjectFilePCHContainerOperations implementation that uses LLVM to
wrap the module in an ELF/Mach-O/COFF container to store debug info
alongside the AST.

rdar://problem/20091852

Added:
    cfe/trunk/include/clang/Frontend/PCHContainerOperations.h
    cfe/trunk/lib/Frontend/PCHContainerOperations.cpp
Modified:
    cfe/trunk/include/clang/ARCMigrate/ARCMT.h
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/include/clang/Frontend/CompilerInstance.h
    cfe/trunk/include/clang/Frontend/FrontendActions.h
    cfe/trunk/include/clang/Frontend/Utils.h
    cfe/trunk/include/clang/Serialization/ASTReader.h
    cfe/trunk/include/clang/Serialization/ASTWriter.h
    cfe/trunk/include/clang/Serialization/GlobalModuleIndex.h
    cfe/trunk/include/clang/Serialization/ModuleManager.h
    cfe/trunk/include/clang/Tooling/Refactoring.h
    cfe/trunk/include/clang/Tooling/Tooling.h
    cfe/trunk/lib/ARCMigrate/ARCMT.cpp
    cfe/trunk/lib/ARCMigrate/ARCMTActions.cpp
    cfe/trunk/lib/AST/ASTConsumer.cpp
    cfe/trunk/lib/Frontend/ASTMerge.cpp
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Frontend/CMakeLists.txt
    cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp
    cfe/trunk/lib/Frontend/CompilerInstance.cpp
    cfe/trunk/lib/Frontend/FrontendAction.cpp
    cfe/trunk/lib/Frontend/FrontendActions.cpp
    cfe/trunk/lib/Frontend/InitPreprocessor.cpp
    cfe/trunk/lib/Serialization/ASTReader.cpp
    cfe/trunk/lib/Serialization/GeneratePCH.cpp
    cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp
    cfe/trunk/lib/Serialization/ModuleManager.cpp
    cfe/trunk/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
    cfe/trunk/lib/Tooling/Refactoring.cpp
    cfe/trunk/lib/Tooling/Tooling.cpp
    cfe/trunk/tools/arcmt-test/arcmt-test.cpp
    cfe/trunk/tools/driver/cc1_main.cpp
    cfe/trunk/tools/libclang/CIndex.cpp
    cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
    cfe/trunk/tools/libclang/CIndexer.h
    cfe/trunk/tools/libclang/Indexing.cpp
    cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h

Modified: cfe/trunk/include/clang/ARCMigrate/ARCMT.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ARCMigrate/ARCMT.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/include/clang/ARCMigrate/ARCMT.h (original)
+++ cfe/trunk/include/clang/ARCMigrate/ARCMT.h Sat Jun 20 13:53:08 2015
@@ -17,6 +17,7 @@
 namespace clang {
   class ASTContext;
   class DiagnosticConsumer;
+  class PCHContainerOperations;
 
 namespace arcmt {
   class MigrationPass;
@@ -37,19 +38,22 @@ namespace arcmt {
 /// the pre-migration ARC diagnostics.
 ///
 /// \returns false if no error is produced, true otherwise.
-bool checkForManualIssues(CompilerInvocation &CI,
-                          const FrontendInputFile &Input,
-                          DiagnosticConsumer *DiagClient,
-                          bool emitPremigrationARCErrors = false,
-                          StringRef plistOut = StringRef());
+bool
+checkForManualIssues(CompilerInvocation &CI, const FrontendInputFile &Input,
+                     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+                     DiagnosticConsumer *DiagClient,
+                     bool emitPremigrationARCErrors = false,
+                     StringRef plistOut = StringRef());
 
 /// \brief Works similar to checkForManualIssues but instead of checking, it
 /// applies automatic modifications to source files to conform to ARC.
 ///
 /// \returns false if no error is produced, true otherwise.
-bool applyTransformations(CompilerInvocation &origCI,
-                          const FrontendInputFile &Input,
-                          DiagnosticConsumer *DiagClient);
+bool
+applyTransformations(CompilerInvocation &origCI,
+                     const FrontendInputFile &Input,
+                     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+                     DiagnosticConsumer *DiagClient);
 
 /// \brief Applies automatic modifications and produces temporary files
 /// and metadata into the \p outputDir path.
@@ -62,12 +66,11 @@ bool applyTransformations(CompilerInvoca
 /// the pre-migration ARC diagnostics.
 ///
 /// \returns false if no error is produced, true otherwise.
-bool migrateWithTemporaryFiles(CompilerInvocation &origCI,
-                               const FrontendInputFile &Input,
-                               DiagnosticConsumer *DiagClient,
-                               StringRef outputDir,
-                               bool emitPremigrationARCErrors,
-                               StringRef plistOut);
+bool migrateWithTemporaryFiles(
+    CompilerInvocation &origCI, const FrontendInputFile &Input,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    DiagnosticConsumer *DiagClient, StringRef outputDir,
+    bool emitPremigrationARCErrors, StringRef plistOut);
 
 /// \brief Get the set of file remappings from the \p outputDir path that
 /// migrateWithTemporaryFiles produced.
@@ -93,13 +96,16 @@ std::vector<TransformFn> getAllTransform
 
 class MigrationProcess {
   CompilerInvocation OrigCI;
+  std::shared_ptr<PCHContainerOperations> PCHContainerOps;
   DiagnosticConsumer *DiagClient;
   FileRemapper Remapper;
 
 public:
   bool HadARCErrors;
 
-  MigrationProcess(const CompilerInvocation &CI, DiagnosticConsumer *diagClient,
+  MigrationProcess(const CompilerInvocation &CI,
+                   std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+                   DiagnosticConsumer *diagClient,
                    StringRef outputDir = StringRef());
 
   class RewriteListener {

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Sat Jun 20 13:53:08 2015
@@ -56,6 +56,7 @@ class FileEntry;
 class FileManager;
 class HeaderSearch;
 class Preprocessor;
+class PCHContainerOperations;
 class SourceManager;
 class TargetInfo;
 class ASTFrontendAction;
@@ -422,7 +423,8 @@ private:
   explicit ASTUnit(bool MainFileIsAST);
 
   void CleanTemporaryFiles();
-  bool Parse(std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer);
+  bool Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+             std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer);
 
   struct ComputedPreamble {
     llvm::MemoryBuffer *Buffer;
@@ -442,6 +444,7 @@ private:
                                    unsigned MaxLines);
 
   std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble(
+      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
       const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild = true,
       unsigned MaxLines = 0);
   void RealizeTopLevelDeclsFromPreamble();
@@ -715,12 +718,16 @@ public:
   ///
   /// \param Filename - The AST file to load.
   ///
+  /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
+  /// creating modules.
   /// \param Diags - The diagnostics engine to use for reporting errors; its
   /// lifetime is expected to extend past that of the returned ASTUnit.
   ///
   /// \returns - The initialized ASTUnit or null if the AST failed to load.
   static std::unique_ptr<ASTUnit> LoadFromASTFile(
-      const std::string &Filename, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+      const std::string &Filename,
+      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+      IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
       const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls = false,
       ArrayRef<RemappedFile> RemappedFiles = None,
       bool CaptureDiagnostics = false, bool AllowPCHWithCompilerErrors = false,
@@ -735,8 +742,10 @@ private:
   ///
   /// \returns \c true if a catastrophic failure occurred (which means that the
   /// \c ASTUnit itself is invalid), or \c false otherwise.
-  bool LoadFromCompilerInvocation(bool PrecompilePreamble);
-  
+  bool LoadFromCompilerInvocation(
+      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+      bool PrecompilePreamble);
+
 public:
   
   /// \brief Create an ASTUnit from a source file, via a CompilerInvocation
@@ -745,6 +754,9 @@ public:
   /// \param CI - The compiler invocation to use; it must have exactly one input
   /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
   ///
+  /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
+  /// creating modules.
+  ///
   /// \param Diags - The diagnostics engine to use for reporting errors; its
   /// lifetime is expected to extend past that of the returned ASTUnit.
   ///
@@ -765,7 +777,9 @@ public:
   /// created ASTUnit was passed in \p Unit then the caller can check that.
   ///
   static ASTUnit *LoadFromCompilerInvocationAction(
-      CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+      CompilerInvocation *CI,
+      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+      IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
       ASTFrontendAction *Action = nullptr, ASTUnit *Unit = nullptr,
       bool Persistent = true, StringRef ResourceFilesPath = StringRef(),
       bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
@@ -780,15 +794,20 @@ public:
   /// \param CI - The compiler invocation to use; it must have exactly one input
   /// source file. The ASTUnit takes ownership of the CompilerInvocation object.
   ///
+  /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
+  /// creating modules.
+  ///
   /// \param Diags - The diagnostics engine to use for reporting errors; its
   /// lifetime is expected to extend past that of the returned ASTUnit.
   //
   // FIXME: Move OnlyLocalDecls, UseBumpAllocator to setters on the ASTUnit, we
   // shouldn't need to specify them at construction time.
   static std::unique_ptr<ASTUnit> LoadFromCompilerInvocation(
-      CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-      bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
-      bool PrecompilePreamble = false, TranslationUnitKind TUKind = TU_Complete,
+      CompilerInvocation *CI,
+      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+      IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool OnlyLocalDecls = false,
+      bool CaptureDiagnostics = false, bool PrecompilePreamble = false,
+      TranslationUnitKind TUKind = TU_Complete,
       bool CacheCodeCompletionResults = false,
       bool IncludeBriefCommentsInCodeCompletion = false,
       bool UserFilesAreVolatile = false);
@@ -800,6 +819,9 @@ public:
   ///
   /// \param ArgEnd - The end of the argument vector.
   ///
+  /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
+  /// creating modules.
+  ///
   /// \param Diags - The diagnostics engine to use for reporting errors; its
   /// lifetime is expected to extend past that of the returned ASTUnit.
   ///
@@ -813,6 +835,7 @@ public:
   // shouldn't need to specify them at construction time.
   static ASTUnit *LoadFromCommandLine(
       const char **ArgBegin, const char **ArgEnd,
+      std::shared_ptr<PCHContainerOperations> PCHContainerOps,
       IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
       bool OnlyLocalDecls = false, bool CaptureDiagnostics = false,
       ArrayRef<RemappedFile> RemappedFiles = None,
@@ -828,8 +851,9 @@ public:
   /// were originally used to produce this translation unit.
   ///
   /// \returns True if a failure occurred that causes the ASTUnit not to
-  /// contain any translation-unit information, false otherwise.  
-  bool Reparse(ArrayRef<RemappedFile> RemappedFiles = None);
+  /// contain any translation-unit information, false otherwise.
+  bool Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+               ArrayRef<RemappedFile> RemappedFiles = None);
 
   /// \brief Perform code completion at the given file, line, and
   /// column within this translation unit.
@@ -852,14 +876,14 @@ public:
   /// FIXME: The Diag, LangOpts, SourceMgr, FileMgr, StoredDiagnostics, and
   /// OwnedBuffers parameters are all disgusting hacks. They will go away.
   void CodeComplete(StringRef File, unsigned Line, unsigned Column,
-                    ArrayRef<RemappedFile> RemappedFiles,
-                    bool IncludeMacros, bool IncludeCodePatterns,
-                    bool IncludeBriefComments,
+                    ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
+                    bool IncludeCodePatterns, bool IncludeBriefComments,
                     CodeCompleteConsumer &Consumer,
+                    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
                     DiagnosticsEngine &Diag, LangOptions &LangOpts,
                     SourceManager &SourceMgr, FileManager &FileMgr,
                     SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
-              SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers);
+                    SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers);
 
   /// \brief Save this translation unit to a file with the given name.
   ///

Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original)
+++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Sat Jun 20 13:53:08 2015
@@ -11,6 +11,7 @@
 #define LLVM_CLANG_FRONTEND_COMPILERINSTANCE_H_
 
 #include "clang/AST/ASTConsumer.h"
+#include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Frontend/CompilerInvocation.h"
@@ -109,6 +110,9 @@ class CompilerInstance : public ModuleLo
   /// \brief The module dependency collector for crashdumps
   std::shared_ptr<ModuleDependencyCollector> ModuleDepCollector;
 
+  /// \brief The module provider.
+  std::shared_ptr<PCHContainerOperations> ThePCHContainerOperations;
+
   /// \brief The dependency file generator.
   std::unique_ptr<DependencyFileGenerator> TheDependencyFileGenerator;
 
@@ -172,7 +176,10 @@ class CompilerInstance : public ModuleLo
   CompilerInstance(const CompilerInstance &) = delete;
   void operator=(const CompilerInstance &) = delete;
 public:
-  explicit CompilerInstance(bool BuildingModule = false);
+  explicit CompilerInstance(
+      std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+          std::make_shared<RawPCHContainerOperations>(),
+      bool BuildingModule = false);
   ~CompilerInstance() override;
 
   /// @name High-Level Operations
@@ -492,6 +499,10 @@ public:
   void setModuleDepCollector(
       std::shared_ptr<ModuleDependencyCollector> Collector);
 
+  std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
+    return ThePCHContainerOperations;
+  }
+
   /// }
   /// @name Code Completion
   /// {
@@ -605,6 +616,7 @@ public:
   static IntrusiveRefCntPtr<ASTReader> createPCHExternalASTSource(
       StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,
       bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
+      const PCHContainerOperations &PCHContainerOps,
       void *DeserializationListener, bool OwnDeserializationListener,
       bool Preamble, bool UseGlobalModuleIndex);
 

Modified: cfe/trunk/include/clang/Frontend/FrontendActions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendActions.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendActions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendActions.h Sat Jun 20 13:53:08 2015
@@ -85,10 +85,9 @@ public:
   /// create the PCHGenerator instance returned by CreateASTConsumer.
   ///
   /// \returns true if an error occurred, false otherwise.
-  static raw_ostream *ComputeASTConsumerArguments(CompilerInstance &CI,
-                                                  StringRef InFile,
-                                                  std::string &Sysroot,
-                                                  std::string &OutputFile);
+  static raw_pwrite_stream *
+  ComputeASTConsumerArguments(CompilerInstance &CI, StringRef InFile,
+                              std::string &Sysroot, std::string &OutputFile);
 };
 
 class GenerateModuleAction : public ASTFrontendAction {
@@ -118,10 +117,10 @@ public:
   /// create the PCHGenerator instance returned by CreateASTConsumer.
   ///
   /// \returns true if an error occurred, false otherwise.
-  raw_ostream *ComputeASTConsumerArguments(CompilerInstance &CI,
-                                           StringRef InFile,
-                                           std::string &Sysroot,
-                                           std::string &OutputFile);
+  raw_pwrite_stream *ComputeASTConsumerArguments(CompilerInstance &CI,
+                                                 StringRef InFile,
+                                                 std::string &Sysroot,
+                                                 std::string &OutputFile);
 };
 
 class SyntaxOnlyAction : public ASTFrontendAction {

Added: cfe/trunk/include/clang/Frontend/PCHContainerOperations.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/PCHContainerOperations.h?rev=240225&view=auto
==============================================================================
--- cfe/trunk/include/clang/Frontend/PCHContainerOperations.h (added)
+++ cfe/trunk/include/clang/Frontend/PCHContainerOperations.h Sat Jun 20 13:53:08 2015
@@ -0,0 +1,76 @@
+//===--- Frontend/PCHContainerOperations.h - PCH Containers -----*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
+#define LLVM_CLANG_PCH_CONTAINER_OPERATIONS_H
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/MemoryBuffer.h"
+#include <memory>
+
+namespace llvm {
+class raw_pwrite_stream;
+class BitstreamReader;
+}
+
+namespace clang {
+
+class ASTConsumer;
+class CodeGenOptions;
+class DiagnosticsEngine;
+class HeaderSearchOptions;
+class LangOptions;
+class PreprocessorOptions;
+class TargetOptions;
+
+struct PCHBuffer {
+  bool IsComplete;
+  llvm::SmallVector<char, 0> Data;
+};
+
+/// \brief This abstract interface provides operations for creating
+/// and unwrapping containers for serialized ASTs (precompiled headers
+/// and clang modules).
+class PCHContainerOperations {
+public:
+  virtual ~PCHContainerOperations();
+  /// \brief Return an ASTConsumer that can be chained with a
+  /// PCHGenerator that produces a wrapper file format containing a
+  /// serialized AST bitstream.
+  virtual std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator(
+      DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO,
+      const PreprocessorOptions &PPO, const TargetOptions &TO,
+      const LangOptions &LO, const std::string &MainFileName,
+      const std::string &OutputFileName, llvm::raw_pwrite_stream *OS,
+      std::shared_ptr<PCHBuffer> Buffer) const = 0;
+
+  /// \brief Initialize an llvm::BitstreamReader with the serialized AST inside
+  /// the PCH container Buffer.
+  virtual void ExtractPCH(llvm::MemoryBufferRef Buffer,
+                          llvm::BitstreamReader &StreamFile) const = 0;
+};
+
+/// \brief Implements a raw pass-through PCH container.
+class RawPCHContainerOperations : public PCHContainerOperations {
+  /// \brief Return an ASTConsumer that can be chained with a
+  /// PCHGenerator that writes the module to a flat file.
+  std::unique_ptr<ASTConsumer> CreatePCHContainerGenerator(
+      DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO,
+      const PreprocessorOptions &PPO, const TargetOptions &TO,
+      const LangOptions &LO, const std::string &MainFileName,
+      const std::string &OutputFileName, llvm::raw_pwrite_stream *OS,
+      std::shared_ptr<PCHBuffer> Buffer) const override;
+
+  /// \brief Initialize an llvm::BitstreamReader with Buffer.
+  void ExtractPCH(llvm::MemoryBufferRef Buffer,
+                  llvm::BitstreamReader &StreamFile) const override;
+};
+}
+
+#endif

Modified: cfe/trunk/include/clang/Frontend/Utils.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/Utils.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/Utils.h (original)
+++ cfe/trunk/include/clang/Frontend/Utils.h Sat Jun 20 13:53:08 2015
@@ -45,6 +45,7 @@ class HeaderSearch;
 class HeaderSearchOptions;
 class IdentifierTable;
 class LangOptions;
+class PCHContainerOperations;
 class Preprocessor;
 class PreprocessorOptions;
 class PreprocessorOutputOptions;
@@ -61,8 +62,8 @@ void ApplyHeaderSearchOptions(HeaderSear
 
 /// InitializePreprocessor - Initialize the preprocessor getting it and the
 /// environment ready to process a single file.
-void InitializePreprocessor(Preprocessor &PP,
-                            const PreprocessorOptions &PPOpts,
+void InitializePreprocessor(Preprocessor &PP, const PreprocessorOptions &PPOpts,
+                            const PCHContainerOperations &PCHContainerOps,
                             const FrontendOptions &FEOpts);
 
 /// DoPrintPreprocessedInput - Implement -E mode.

Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Sat Jun 20 13:53:08 2015
@@ -362,6 +362,7 @@ private:
 
   SourceManager &SourceMgr;
   FileManager &FileMgr;
+  const PCHContainerOperations &PCHContainerOps;
   DiagnosticsEngine &Diags;
 
   /// \brief The semantic analysis object that will be processing the
@@ -1237,6 +1238,9 @@ public:
   /// \param Context the AST context that this precompiled header will be
   /// loaded into.
   ///
+  /// \param PCHContainerOps the PCHContainerOperations to use for loading and
+  /// creating modules.
+  ///
   /// \param isysroot If non-NULL, the system include path specified by the
   /// user. This is only used with relocatable PCH files. If non-NULL,
   /// a relocatable PCH file will use the default path "/".
@@ -1258,12 +1262,12 @@ public:
   ///
   /// \param UseGlobalIndex If true, the AST reader will try to load and use
   /// the global module index.
-  ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot = "",
-            bool DisableValidation = false,
+  ASTReader(Preprocessor &PP, ASTContext &Context,
+            const PCHContainerOperations &PCHContainerOps,
+            StringRef isysroot = "", bool DisableValidation = false,
             bool AllowASTWithCompilerErrors = false,
             bool AllowConfigurationMismatch = false,
-            bool ValidateSystemInputs = false,
-            bool UseGlobalIndex = true);
+            bool ValidateSystemInputs = false, bool UseGlobalIndex = true);
 
   ~ASTReader() override;
 
@@ -1425,21 +1429,23 @@ public:
 
   /// \brief Retrieve the name of the original source file name directly from
   /// the AST file, without actually loading the AST file.
-  static std::string getOriginalSourceFile(const std::string &ASTFileName,
-                                           FileManager &FileMgr,
-                                           DiagnosticsEngine &Diags);
+  static std::string
+  getOriginalSourceFile(const std::string &ASTFileName, FileManager &FileMgr,
+                        const 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,
-                                      ASTReaderListener &Listener);
+  static bool
+  readASTFileControlBlock(StringRef Filename, FileManager &FileMgr,
+                          const 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,
+  static bool isAcceptableASTFile(StringRef Filename, FileManager &FileMgr,
+                                  const PCHContainerOperations &PCHContainerOps,
                                   const LangOptions &LangOpts,
                                   const TargetOptions &TargetOpts,
                                   const PreprocessorOptions &PPOpts,

Modified: cfe/trunk/include/clang/Serialization/ASTWriter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTWriter.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ASTWriter.h (original)
+++ cfe/trunk/include/clang/Serialization/ASTWriter.h Sat Jun 20 13:53:08 2015
@@ -17,6 +17,7 @@
 #include "clang/AST/ASTMutationListener.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclarationName.h"
+#include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/AST/TemplateBase.h"
 #include "clang/Sema/SemaConsumer.h"
 #include "clang/Serialization/ASTBitCodes.h"
@@ -868,30 +869,28 @@ class PCHGenerator : public SemaConsumer
   std::string OutputFile;
   clang::Module *Module;
   std::string isysroot;
-  raw_ostream *Out;
   Sema *SemaPtr;
-  SmallVector<char, 128> Buffer;
+  std::shared_ptr<PCHBuffer> Buffer;
   llvm::BitstreamWriter Stream;
   ASTWriter Writer;
   bool AllowASTWithErrors;
-  bool HasEmittedPCH;
 
 protected:
   ASTWriter &getWriter() { return Writer; }
   const ASTWriter &getWriter() const { return Writer; }
+  SmallVectorImpl<char> &getPCH() const { return Buffer->Data; }
 
 public:
   PCHGenerator(const Preprocessor &PP, StringRef OutputFile,
-               clang::Module *Module,
-               StringRef isysroot, raw_ostream *Out,
+               clang::Module *Module, StringRef isysroot,
+               std::shared_ptr<PCHBuffer> Buffer,
                bool AllowASTWithErrors = false);
   ~PCHGenerator() override;
   void InitializeSema(Sema &S) override { SemaPtr = &S; }
   void HandleTranslationUnit(ASTContext &Ctx) override;
   ASTMutationListener *GetASTMutationListener() override;
   ASTDeserializationListener *GetASTDeserializationListener() override;
-
-  bool hasEmittedPCH() const { return HasEmittedPCH; }
+  bool hasEmittedPCH() const { return Buffer->IsComplete; }
 };
 
 } // end namespace clang

Modified: cfe/trunk/include/clang/Serialization/GlobalModuleIndex.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/GlobalModuleIndex.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/GlobalModuleIndex.h (original)
+++ cfe/trunk/include/clang/Serialization/GlobalModuleIndex.h Sat Jun 20 13:53:08 2015
@@ -35,6 +35,7 @@ class DirectoryEntry;
 class FileEntry;
 class FileManager;
 class IdentifierIterator;
+class PCHContainerOperations;
 
 namespace serialization {
   class ModuleFile;
@@ -192,10 +193,13 @@ public:
   /// \brief Write a global index into the given
   ///
   /// \param FileMgr The file manager to use to load module files.
-  ///
+  /// \param PCHContainerOps - The PCHContainerOperations to use for loading and
+  /// 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, StringRef Path);
+  static ErrorCode writeIndex(FileManager &FileMgr,
+                              const PCHContainerOperations &PCHContainerOps,
+                              StringRef Path);
 };
 
 }

Modified: cfe/trunk/include/clang/Serialization/ModuleManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ModuleManager.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/include/clang/Serialization/ModuleManager.h (original)
+++ cfe/trunk/include/clang/Serialization/ModuleManager.h Sat Jun 20 13:53:08 2015
@@ -24,6 +24,7 @@ namespace clang {
 
 class GlobalModuleIndex;
 class ModuleMap;
+class PCHContainerOperations;
 
 namespace serialization {
 
@@ -49,7 +50,10 @@ class ModuleManager {
   /// \brief FileManager that handles translating between filenames and
   /// FileEntry *.
   FileManager &FileMgr;
-  
+
+  /// \brief Knows how to unwrap module containers.
+  const PCHContainerOperations &PCHContainerOps;
+
   /// \brief A lookup of in-memory (virtual file) buffers
   llvm::DenseMap<const FileEntry *, std::unique_ptr<llvm::MemoryBuffer>>
       InMemoryBuffers;
@@ -112,8 +116,9 @@ public:
   typedef SmallVectorImpl<ModuleFile*>::const_iterator ModuleConstIterator;
   typedef SmallVectorImpl<ModuleFile*>::reverse_iterator ModuleReverseIterator;
   typedef std::pair<uint32_t, StringRef> ModuleOffset;
-  
-  explicit ModuleManager(FileManager &FileMgr);
+
+  explicit ModuleManager(FileManager &FileMgr,
+                         const PCHContainerOperations &PCHContainerOps);
   ~ModuleManager();
   
   /// \brief Forward iterator to traverse all loaded modules.  This is reverse

Modified: cfe/trunk/include/clang/Tooling/Refactoring.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Refactoring.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/include/clang/Tooling/Refactoring.h (original)
+++ cfe/trunk/include/clang/Tooling/Refactoring.h Sat Jun 20 13:53:08 2015
@@ -38,7 +38,9 @@ class RefactoringTool : public ClangTool
 public:
   /// \see ClangTool::ClangTool.
   RefactoringTool(const CompilationDatabase &Compilations,
-                  ArrayRef<std::string> SourcePaths);
+                  ArrayRef<std::string> SourcePaths,
+                  std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+                      std::make_shared<RawPCHContainerOperations>());
 
   /// \brief Returns the set of replacements to which replacements should
   /// be added during the run of the tool.

Modified: cfe/trunk/include/clang/Tooling/Tooling.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Tooling/Tooling.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/include/clang/Tooling/Tooling.h (original)
+++ cfe/trunk/include/clang/Tooling/Tooling.h Sat Jun 20 13:53:08 2015
@@ -31,11 +31,13 @@
 #define LLVM_CLANG_TOOLING_TOOLING_H
 
 #include "clang/AST/ASTConsumer.h"
+#include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Driver/Util.h"
 #include "clang/Frontend/FrontendAction.h"
+#include "clang/Lex/ModuleLoader.h"
 #include "clang/Tooling/ArgumentsAdjusters.h"
 #include "clang/Tooling/CompilationDatabase.h"
 #include "llvm/ADT/StringMap.h"
@@ -66,9 +68,10 @@ public:
   virtual ~ToolAction();
 
   /// \brief Perform an action for an invocation.
-  virtual bool runInvocation(clang::CompilerInvocation *Invocation,
-                             FileManager *Files,
-                             DiagnosticConsumer *DiagConsumer) = 0;
+  virtual bool
+  runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
+                std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+                DiagnosticConsumer *DiagConsumer) = 0;
 };
 
 /// \brief Interface to generate clang::FrontendActions.
@@ -83,6 +86,7 @@ public:
 
   /// \brief Invokes the compiler with a FrontendAction created by create().
   bool runInvocation(clang::CompilerInvocation *Invocation, FileManager *Files,
+                     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
                      DiagnosticConsumer *DiagConsumer) override;
 
   /// \brief Returns a new clang::FrontendAction.
@@ -139,10 +143,14 @@ inline std::unique_ptr<FrontendActionFac
 /// \param ToolAction The action to run over the code.
 /// \param Code C++ code.
 /// \param FileName The file name which 'Code' will be mapped as.
+/// \param PCHContainerOps  The PCHContainerOperations for loading and creating
+///                         clang modules.
 ///
 /// \return - True if 'ToolAction' was successfully executed.
 bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
-                   const Twine &FileName = "input.cc");
+                   const Twine &FileName = "input.cc",
+                   std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+                       std::make_shared<RawPCHContainerOperations>());
 
 /// The first part of the pair is the filename, the second part the
 /// file-content.
@@ -155,37 +163,48 @@ typedef std::vector<std::pair<std::strin
 /// \param Code C++ code.
 /// \param Args Additional flags to pass on.
 /// \param FileName The file name which 'Code' will be mapped as.
+/// \param PCHContainerOps   The PCHContainerOperations for loading and creating
+///                          clang modules.
 ///
 /// \return - True if 'ToolAction' was successfully executed.
 bool runToolOnCodeWithArgs(
     clang::FrontendAction *ToolAction, const Twine &Code,
     const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+        std::make_shared<RawPCHContainerOperations>(),
     const FileContentMappings &VirtualMappedFiles = FileContentMappings());
 
 /// \brief Builds an AST for 'Code'.
 ///
 /// \param Code C++ code.
 /// \param FileName The file name which 'Code' will be mapped as.
+/// \param PCHContainerOps The PCHContainerOperations for loading and creating
+/// clang modules.
 ///
 /// \return The resulting AST or null if an error occurred.
-std::unique_ptr<ASTUnit> buildASTFromCode(const Twine &Code,
-                                          const Twine &FileName = "input.cc");
+std::unique_ptr<ASTUnit>
+buildASTFromCode(const Twine &Code, const Twine &FileName = "input.cc",
+                 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+                     std::make_shared<RawPCHContainerOperations>());
 
 /// \brief Builds an AST for 'Code' with additional flags.
 ///
 /// \param Code C++ code.
 /// \param Args Additional flags to pass on.
 /// \param FileName The file name which 'Code' will be mapped as.
+/// \param PCHContainerOps The PCHContainerOperations for loading and creating
+/// clang modules.
 ///
 /// \return The resulting AST or null if an error occurred.
-std::unique_ptr<ASTUnit>
-buildASTFromCodeWithArgs(const Twine &Code,
-                         const std::vector<std::string> &Args,
-                         const Twine &FileName = "input.cc");
+std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
+    const Twine &Code, const std::vector<std::string> &Args,
+    const Twine &FileName = "input.cc",
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+        std::make_shared<RawPCHContainerOperations>());
 
 /// \brief Utility to run a FrontendAction in a single clang invocation.
 class ToolInvocation {
- public:
+public:
   /// \brief Create a tool invocation.
   ///
   /// \param CommandLine The command line arguments to clang. Note that clang
@@ -195,16 +214,23 @@ class ToolInvocation {
   /// \param FAction The action to be executed. Class takes ownership.
   /// \param Files The FileManager used for the execution. Class does not take
   /// ownership.
+  /// \param PCHContainerOps The PCHContainerOperations for loading and creating
+  /// clang modules.
   ToolInvocation(std::vector<std::string> CommandLine, FrontendAction *FAction,
-                 FileManager *Files);
+                 FileManager *Files,
+                 std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+                     std::make_shared<RawPCHContainerOperations>());
 
   /// \brief Create a tool invocation.
   ///
   /// \param CommandLine The command line arguments to clang.
   /// \param Action The action to be executed.
   /// \param Files The FileManager used for the execution.
+  /// \param PCHContainerOps The PCHContainerOperations for loading and creating
+  /// clang modules.
   ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
-                 FileManager *Files);
+                 FileManager *Files,
+                 std::shared_ptr<PCHContainerOperations> PCHContainerOps);
 
   ~ToolInvocation();
 
@@ -229,12 +255,14 @@ class ToolInvocation {
 
   bool runInvocation(const char *BinaryName,
                      clang::driver::Compilation *Compilation,
-                     clang::CompilerInvocation *Invocation);
+                     clang::CompilerInvocation *Invocation,
+                     std::shared_ptr<PCHContainerOperations> PCHContainerOps);
 
   std::vector<std::string> CommandLine;
   ToolAction *Action;
   bool OwnsAction;
   FileManager *Files;
+  std::shared_ptr<PCHContainerOperations> PCHContainerOps;
   // Maps <file name> -> <file content>.
   llvm::StringMap<StringRef> MappedFileContents;
   DiagnosticConsumer *DiagConsumer;
@@ -255,8 +283,12 @@ class ClangTool {
   ///        command lines for the given source paths.
   /// \param SourcePaths The source files to run over. If a source files is
   ///        not found in Compilations, it is skipped.
+  /// \param PCHContainerOps The PCHContainerOperations for loading and creating
+  /// clang modules.
   ClangTool(const CompilationDatabase &Compilations,
-            ArrayRef<std::string> SourcePaths);
+            ArrayRef<std::string> SourcePaths,
+            std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+                std::make_shared<RawPCHContainerOperations>());
 
   ~ClangTool();
 
@@ -297,6 +329,7 @@ class ClangTool {
  private:
   const CompilationDatabase &Compilations;
   std::vector<std::string> SourcePaths;
+  std::shared_ptr<PCHContainerOperations> PCHContainerOps;
 
   llvm::IntrusiveRefCntPtr<FileManager> Files;
   // Contains a list of pairs (<file name>, <file content>).

Modified: cfe/trunk/lib/ARCMigrate/ARCMT.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ARCMT.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ARCMT.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ARCMT.cpp Sat Jun 20 13:53:08 2015
@@ -166,7 +166,8 @@ static bool HasARCRuntime(CompilerInvoca
 }
 
 static CompilerInvocation *
-createInvocationForMigration(CompilerInvocation &origCI) {
+createInvocationForMigration(CompilerInvocation &origCI,
+                             const PCHContainerOperations &PCHContainerOps) {
   std::unique_ptr<CompilerInvocation> CInvok;
   CInvok.reset(new CompilerInvocation(origCI));
   PreprocessorOptions &PPOpts = CInvok->getPreprocessorOpts();
@@ -178,9 +179,8 @@ createInvocationForMigration(CompilerInv
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
         new DiagnosticsEngine(DiagID, &origCI.getDiagnosticOpts(),
                               new IgnoringDiagConsumer()));
-    std::string OriginalFile =
-        ASTReader::getOriginalSourceFile(PPOpts.ImplicitPCHInclude,
-                                         FileMgr, *Diags);
+    std::string OriginalFile = ASTReader::getOriginalSourceFile(
+        PPOpts.ImplicitPCHInclude, FileMgr, PCHContainerOps, *Diags);
     if (!OriginalFile.empty())
       PPOpts.Includes.insert(PPOpts.Includes.begin(), OriginalFile);
     PPOpts.ImplicitPCHInclude.clear();
@@ -230,11 +230,11 @@ static void emitPremigrationErrors(const
 // checkForManualIssues.
 //===----------------------------------------------------------------------===//
 
-bool arcmt::checkForManualIssues(CompilerInvocation &origCI,
-                                 const FrontendInputFile &Input,
-                                 DiagnosticConsumer *DiagClient,
-                                 bool emitPremigrationARCErrors,
-                                 StringRef plistOut) {
+bool arcmt::checkForManualIssues(
+    CompilerInvocation &origCI, const FrontendInputFile &Input,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    DiagnosticConsumer *DiagClient, bool emitPremigrationARCErrors,
+    StringRef plistOut) {
   if (!origCI.getLangOpts()->ObjC1)
     return false;
 
@@ -247,7 +247,7 @@ bool arcmt::checkForManualIssues(Compile
   assert(!transforms.empty());
 
   std::unique_ptr<CompilerInvocation> CInvok;
-  CInvok.reset(createInvocationForMigration(origCI));
+  CInvok.reset(createInvocationForMigration(origCI, *PCHContainerOps));
   CInvok->getFrontendOpts().Inputs.clear();
   CInvok->getFrontendOpts().Inputs.push_back(Input);
 
@@ -263,8 +263,8 @@ bool arcmt::checkForManualIssues(Compile
   CaptureDiagnosticConsumer errRec(*Diags, *DiagClient, capturedDiags);
   Diags->setClient(&errRec, /*ShouldOwnClient=*/false);
 
-  std::unique_ptr<ASTUnit> Unit(
-      ASTUnit::LoadFromCompilerInvocationAction(CInvok.release(), Diags));
+  std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCompilerInvocationAction(
+      CInvok.release(), PCHContainerOps, Diags));
   if (!Unit) {
     errRec.FinishCapture();
     return true;
@@ -330,12 +330,11 @@ bool arcmt::checkForManualIssues(Compile
 // applyTransformations.
 //===----------------------------------------------------------------------===//
 
-static bool applyTransforms(CompilerInvocation &origCI,
-                            const FrontendInputFile &Input,
-                            DiagnosticConsumer *DiagClient,
-                            StringRef outputDir,
-                            bool emitPremigrationARCErrors,
-                            StringRef plistOut) {
+static bool
+applyTransforms(CompilerInvocation &origCI, const FrontendInputFile &Input,
+                std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+                DiagnosticConsumer *DiagClient, StringRef outputDir,
+                bool emitPremigrationARCErrors, StringRef plistOut) {
   if (!origCI.getLangOpts()->ObjC1)
     return false;
 
@@ -343,15 +342,16 @@ static bool applyTransforms(CompilerInvo
 
   // Make sure checking is successful first.
   CompilerInvocation CInvokForCheck(origCI);
-  if (arcmt::checkForManualIssues(CInvokForCheck, Input, DiagClient,
-                                  emitPremigrationARCErrors, plistOut))
+  if (arcmt::checkForManualIssues(CInvokForCheck, Input, PCHContainerOps,
+                                  DiagClient, emitPremigrationARCErrors,
+                                  plistOut))
     return true;
 
   CompilerInvocation CInvok(origCI);
   CInvok.getFrontendOpts().Inputs.clear();
   CInvok.getFrontendOpts().Inputs.push_back(Input);
-  
-  MigrationProcess migration(CInvok, DiagClient, outputDir);
+
+  MigrationProcess migration(CInvok, PCHContainerOps, DiagClient, outputDir);
   bool NoFinalizeRemoval = origCI.getMigratorOpts().NoFinalizeRemoval;
 
   std::vector<TransformFn> transforms = arcmt::getAllTransformations(OrigGCMode,
@@ -376,22 +376,22 @@ static bool applyTransforms(CompilerInvo
   }
 }
 
-bool arcmt::applyTransformations(CompilerInvocation &origCI,
-                                 const FrontendInputFile &Input,
-                                 DiagnosticConsumer *DiagClient) {
-  return applyTransforms(origCI, Input, DiagClient,
+bool arcmt::applyTransformations(
+    CompilerInvocation &origCI, const FrontendInputFile &Input,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    DiagnosticConsumer *DiagClient) {
+  return applyTransforms(origCI, Input, PCHContainerOps, DiagClient,
                          StringRef(), false, StringRef());
 }
 
-bool arcmt::migrateWithTemporaryFiles(CompilerInvocation &origCI,
-                                      const FrontendInputFile &Input,
-                                      DiagnosticConsumer *DiagClient,
-                                      StringRef outputDir,
-                                      bool emitPremigrationARCErrors,
-                                      StringRef plistOut) {
+bool arcmt::migrateWithTemporaryFiles(
+    CompilerInvocation &origCI, const FrontendInputFile &Input,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    DiagnosticConsumer *DiagClient, StringRef outputDir,
+    bool emitPremigrationARCErrors, StringRef plistOut) {
   assert(!outputDir.empty() && "Expected output directory path");
-  return applyTransforms(origCI, Input, DiagClient,
-                         outputDir, emitPremigrationARCErrors, plistOut);
+  return applyTransforms(origCI, Input, PCHContainerOps, DiagClient, outputDir,
+                         emitPremigrationARCErrors, plistOut);
 }
 
 bool arcmt::getFileRemappings(std::vector<std::pair<std::string,std::string> > &
@@ -499,10 +499,12 @@ public:
 /// \brief Anchor for VTable.
 MigrationProcess::RewriteListener::~RewriteListener() { }
 
-MigrationProcess::MigrationProcess(const CompilerInvocation &CI,
-                                   DiagnosticConsumer *diagClient,
-                                   StringRef outputDir)
-  : OrigCI(CI), DiagClient(diagClient), HadARCErrors(false) {
+MigrationProcess::MigrationProcess(
+    const CompilerInvocation &CI,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    DiagnosticConsumer *diagClient, StringRef outputDir)
+    : OrigCI(CI), PCHContainerOps(PCHContainerOps), DiagClient(diagClient),
+      HadARCErrors(false) {
   if (!outputDir.empty()) {
     IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
@@ -515,7 +517,7 @@ MigrationProcess::MigrationProcess(const
 bool MigrationProcess::applyTransform(TransformFn trans,
                                       RewriteListener *listener) {
   std::unique_ptr<CompilerInvocation> CInvok;
-  CInvok.reset(createInvocationForMigration(OrigCI));
+  CInvok.reset(createInvocationForMigration(OrigCI, *PCHContainerOps));
   CInvok->getDiagnosticOpts().IgnoreWarnings = true;
 
   Remapper.applyMappings(CInvok->getPreprocessorOpts());
@@ -537,7 +539,7 @@ bool MigrationProcess::applyTransform(Tr
   ASTAction.reset(new ARCMTMacroTrackerAction(ARCMTMacroLocs));
 
   std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCompilerInvocationAction(
-      CInvok.release(), Diags, ASTAction.get()));
+      CInvok.release(), PCHContainerOps, Diags, ASTAction.get()));
   if (!Unit) {
     errRec.FinishCapture();
     return true;

Modified: cfe/trunk/lib/ARCMigrate/ARCMTActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ARCMTActions.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/ARCMigrate/ARCMTActions.cpp (original)
+++ cfe/trunk/lib/ARCMigrate/ARCMTActions.cpp Sat Jun 20 13:53:08 2015
@@ -16,6 +16,7 @@ using namespace arcmt;
 
 bool CheckAction::BeginInvocation(CompilerInstance &CI) {
   if (arcmt::checkForManualIssues(CI.getInvocation(), getCurrentInput(),
+                                  CI.getPCHContainerOperations(),
                                   CI.getDiagnostics().getClient()))
     return false; // errors, stop the action.
 
@@ -29,6 +30,7 @@ CheckAction::CheckAction(FrontendAction
 
 bool ModifyAction::BeginInvocation(CompilerInstance &CI) {
   return !arcmt::applyTransformations(CI.getInvocation(), getCurrentInput(),
+                                      CI.getPCHContainerOperations(),
                                       CI.getDiagnostics().getClient());
 }
 
@@ -36,12 +38,10 @@ ModifyAction::ModifyAction(FrontendActio
   : WrapperFrontendAction(WrappedAction) {}
 
 bool MigrateAction::BeginInvocation(CompilerInstance &CI) {
-  if (arcmt::migrateWithTemporaryFiles(CI.getInvocation(),
-                                       getCurrentInput(),
-                                       CI.getDiagnostics().getClient(),
-                                       MigrateDir,
-                                       EmitPremigrationARCErros,
-                                       PlistOut))
+  if (arcmt::migrateWithTemporaryFiles(
+          CI.getInvocation(), getCurrentInput(), CI.getPCHContainerOperations(),
+          CI.getDiagnostics().getClient(), MigrateDir, EmitPremigrationARCErros,
+          PlistOut))
     return false; // errors, stop the action.
 
   // We only want to see diagnostics emitted by migrateWithTemporaryFiles.

Modified: cfe/trunk/lib/AST/ASTConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTConsumer.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTConsumer.cpp (original)
+++ cfe/trunk/lib/AST/ASTConsumer.cpp Sat Jun 20 13:53:08 2015
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/AST/ASTConsumer.h"
+#include "llvm/Bitcode/BitstreamReader.h"
 #include "clang/AST/Decl.h"
 #include "clang/AST/DeclGroup.h"
 using namespace clang;

Modified: cfe/trunk/lib/Frontend/ASTMerge.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTMerge.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTMerge.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTMerge.cpp Sat Jun 20 13:53:08 2015
@@ -45,8 +45,10 @@ void ASTMergeAction::ExecuteAction() {
                                     new ForwardingDiagnosticConsumer(
                                           *CI.getDiagnostics().getClient()),
                                     /*ShouldOwnClient=*/true));
-    std::unique_ptr<ASTUnit> Unit = ASTUnit::LoadFromASTFile(
-        ASTFiles[I], Diags, CI.getFileSystemOpts(), false);
+    std::unique_ptr<ASTUnit> Unit =
+        ASTUnit::LoadFromASTFile(ASTFiles[I], CI.getPCHContainerOperations(),
+                                 Diags, CI.getFileSystemOpts(), false);
+
     if (!Unit)
       continue;
 

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Sat Jun 20 13:53:08 2015
@@ -648,7 +648,9 @@ void ASTUnit::ConfigureDiags(IntrusiveRe
 }
 
 std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
-    const std::string &Filename, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
+    const std::string &Filename,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
     const FileSystemOptions &FileSystemOpts, bool OnlyLocalDecls,
     ArrayRef<RemappedFile> RemappedFiles, bool CaptureDiagnostics,
     bool AllowPCHWithCompilerErrors, bool UserFilesAreVolatile) {
@@ -705,10 +707,10 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFr
   bool disableValid = false;
   if (::getenv("LIBCLANG_DISABLE_PCH_VALIDATION"))
     disableValid = true;
-  AST->Reader = new ASTReader(PP, Context,
-                             /*isysroot=*/"",
-                             /*DisableValidation=*/disableValid,
-                             AllowPCHWithCompilerErrors);
+  AST->Reader = new ASTReader(PP, Context, *PCHContainerOps,
+                              /*isysroot=*/"",
+                              /*DisableValidation=*/disableValid,
+                              AllowPCHWithCompilerErrors);
 
   AST->Reader->setListener(llvm::make_unique<ASTInfoCollector>(
       *AST->PP, Context, AST->ASTFileLangOpts, AST->TargetOpts, AST->Target,
@@ -916,13 +918,16 @@ class PrecompilePreambleConsumer : publi
   unsigned &Hash;
   std::vector<Decl *> TopLevelDecls;
   PrecompilePreambleAction *Action;
+  raw_ostream *Out;
 
 public:
   PrecompilePreambleConsumer(ASTUnit &Unit, PrecompilePreambleAction *Action,
                              const Preprocessor &PP, StringRef isysroot,
                              raw_ostream *Out)
-    : PCHGenerator(PP, "", nullptr, isysroot, Out, /*AllowASTWithErrors=*/true),
-      Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action) {
+      : PCHGenerator(PP, "", nullptr, isysroot, std::make_shared<PCHBuffer>(),
+                     /*AllowASTWithErrors=*/true),
+        Unit(Unit), Hash(Unit.getCurrentTopLevelHashValue()), Action(Action),
+        Out(Out) {
     Hash = 0;
   }
 
@@ -943,6 +948,14 @@ public:
   void HandleTranslationUnit(ASTContext &Ctx) override {
     PCHGenerator::HandleTranslationUnit(Ctx);
     if (hasEmittedPCH()) {
+      // Write the generated bitstream to "Out".
+      *Out << getPCH();
+      // Make sure it hits disk now.
+      Out->flush();
+      // Free the buffer.
+      llvm::SmallVector<char, 0> Empty;
+      getPCH() = std::move(Empty);
+
       // Translate the top-level declarations we captured during
       // parsing into declaration IDs in the precompiled
       // preamble. This will allow us to deserialize those top-level
@@ -1015,14 +1028,16 @@ static void checkAndSanitizeDiags(SmallV
 ///
 /// \returns True if a failure occurred that causes the ASTUnit not to
 /// contain any translation-unit information, false otherwise.
-bool ASTUnit::Parse(std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer) {
+bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+                    std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer) {
   SavedMainFileBuffer.reset();
 
   if (!Invocation)
     return true;
 
   // Create the compiler instance to use for building the AST.
-  std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
+  std::unique_ptr<CompilerInstance> Clang(
+      new CompilerInstance(PCHContainerOps));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
@@ -1323,6 +1338,7 @@ makeStandaloneDiagnostic(const LangOptio
 /// Otherwise, returns a NULL pointer.
 std::unique_ptr<llvm::MemoryBuffer>
 ASTUnit::getMainBufferWithPrecompiledPreamble(
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild,
     unsigned MaxLines) {
 
@@ -1487,7 +1503,8 @@ ASTUnit::getMainBufferWithPrecompiledPre
   PreprocessorOpts.PrecompiledPreambleBytes.second = false;
   
   // Create the compiler instance to use for building the precompiled preamble.
-  std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
+  std::unique_ptr<CompilerInstance> Clang(
+      new CompilerInstance(PCHContainerOps));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
@@ -1702,12 +1719,13 @@ ASTUnit *ASTUnit::create(CompilerInvocat
 }
 
 ASTUnit *ASTUnit::LoadFromCompilerInvocationAction(
-    CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-    ASTFrontendAction *Action, ASTUnit *Unit, bool Persistent,
-    StringRef ResourceFilesPath, bool OnlyLocalDecls, bool CaptureDiagnostics,
-    bool PrecompilePreamble, bool CacheCodeCompletionResults,
-    bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile,
-    std::unique_ptr<ASTUnit> *ErrAST) {
+    CompilerInvocation *CI,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    IntrusiveRefCntPtr<DiagnosticsEngine> Diags, ASTFrontendAction *Action,
+    ASTUnit *Unit, bool Persistent, StringRef ResourceFilesPath,
+    bool OnlyLocalDecls, bool CaptureDiagnostics, bool PrecompilePreamble,
+    bool CacheCodeCompletionResults, bool IncludeBriefCommentsInCodeCompletion,
+    bool UserFilesAreVolatile, std::unique_ptr<ASTUnit> *ErrAST) {
   assert(CI && "A CompilerInvocation is required");
 
   std::unique_ptr<ASTUnit> OwnAST;
@@ -1746,7 +1764,8 @@ ASTUnit *ASTUnit::LoadFromCompilerInvoca
   ProcessWarningOptions(AST->getDiagnostics(), CI->getDiagnosticOpts());
 
   // Create the compiler instance to use for building the AST.
-  std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
+  std::unique_ptr<CompilerInstance> Clang(
+      new CompilerInstance(PCHContainerOps));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
@@ -1841,7 +1860,9 @@ ASTUnit *ASTUnit::LoadFromCompilerInvoca
     return AST;
 }
 
-bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) {
+bool ASTUnit::LoadFromCompilerInvocation(
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    bool PrecompilePreamble) {
   if (!Invocation)
     return true;
   
@@ -1853,7 +1874,8 @@ bool ASTUnit::LoadFromCompilerInvocation
   std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
   if (PrecompilePreamble) {
     PreambleRebuildCounter = 2;
-    OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation);
+    OverrideMainBuffer =
+        getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation);
   }
   
   SimpleTimer ParsingTimer(WantTiming);
@@ -1863,12 +1885,14 @@ bool ASTUnit::LoadFromCompilerInvocation
   llvm::CrashRecoveryContextCleanupRegistrar<llvm::MemoryBuffer>
     MemBufferCleanup(OverrideMainBuffer.get());
 
-  return Parse(std::move(OverrideMainBuffer));
+  return Parse(PCHContainerOps, std::move(OverrideMainBuffer));
 }
 
 std::unique_ptr<ASTUnit> ASTUnit::LoadFromCompilerInvocation(
-    CompilerInvocation *CI, IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
-    bool OnlyLocalDecls, bool CaptureDiagnostics, bool PrecompilePreamble,
+    CompilerInvocation *CI,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    IntrusiveRefCntPtr<DiagnosticsEngine> Diags, bool OnlyLocalDecls,
+    bool CaptureDiagnostics, bool PrecompilePreamble,
     TranslationUnitKind TUKind, bool CacheCodeCompletionResults,
     bool IncludeBriefCommentsInCodeCompletion, bool UserFilesAreVolatile) {
   // Create the AST unit.
@@ -1897,13 +1921,14 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFr
     llvm::CrashRecoveryContextReleaseRefCleanup<DiagnosticsEngine> >
     DiagCleanup(Diags.get());
 
-  if (AST->LoadFromCompilerInvocation(PrecompilePreamble))
+  if (AST->LoadFromCompilerInvocation(PCHContainerOps, PrecompilePreamble))
     return nullptr;
   return AST;
 }
 
 ASTUnit *ASTUnit::LoadFromCommandLine(
     const char **ArgBegin, const char **ArgEnd,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags, StringRef ResourceFilesPath,
     bool OnlyLocalDecls, bool CaptureDiagnostics,
     ArrayRef<RemappedFile> RemappedFiles, bool RemappedFilesKeepOriginalName,
@@ -1975,7 +2000,7 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
   llvm::CrashRecoveryContextCleanupRegistrar<ASTUnit>
     ASTUnitCleanup(AST.get());
 
-  if (AST->LoadFromCompilerInvocation(PrecompilePreamble)) {
+  if (AST->LoadFromCompilerInvocation(PCHContainerOps, PrecompilePreamble)) {
     // Some error occurred, if caller wants to examine diagnostics, pass it the
     // ASTUnit.
     if (ErrAST) {
@@ -1988,7 +2013,8 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
   return AST.release();
 }
 
-bool ASTUnit::Reparse(ArrayRef<RemappedFile> RemappedFiles) {
+bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+                      ArrayRef<RemappedFile> RemappedFiles) {
   if (!Invocation)
     return true;
 
@@ -2012,8 +2038,9 @@ bool ASTUnit::Reparse(ArrayRef<RemappedF
   // build a precompiled preamble, do so now.
   std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
   if (!getPreambleFile(this).empty() || PreambleRebuildCounter > 0)
-    OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation);
-    
+    OverrideMainBuffer =
+        getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation);
+
   // Clear out the diagnostics state.
   getDiagnostics().Reset();
   ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
@@ -2021,7 +2048,7 @@ bool ASTUnit::Reparse(ArrayRef<RemappedF
     getDiagnostics().setNumWarnings(NumWarningsInPreamble);
 
   // Parse the sources
-  bool Result = Parse(std::move(OverrideMainBuffer));
+  bool Result = Parse(PCHContainerOps, std::move(OverrideMainBuffer));
 
   // If we're caching global code-completion results, and the top-level 
   // declarations have changed, clear out the code-completion cache.
@@ -2273,18 +2300,15 @@ void AugmentedCodeCompleteConsumer::Proc
                                   AllResults.size());
 }
 
-
-
-void ASTUnit::CodeComplete(StringRef File, unsigned Line, unsigned Column,
-                           ArrayRef<RemappedFile> RemappedFiles,
-                           bool IncludeMacros, 
-                           bool IncludeCodePatterns,
-                           bool IncludeBriefComments,
-                           CodeCompleteConsumer &Consumer,
-                           DiagnosticsEngine &Diag, LangOptions &LangOpts,
-                           SourceManager &SourceMgr, FileManager &FileMgr,
-                   SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
-             SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) {
+void ASTUnit::CodeComplete(
+    StringRef File, unsigned Line, unsigned Column,
+    ArrayRef<RemappedFile> RemappedFiles, bool IncludeMacros,
+    bool IncludeCodePatterns, bool IncludeBriefComments,
+    CodeCompleteConsumer &Consumer,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    DiagnosticsEngine &Diag, LangOptions &LangOpts, SourceManager &SourceMgr,
+    FileManager &FileMgr, SmallVectorImpl<StoredDiagnostic> &StoredDiagnostics,
+    SmallVectorImpl<const llvm::MemoryBuffer *> &OwnedBuffers) {
   if (!Invocation)
     return;
 
@@ -2318,7 +2342,8 @@ void ASTUnit::CodeComplete(StringRef Fil
   LangOpts.SpellChecking = false;
   CCInvocation->getDiagnosticOpts().IgnoreWarnings = true;
 
-  std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
+  std::unique_ptr<CompilerInstance> Clang(
+      new CompilerInstance(PCHContainerOps));
 
   // Recover resources if we crash before exiting this method.
   llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
@@ -2389,7 +2414,7 @@ void ASTUnit::CodeComplete(StringRef Fil
       if (!llvm::sys::fs::getUniqueID(MainPath, MainID)) {
         if (CompleteFileID == MainID && Line > 1)
           OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
-              *CCInvocation, false, Line - 1);
+              PCHContainerOps, *CCInvocation, false, Line - 1);
       }
     }
   }

Modified: cfe/trunk/lib/Frontend/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CMakeLists.txt?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CMakeLists.txt (original)
+++ cfe/trunk/lib/Frontend/CMakeLists.txt Sat Jun 20 13:53:08 2015
@@ -31,6 +31,7 @@ add_clang_library(clangFrontend
   LogDiagnosticPrinter.cpp
   ModuleDependencyCollector.cpp
   MultiplexConsumer.cpp
+  PCHContainerOperations.cpp
   PrintPreprocessedOutput.cpp
   SerializedDiagnosticPrinter.cpp
   SerializedDiagnosticReader.cpp

Modified: cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp (original)
+++ cfe/trunk/lib/Frontend/ChainedIncludesSource.cpp Sat Jun 20 13:53:08 2015
@@ -80,8 +80,9 @@ createASTReader(CompilerInstance &CI, St
                 ASTDeserializationListener *deserialListener = nullptr) {
   Preprocessor &PP = CI.getPreprocessor();
   std::unique_ptr<ASTReader> Reader;
-  Reader.reset(new ASTReader(PP, CI.getASTContext(), /*isysroot=*/"",
-                             /*DisableValidation=*/true));
+  Reader.reset(new ASTReader(PP, CI.getASTContext(),
+                             *CI.getPCHContainerOperations(),
+                             /*isysroot=*/"", /*DisableValidation=*/true));
   for (unsigned ti = 0; ti < bufNames.size(); ++ti) {
     StringRef sr(bufNames[ti]);
     Reader->addInMemoryBuffer(sr, std::move(MemBufs[ti]));
@@ -145,7 +146,8 @@ IntrusiveRefCntPtr<ExternalSemaSource> c
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(
         new DiagnosticsEngine(DiagID, &CI.getDiagnosticOpts(), DiagClient));
 
-    std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
+    std::unique_ptr<CompilerInstance> Clang(
+        new CompilerInstance(CI.getPCHContainerOperations()));
     Clang->setInvocation(CInvok.release());
     Clang->setDiagnostics(Diags.get());
     Clang->setTarget(TargetInfo::CreateTargetInfo(
@@ -157,11 +159,9 @@ IntrusiveRefCntPtr<ExternalSemaSource> c
                                                  &Clang->getPreprocessor());
     Clang->createASTContext();
 
-    SmallVector<char, 256> serialAST;
-    llvm::raw_svector_ostream OS(serialAST);
-    auto consumer =
-        llvm::make_unique<PCHGenerator>(Clang->getPreprocessor(), "-", nullptr,
-                                        /*isysroot=*/"", &OS);
+    auto Buffer = std::make_shared<PCHBuffer>();
+    auto consumer = llvm::make_unique<PCHGenerator>(
+        Clang->getPreprocessor(), "-", nullptr, /*isysroot=*/"", Buffer);
     Clang->getASTContext().setASTMutationListener(
                                             consumer->GetASTMutationListener());
     Clang->setASTConsumer(std::move(consumer));
@@ -198,7 +198,11 @@ IntrusiveRefCntPtr<ExternalSemaSource> c
 
     ParseAST(Clang->getSema());
     Clang->getDiagnosticClient().EndSourceFile();
-    SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(OS.str()));
+    assert(Buffer->IsComplete && "serialization did not complete");
+    auto &serialAST = Buffer->Data;
+    SerialBufs.push_back(llvm::MemoryBuffer::getMemBufferCopy(
+        StringRef(serialAST.data(), serialAST.size())));
+    serialAST.clear();
     source->CIs.push_back(Clang.release());
   }
 

Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Sat Jun 20 13:53:08 2015
@@ -51,12 +51,13 @@
 
 using namespace clang;
 
-CompilerInstance::CompilerInstance(bool BuildingModule)
-  : ModuleLoader(BuildingModule),
-    Invocation(new CompilerInvocation()), ModuleManager(nullptr),
-    BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false),
-    ModuleBuildFailed(false) {
-}
+CompilerInstance::CompilerInstance(
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    bool BuildingModule)
+    : ModuleLoader(BuildingModule), Invocation(new CompilerInvocation()),
+      ModuleManager(nullptr), ThePCHContainerOperations(PCHContainerOps),
+      BuildGlobalModuleIndex(false), HaveFullGlobalModuleIndex(false),
+      ModuleBuildFailed(false) {}
 
 CompilerInstance::~CompilerInstance() {
   assert(OutputFiles.empty() && "Still output files in flight?");
@@ -321,7 +322,8 @@ void CompilerInstance::createPreprocesso
                           PP->getFileManager(), PPOpts);
 
   // Predefine macros and configure the preprocessor.
-  InitializePreprocessor(*PP, PPOpts, getFrontendOpts());
+  InitializePreprocessor(*PP, PPOpts, *getPCHContainerOperations(),
+                         getFrontendOpts());
 
   // Initialize the header search object.
   ApplyHeaderSearchOptions(PP->getHeaderSearchInfo(), getHeaderSearchOpts(),
@@ -397,22 +399,24 @@ void CompilerInstance::createPCHExternal
   ModuleManager = createPCHExternalASTSource(
       Path, getHeaderSearchOpts().Sysroot, DisablePCHValidation,
       AllowPCHWithCompilerErrors, getPreprocessor(), getASTContext(),
-      DeserializationListener, OwnDeserializationListener, Preamble,
+      *getPCHContainerOperations(), DeserializationListener,
+      OwnDeserializationListener, Preamble,
       getFrontendOpts().UseGlobalModuleIndex);
 }
 
 IntrusiveRefCntPtr<ASTReader> CompilerInstance::createPCHExternalASTSource(
     StringRef Path, const std::string &Sysroot, bool DisablePCHValidation,
     bool AllowPCHWithCompilerErrors, Preprocessor &PP, ASTContext &Context,
+    const PCHContainerOperations &PCHContainerOps,
     void *DeserializationListener, bool OwnDeserializationListener,
     bool Preamble, bool UseGlobalModuleIndex) {
   HeaderSearchOptions &HSOpts = PP.getHeaderSearchInfo().getHeaderSearchOpts();
 
-  IntrusiveRefCntPtr<ASTReader> Reader(
-      new ASTReader(PP, Context, Sysroot.empty() ? "" : Sysroot.c_str(),
-                    DisablePCHValidation, AllowPCHWithCompilerErrors,
-                    /*AllowConfigurationMismatch*/ false,
-                    HSOpts.ModulesValidateSystemHeaders, UseGlobalModuleIndex));
+  IntrusiveRefCntPtr<ASTReader> Reader(new ASTReader(
+      PP, Context, PCHContainerOps, Sysroot.empty() ? "" : Sysroot.c_str(),
+      DisablePCHValidation, AllowPCHWithCompilerErrors,
+      /*AllowConfigurationMismatch*/ false, HSOpts.ModulesValidateSystemHeaders,
+      UseGlobalModuleIndex));
 
   // We need the external source to be set up before we read the AST, because
   // eagerly-deserialized declarations may use it.
@@ -918,7 +922,8 @@ static bool compileModuleImpl(CompilerIn
   
   // Construct a compiler instance that will be used to actually create the
   // module.
-  CompilerInstance Instance(/*BuildingModule=*/true);
+  CompilerInstance Instance(ImportingInstance.getPCHContainerOperations(),
+                            /*BuildingModule=*/true);
   Instance.setInvocation(&*Invocation);
 
   Instance.createDiagnostics(new ForwardingDiagnosticConsumer(
@@ -1232,13 +1237,13 @@ void CompilerInstance::createModuleManag
     HeaderSearchOptions &HSOpts = getHeaderSearchOpts();
     std::string Sysroot = HSOpts.Sysroot;
     const PreprocessorOptions &PPOpts = getPreprocessorOpts();
-    ModuleManager = new ASTReader(getPreprocessor(), *Context,
-                                  Sysroot.empty() ? "" : Sysroot.c_str(),
-                                  PPOpts.DisablePCHValidation,
-                                  /*AllowASTWithCompilerErrors=*/false,
-                                  /*AllowConfigurationMismatch=*/false,
-                                  HSOpts.ModulesValidateSystemHeaders,
-                                  getFrontendOpts().UseGlobalModuleIndex);
+    ModuleManager = new ASTReader(
+        getPreprocessor(), *Context, *getPCHContainerOperations(),
+        Sysroot.empty() ? "" : Sysroot.c_str(), PPOpts.DisablePCHValidation,
+        /*AllowASTWithCompilerErrors=*/false,
+        /*AllowConfigurationMismatch=*/false,
+        HSOpts.ModulesValidateSystemHeaders,
+        getFrontendOpts().UseGlobalModuleIndex);
     if (hasASTConsumer()) {
       ModuleManager->setDeserializationListener(
         getASTConsumer().GetASTDeserializationListener());
@@ -1279,6 +1284,7 @@ bool CompilerInstance::loadModuleFile(St
       ModuleFileStack.push_back(FileName);
       ModuleNameStack.push_back(StringRef());
       if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),
+                                             *CI.getPCHContainerOperations(),
                                              *this)) {
         CI.getDiagnostics().Report(
             SourceLocation(), CI.getFileManager().getBufferForFile(FileName)
@@ -1644,8 +1650,8 @@ GlobalModuleIndex *CompilerInstance::loa
     llvm::sys::fs::create_directories(
       getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
     GlobalModuleIndex::writeIndex(
-      getFileManager(),
-      getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
+        getFileManager(), *getPCHContainerOperations(),
+        getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
     ModuleManager->resetForReload();
     ModuleManager->loadGlobalIndex();
     GlobalIndex = ModuleManager->getGlobalIndex();
@@ -1672,8 +1678,8 @@ GlobalModuleIndex *CompilerInstance::loa
     }
     if (RecreateIndex) {
       GlobalModuleIndex::writeIndex(
-        getFileManager(),
-        getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
+          getFileManager(), *getPCHContainerOperations(),
+          getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
       ModuleManager->resetForReload();
       ModuleManager->loadGlobalIndex();
       GlobalIndex = ModuleManager->getGlobalIndex();

Modified: cfe/trunk/lib/Frontend/FrontendAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendAction.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendAction.cpp Sat Jun 20 13:53:08 2015
@@ -191,7 +191,8 @@ bool FrontendAction::BeginSourceFile(Com
     IntrusiveRefCntPtr<DiagnosticsEngine> Diags(&CI.getDiagnostics());
 
     std::unique_ptr<ASTUnit> AST =
-        ASTUnit::LoadFromASTFile(InputFile, Diags, CI.getFileSystemOpts());
+        ASTUnit::LoadFromASTFile(InputFile, CI.getPCHContainerOperations(),
+                                 Diags, CI.getFileSystemOpts());
 
     if (!AST)
       goto failure;
@@ -271,11 +272,10 @@ bool FrontendAction::BeginSourceFile(Com
       for (llvm::sys::fs::directory_iterator Dir(DirNative, EC), DirEnd;
            Dir != DirEnd && !EC; Dir.increment(EC)) {
         // Check whether this is an acceptable AST file.
-        if (ASTReader::isAcceptableASTFile(Dir->path(), FileMgr,
-                                           CI.getLangOpts(),
-                                           CI.getTargetOpts(),
-                                           CI.getPreprocessorOpts(),
-                                           SpecificModuleCachePath)) {
+        if (ASTReader::isAcceptableASTFile(
+                Dir->path(), FileMgr, *CI.getPCHContainerOperations(),
+                CI.getLangOpts(), CI.getTargetOpts(), CI.getPreprocessorOpts(),
+                SpecificModuleCachePath)) {
           PPOpts.ImplicitPCHInclude = Dir->path();
           Found = true;
           break;
@@ -443,8 +443,8 @@ bool FrontendAction::Execute() {
   if (CI.shouldBuildGlobalModuleIndex() && CI.hasFileManager() &&
       CI.hasPreprocessor()) {
     GlobalModuleIndex::writeIndex(
-      CI.getFileManager(),
-      CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
+        CI.getFileManager(), *CI.getPCHContainerOperations(),
+        CI.getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
   }
 
   return true;

Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Sat Jun 20 13:53:08 2015
@@ -14,6 +14,7 @@
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/CompilerInstance.h"
 #include "clang/Frontend/FrontendDiagnostic.h"
+#include "clang/Frontend/MultiplexConsumer.h"
 #include "clang/Frontend/Utils.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/Pragma.h"
@@ -79,18 +80,28 @@ std::unique_ptr<ASTConsumer>
 GeneratePCHAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
   std::string Sysroot;
   std::string OutputFile;
-  raw_ostream *OS =
+  raw_pwrite_stream *OS =
       ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile);
   if (!OS)
     return nullptr;
 
   if (!CI.getFrontendOpts().RelocatablePCH)
     Sysroot.clear();
-  return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile,
-                                         nullptr, Sysroot, OS);
+
+  auto Buffer = std::make_shared<PCHBuffer>();
+  std::vector<std::unique_ptr<ASTConsumer>> Consumers;
+  Consumers.push_back(llvm::make_unique<PCHGenerator>(
+      CI.getPreprocessor(), OutputFile, nullptr, Sysroot, Buffer));
+  Consumers.push_back(
+      CI.getPCHContainerOperations()->CreatePCHContainerGenerator(
+          CI.getDiagnostics(), CI.getHeaderSearchOpts(),
+          CI.getPreprocessorOpts(), CI.getTargetOpts(), CI.getLangOpts(),
+          InFile, OutputFile, OS, Buffer));
+
+  return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
 }
 
-raw_ostream *GeneratePCHAction::ComputeASTConsumerArguments(
+raw_pwrite_stream *GeneratePCHAction::ComputeASTConsumerArguments(
     CompilerInstance &CI, StringRef InFile, std::string &Sysroot,
     std::string &OutputFile) {
   Sysroot = CI.getHeaderSearchOpts().Sysroot;
@@ -102,7 +113,7 @@ raw_ostream *GeneratePCHAction::ComputeA
   // We use createOutputFile here because this is exposed via libclang, and we
   // must disable the RemoveFileOnSignal behavior.
   // We use a temporary to avoid race conditions.
-  raw_ostream *OS =
+  raw_pwrite_stream *OS =
       CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
                           /*RemoveFileOnSignal=*/false, InFile,
                           /*Extension=*/"", /*useTemporary=*/true);
@@ -118,13 +129,21 @@ GenerateModuleAction::CreateASTConsumer(
                                         StringRef InFile) {
   std::string Sysroot;
   std::string OutputFile;
-  raw_ostream *OS =
+  raw_pwrite_stream *OS =
       ComputeASTConsumerArguments(CI, InFile, Sysroot, OutputFile);
   if (!OS)
     return nullptr;
 
-  return llvm::make_unique<PCHGenerator>(CI.getPreprocessor(), OutputFile,
-                                         Module, Sysroot, OS);
+  auto Buffer = std::make_shared<PCHBuffer>();
+  std::vector<std::unique_ptr<ASTConsumer>> Consumers;
+  Consumers.push_back(llvm::make_unique<PCHGenerator>(
+      CI.getPreprocessor(), OutputFile, Module, Sysroot, Buffer));
+  Consumers.push_back(
+      CI.getPCHContainerOperations()->CreatePCHContainerGenerator(
+          CI.getDiagnostics(), CI.getHeaderSearchOpts(),
+          CI.getPreprocessorOpts(), CI.getTargetOpts(), CI.getLangOpts(),
+          InFile, OutputFile, OS, Buffer));
+  return llvm::make_unique<MultiplexConsumer>(std::move(Consumers));
 }
 
 static SmallVectorImpl<char> &
@@ -348,7 +367,7 @@ bool GenerateModuleAction::BeginSourceFi
   return true;
 }
 
-raw_ostream *GenerateModuleAction::ComputeASTConsumerArguments(
+raw_pwrite_stream *GenerateModuleAction::ComputeASTConsumerArguments(
     CompilerInstance &CI, StringRef InFile, std::string &Sysroot,
     std::string &OutputFile) {
   // If no output file was provided, figure out where this module would go
@@ -363,7 +382,7 @@ raw_ostream *GenerateModuleAction::Compu
   // We use createOutputFile here because this is exposed via libclang, and we
   // must disable the RemoveFileOnSignal behavior.
   // We use a temporary to avoid race conditions.
-  raw_ostream *OS =
+  raw_pwrite_stream *OS =
       CI.createOutputFile(CI.getFrontendOpts().OutputFile, /*Binary=*/true,
                           /*RemoveFileOnSignal=*/false, InFile,
                           /*Extension=*/"", /*useTemporary=*/true,
@@ -395,13 +414,13 @@ void VerifyPCHAction::ExecuteAction() {
   CompilerInstance &CI = getCompilerInstance();
   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(),
-                    Sysroot.empty() ? "" : Sysroot.c_str(),
-                    /*DisableValidation*/ false,
-                    /*AllowPCHWithCompilerErrors*/ false,
-                    /*AllowConfigurationMismatch*/ true,
-                    /*ValidateSystemInputs*/ true));
+  std::unique_ptr<ASTReader> Reader(new ASTReader(
+      CI.getPreprocessor(), CI.getASTContext(), *CI.getPCHContainerOperations(),
+      Sysroot.empty() ? "" : Sysroot.c_str(),
+      /*DisableValidation*/ false,
+      /*AllowPCHWithCompilerErrors*/ false,
+      /*AllowConfigurationMismatch*/ true,
+      /*ValidateSystemInputs*/ true));
 
   Reader->ReadAST(getCurrentFile(),
                   Preamble ? serialization::MK_Preamble
@@ -550,9 +569,9 @@ void DumpModuleInfoAction::ExecuteAction
 
   Out << "Information for module file '" << getCurrentFile() << "':\n";
   DumpModuleInfoListener Listener(Out);
-  ASTReader::readASTFileControlBlock(getCurrentFile(),
-                                     getCompilerInstance().getFileManager(),
-                                     Listener);
+  ASTReader::readASTFileControlBlock(
+      getCurrentFile(), getCompilerInstance().getFileManager(),
+      *getCompilerInstance().getPCHContainerOperations(), Listener);
 }
 
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/lib/Frontend/InitPreprocessor.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/InitPreprocessor.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/InitPreprocessor.cpp (original)
+++ cfe/trunk/lib/Frontend/InitPreprocessor.cpp Sat Jun 20 13:53:08 2015
@@ -97,10 +97,11 @@ static void AddImplicitIncludePTH(MacroB
 /// \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) {
   std::string OriginalFile =
-    ASTReader::getOriginalSourceFile(ImplicitIncludePCH, PP.getFileManager(),
-                                     PP.getDiagnostics());
+      ASTReader::getOriginalSourceFile(ImplicitIncludePCH, PP.getFileManager(),
+                                       PCHContainerOps, PP.getDiagnostics());
   if (OriginalFile.empty())
     return;
 
@@ -891,9 +892,10 @@ static void InitializePredefinedMacros(c
 /// InitializePreprocessor - Initialize the preprocessor getting it and the
 /// environment ready to process a single file. This returns true on error.
 ///
-void clang::InitializePreprocessor(Preprocessor &PP,
-                                   const PreprocessorOptions &InitOpts,
-                                   const FrontendOptions &FEOpts) {
+void clang::InitializePreprocessor(
+    Preprocessor &PP, const PreprocessorOptions &InitOpts,
+    const PCHContainerOperations &PCHContainerOps,
+    const FrontendOptions &FEOpts) {
   const LangOptions &LangOpts = PP.getLangOpts();
   std::string PredefineBuffer;
   PredefineBuffer.reserve(4080);
@@ -952,7 +954,8 @@ void clang::InitializePreprocessor(Prepr
 
   // Process -include-pch/-include-pth directives.
   if (!InitOpts.ImplicitPCHInclude.empty())
-    AddImplicitIncludePCH(Builder, PP, InitOpts.ImplicitPCHInclude);
+    AddImplicitIncludePCH(Builder, PP, PCHContainerOps,
+                          InitOpts.ImplicitPCHInclude);
   if (!InitOpts.ImplicitPTHInclude.empty())
     AddImplicitIncludePTH(Builder, PP, InitOpts.ImplicitPTHInclude);
 

Added: cfe/trunk/lib/Frontend/PCHContainerOperations.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHContainerOperations.cpp?rev=240225&view=auto
==============================================================================
--- cfe/trunk/lib/Frontend/PCHContainerOperations.cpp (added)
+++ cfe/trunk/lib/Frontend/PCHContainerOperations.cpp Sat Jun 20 13:53:08 2015
@@ -0,0 +1,70 @@
+//===--- Frontend/PCHContainerOperations.cpp - PCH Containers ---*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+//  This file defines PCHContainerOperations and RawPCHContainerOperation.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Frontend/PCHContainerOperations.h"
+#include "clang/AST/ASTConsumer.h"
+#include "llvm/Bitcode/BitstreamReader.h"
+#include "llvm/Support/raw_ostream.h"
+#include "clang/Lex/ModuleLoader.h"
+using namespace clang;
+
+PCHContainerOperations::~PCHContainerOperations() {}
+
+namespace {
+
+/// \brief A PCHContainerGenerator that writes out the PCH to a flat file.
+class PCHContainerGenerator : public ASTConsumer {
+  std::shared_ptr<PCHBuffer> Buffer;
+  raw_pwrite_stream *OS;
+
+public:
+  PCHContainerGenerator(DiagnosticsEngine &Diags,
+                        const HeaderSearchOptions &HSO,
+                        const PreprocessorOptions &PPO, const TargetOptions &TO,
+                        const LangOptions &LO, const std::string &MainFileName,
+                        const std::string &OutputFileName,
+                        llvm::raw_pwrite_stream *OS,
+                        std::shared_ptr<PCHBuffer> Buffer)
+      : Buffer(Buffer), OS(OS) {}
+
+  virtual ~PCHContainerGenerator() {}
+
+  void HandleTranslationUnit(ASTContext &Ctx) override {
+    if (Buffer->IsComplete) {
+      // Make sure it hits disk now.
+      *OS << Buffer->Data;
+      OS->flush();
+    }
+    // Free the space of the temporary buffer.
+    llvm::SmallVector<char, 0> Empty;
+    Buffer->Data = std::move(Empty);
+  }
+};
+}
+
+std::unique_ptr<ASTConsumer>
+RawPCHContainerOperations::CreatePCHContainerGenerator(
+    DiagnosticsEngine &Diags, const HeaderSearchOptions &HSO,
+    const PreprocessorOptions &PPO, const TargetOptions &TO,
+    const LangOptions &LO, const std::string &MainFileName,
+    const std::string &OutputFileName, llvm::raw_pwrite_stream *OS,
+    std::shared_ptr<PCHBuffer> Buffer) const {
+  return llvm::make_unique<PCHContainerGenerator>(
+      Diags, HSO, PPO, TO, LO, MainFileName, OutputFileName, OS, Buffer);
+}
+
+void RawPCHContainerOperations::ExtractPCH(
+    llvm::MemoryBufferRef Buffer, llvm::BitstreamReader &StreamFile) const {
+  StreamFile.init((const unsigned char *)Buffer.getBufferStart(),
+                  (const unsigned char *)Buffer.getBufferEnd());
+}

Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Sat Jun 20 13:53:08 2015
@@ -19,6 +19,7 @@
 #include "clang/AST/DeclTemplate.h"
 #include "clang/AST/Expr.h"
 #include "clang/AST/ExprCXX.h"
+#include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeLocVisitor.h"
@@ -3590,6 +3591,7 @@ ASTReader::ReadASTCore(StringRef FileNam
 
   ModuleFile &F = *M;
   BitstreamCursor &Stream = F.Stream;
+  PCHContainerOps.ExtractPCH(F.Buffer->getMemBufferRef(), F.StreamFile);
   Stream.init(&F.StreamFile);
   F.SizeInBits = F.Buffer->getBufferSize() * 8;
   
@@ -3858,9 +3860,9 @@ static ASTFileSignature readASTFileSigna
 /// \brief Retrieve the name of the original source file name
 /// directly from the AST file, without actually loading the AST
 /// file.
-std::string ASTReader::getOriginalSourceFile(const std::string &ASTFileName,
-                                             FileManager &FileMgr,
-                                             DiagnosticsEngine &Diags) {
+std::string ASTReader::getOriginalSourceFile(
+    const std::string &ASTFileName, FileManager &FileMgr,
+    const PCHContainerOperations &PCHContainerOps, DiagnosticsEngine &Diags) {
   // Open the AST file.
   auto Buffer = FileMgr.getBufferForFile(ASTFileName);
   if (!Buffer) {
@@ -3871,8 +3873,7 @@ std::string ASTReader::getOriginalSource
 
   // Initialize the stream
   llvm::BitstreamReader StreamFile;
-  StreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(),
-                  (const unsigned char *)(*Buffer)->getBufferEnd());
+  PCHContainerOps.ExtractPCH((*Buffer)->getMemBufferRef(), StreamFile);
   BitstreamCursor Stream(StreamFile);
 
   // Sniff for the signature.
@@ -3954,9 +3955,10 @@ namespace {
   };
 }
 
-bool ASTReader::readASTFileControlBlock(StringRef Filename,
-                                        FileManager &FileMgr,
-                                        ASTReaderListener &Listener) {
+bool ASTReader::readASTFileControlBlock(
+    StringRef Filename, FileManager &FileMgr,
+    const PCHContainerOperations &PCHContainerOps,
+    ASTReaderListener &Listener) {
   // Open the AST file.
   // FIXME: This allows use of the VFS; we do not allow use of the
   // VFS when actually loading a module.
@@ -4147,16 +4149,15 @@ bool ASTReader::readASTFileControlBlock(
   }
 }
 
-
-bool ASTReader::isAcceptableASTFile(StringRef Filename,
-                                    FileManager &FileMgr,
-                                    const LangOptions &LangOpts,
-                                    const TargetOptions &TargetOpts,
-                                    const PreprocessorOptions &PPOpts,
-                                    std::string ExistingModuleCachePath) {
+bool ASTReader::isAcceptableASTFile(
+    StringRef Filename, FileManager &FileMgr,
+    const 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, validator);
+  return !readASTFileControlBlock(Filename, FileMgr, PCHContainerOps,
+                                  validator);
 }
 
 ASTReader::ASTReadResult
@@ -8407,24 +8408,26 @@ void ASTReader::pushExternalDeclIntoScop
   }
 }
 
-ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context, StringRef isysroot,
-                     bool DisableValidation, bool AllowASTWithCompilerErrors,
+ASTReader::ASTReader(Preprocessor &PP, ASTContext &Context,
+                     const PCHContainerOperations &PCHContainerOps,
+                     StringRef isysroot, bool DisableValidation,
+                     bool AllowASTWithCompilerErrors,
                      bool AllowConfigurationMismatch, bool ValidateSystemInputs,
                      bool UseGlobalIndex)
     : Listener(new PCHValidator(PP, *this)), DeserializationListener(nullptr),
       OwnsDeserializationListener(false), SourceMgr(PP.getSourceManager()),
-      FileMgr(PP.getFileManager()), Diags(PP.getDiagnostics()),
-      SemaObj(nullptr), PP(PP), Context(Context), Consumer(nullptr),
-      ModuleMgr(PP.getFileManager()), isysroot(isysroot),
-      DisableValidation(DisableValidation),
+      FileMgr(PP.getFileManager()), PCHContainerOps(PCHContainerOps),
+      Diags(PP.getDiagnostics()), SemaObj(nullptr), PP(PP), Context(Context),
+      Consumer(nullptr), ModuleMgr(PP.getFileManager(), PCHContainerOps),
+      isysroot(isysroot), DisableValidation(DisableValidation),
       AllowASTWithCompilerErrors(AllowASTWithCompilerErrors),
       AllowConfigurationMismatch(AllowConfigurationMismatch),
       ValidateSystemInputs(ValidateSystemInputs),
       UseGlobalIndex(UseGlobalIndex), TriedLoadingGlobalIndex(false),
-      CurrSwitchCaseStmts(&SwitchCaseStmts),
-      NumSLocEntriesRead(0), TotalNumSLocEntries(0), NumStatementsRead(0),
-      TotalNumStatements(0), NumMacrosRead(0), TotalNumMacros(0),
-      NumIdentifierLookups(0), NumIdentifierLookupHits(0), NumSelectorsRead(0),
+      CurrSwitchCaseStmts(&SwitchCaseStmts), NumSLocEntriesRead(0),
+      TotalNumSLocEntries(0), NumStatementsRead(0), TotalNumStatements(0),
+      NumMacrosRead(0), TotalNumMacros(0), NumIdentifierLookups(0),
+      NumIdentifierLookupHits(0), NumSelectorsRead(0),
       NumMethodPoolEntriesRead(0), NumMethodPoolLookups(0),
       NumMethodPoolHits(0), NumMethodPoolTableLookups(0),
       NumMethodPoolTableHits(0), TotalNumMethodPoolEntries(0),

Modified: cfe/trunk/lib/Serialization/GeneratePCH.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/GeneratePCH.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/GeneratePCH.cpp (original)
+++ cfe/trunk/lib/Serialization/GeneratePCH.cpp Sat Jun 20 13:53:08 2015
@@ -24,16 +24,14 @@
 
 using namespace clang;
 
-PCHGenerator::PCHGenerator(const Preprocessor &PP,
-                           StringRef OutputFile,
-                           clang::Module *Module,
-                           StringRef isysroot,
-                           raw_ostream *OS, bool AllowASTWithErrors)
-  : PP(PP), OutputFile(OutputFile), Module(Module), 
-    isysroot(isysroot.str()), Out(OS), 
-    SemaPtr(nullptr), Stream(Buffer), Writer(Stream),
-    AllowASTWithErrors(AllowASTWithErrors),
-    HasEmittedPCH(false) {
+PCHGenerator::PCHGenerator(const Preprocessor &PP, StringRef OutputFile,
+                           clang::Module *Module, StringRef isysroot,
+                           std::shared_ptr<PCHBuffer> Buffer,
+                           bool AllowASTWithErrors)
+    : PP(PP), OutputFile(OutputFile), Module(Module), isysroot(isysroot.str()),
+      SemaPtr(nullptr), Buffer(Buffer), Stream(Buffer->Data), Writer(Stream),
+      AllowASTWithErrors(AllowASTWithErrors) {
+  Buffer->IsComplete = false;
 }
 
 PCHGenerator::~PCHGenerator() {
@@ -47,21 +45,12 @@ void PCHGenerator::HandleTranslationUnit
   bool hasErrors = PP.getDiagnostics().hasErrorOccurred();
   if (hasErrors && !AllowASTWithErrors)
     return;
-  
-  // Emit the PCH file
+
+  // Emit the PCH file to the Buffer.
   assert(SemaPtr && "No Sema?");
   Writer.WriteAST(*SemaPtr, OutputFile, Module, isysroot, hasErrors);
 
-  // Write the generated bitstream to "Out".
-  Out->write((char *)&Buffer.front(), Buffer.size());
-
-  // Make sure it hits disk now.
-  Out->flush();
-
-  // Free up some memory, in case the process is kept alive.
-  Buffer.clear();
-
-  HasEmittedPCH = true;
+  Buffer->IsComplete = true;
 }
 
 ASTMutationListener *PCHGenerator::GetASTMutationListener() {

Modified: cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp (original)
+++ cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp Sat Jun 20 13:53:08 2015
@@ -12,6 +12,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "ASTReaderInternals.h"
+#include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Serialization/ASTBitCodes.h"
@@ -384,6 +385,7 @@ namespace {
   /// \brief Builder that generates the global module index file.
   class GlobalModuleIndexBuilder {
     FileManager &FileMgr;
+    const PCHContainerOperations &PCHContainerOps;
 
     /// \brief Mapping from files to module file information.
     typedef llvm::MapVector<const FileEntry *, ModuleFileInfo> ModuleFilesMap;
@@ -416,7 +418,9 @@ namespace {
     }
 
   public:
-    explicit GlobalModuleIndexBuilder(FileManager &FileMgr) : FileMgr(FileMgr){}
+    explicit GlobalModuleIndexBuilder(
+        FileManager &FileMgr, const PCHContainerOperations &PCHContainerOps)
+        : FileMgr(FileMgr), PCHContainerOps(PCHContainerOps) {}
 
     /// \brief Load the contents of the given module file into the builder.
     ///
@@ -501,8 +505,7 @@ bool GlobalModuleIndexBuilder::loadModul
 
   // Initialize the input stream
   llvm::BitstreamReader InStreamFile;
-  InStreamFile.init((const unsigned char *)(*Buffer)->getBufferStart(),
-                    (const unsigned char *)(*Buffer)->getBufferEnd());
+  PCHContainerOps.ExtractPCH((*Buffer)->getMemBufferRef(), InStreamFile);
   llvm::BitstreamCursor InStream(InStreamFile);
 
   // Sniff for the signature.
@@ -764,7 +767,9 @@ void GlobalModuleIndexBuilder::writeInde
 }
 
 GlobalModuleIndex::ErrorCode
-GlobalModuleIndex::writeIndex(FileManager &FileMgr, StringRef Path) {
+GlobalModuleIndex::writeIndex(FileManager &FileMgr,
+                              const PCHContainerOperations &PCHContainerOps,
+                              StringRef Path) {
   llvm::SmallString<128> IndexPath;
   IndexPath += Path;
   llvm::sys::path::append(IndexPath, IndexFileName);
@@ -787,8 +792,8 @@ GlobalModuleIndex::writeIndex(FileManage
   }
 
   // The module index builder.
-  GlobalModuleIndexBuilder Builder(FileMgr);
-  
+  GlobalModuleIndexBuilder Builder(FileMgr, PCHContainerOps);
+
   // Load each of the module files.
   std::error_code EC;
   for (llvm::sys::fs::directory_iterator D(Path, EC), DEnd;

Modified: cfe/trunk/lib/Serialization/ModuleManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ModuleManager.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ModuleManager.cpp (original)
+++ cfe/trunk/lib/Serialization/ModuleManager.cpp Sat Jun 20 13:53:08 2015
@@ -11,6 +11,7 @@
 //  modules for the ASTReader.
 //
 //===----------------------------------------------------------------------===//
+#include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/Lex/HeaderSearch.h"
 #include "clang/Lex/ModuleMap.h"
 #include "clang/Serialization/GlobalModuleIndex.h"
@@ -136,10 +137,9 @@ ModuleManager::addModule(StringRef FileN
 
       New->Buffer = std::move(*Buf);
     }
-    
-    // Initialize the stream
-    New->StreamFile.init((const unsigned char *)New->Buffer->getBufferStart(),
-                         (const unsigned char *)New->Buffer->getBufferEnd());
+
+    // Initialize the stream.
+    PCHContainerOps.ExtractPCH(New->Buffer->getMemBufferRef(), New->StreamFile);
   }
 
   if (ExpectedSignature) {
@@ -289,8 +289,10 @@ void ModuleManager::moduleFileAccepted(M
   ModulesInCommonWithGlobalIndex.push_back(MF);
 }
 
-ModuleManager::ModuleManager(FileManager &FileMgr)
-  : FileMgr(FileMgr), GlobalIndex(), FirstVisitState(nullptr) {}
+ModuleManager::ModuleManager(FileManager &FileMgr,
+                             const PCHContainerOperations &PCHContainerOps)
+    : FileMgr(FileMgr), PCHContainerOps(PCHContainerOps), GlobalIndex(),
+      FirstVisitState(nullptr) {}
 
 ModuleManager::~ModuleManager() {
   for (unsigned i = 0, e = Chain.size(); i != e; ++i)

Modified: cfe/trunk/lib/StaticAnalyzer/Frontend/ModelInjector.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Frontend/ModelInjector.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Frontend/ModelInjector.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Frontend/ModelInjector.cpp Sat Jun 20 13:53:08 2015
@@ -76,7 +76,7 @@ void ModelInjector::onBodySynthesis(cons
 
   // Modules are parsed by a separate CompilerInstance, so this code mimics that
   // behavior for models
-  CompilerInstance Instance;
+  CompilerInstance Instance(CI.getPCHContainerOperations());
   Instance.setInvocation(&*Invocation);
   Instance.createDiagnostics(
       new ForwardingDiagnosticConsumer(CI.getDiagnosticClient()),

Modified: cfe/trunk/lib/Tooling/Refactoring.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Refactoring.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/Refactoring.cpp (original)
+++ cfe/trunk/lib/Tooling/Refactoring.cpp Sat Jun 20 13:53:08 2015
@@ -25,9 +25,10 @@
 namespace clang {
 namespace tooling {
 
-RefactoringTool::RefactoringTool(const CompilationDatabase &Compilations,
-                                 ArrayRef<std::string> SourcePaths)
-  : ClangTool(Compilations, SourcePaths) {}
+RefactoringTool::RefactoringTool(
+    const CompilationDatabase &Compilations, ArrayRef<std::string> SourcePaths,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps)
+    : ClangTool(Compilations, SourcePaths, PCHContainerOps) {}
 
 Replacements &RefactoringTool::getReplacements() { return Replace; }
 

Modified: cfe/trunk/lib/Tooling/Tooling.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Tooling/Tooling.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/lib/Tooling/Tooling.cpp (original)
+++ cfe/trunk/lib/Tooling/Tooling.cpp Sat Jun 20 13:53:08 2015
@@ -105,9 +105,10 @@ clang::CompilerInvocation *newInvocation
 }
 
 bool runToolOnCode(clang::FrontendAction *ToolAction, const Twine &Code,
-                   const Twine &FileName) {
-  return runToolOnCodeWithArgs(
-      ToolAction, Code, std::vector<std::string>(), FileName);
+                   const Twine &FileName,
+                   std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
+  return runToolOnCodeWithArgs(ToolAction, Code, std::vector<std::string>(),
+                               FileName, PCHContainerOps);
 }
 
 static std::vector<std::string>
@@ -121,17 +122,18 @@ getSyntaxOnlyToolArgs(const std::vector<
   return Args;
 }
 
-bool runToolOnCodeWithArgs(clang::FrontendAction *ToolAction, const Twine &Code,
-                           const std::vector<std::string> &Args,
-                           const Twine &FileName,
-                           const FileContentMappings &VirtualMappedFiles) {
+bool runToolOnCodeWithArgs(
+    clang::FrontendAction *ToolAction, const Twine &Code,
+    const std::vector<std::string> &Args, const Twine &FileName,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    const FileContentMappings &VirtualMappedFiles) {
 
   SmallString<16> FileNameStorage;
   StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
   llvm::IntrusiveRefCntPtr<FileManager> Files(
       new FileManager(FileSystemOptions()));
   ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef),
-                            ToolAction, Files.get());
+                            ToolAction, Files.get(), PCHContainerOps);
 
   SmallString<1024> CodeStorage;
   Invocation.mapVirtualFile(FileNameRef,
@@ -173,21 +175,18 @@ public:
 
 }
 
-ToolInvocation::ToolInvocation(std::vector<std::string> CommandLine,
-                               ToolAction *Action, FileManager *Files)
+ToolInvocation::ToolInvocation(
+    std::vector<std::string> CommandLine, ToolAction *Action,
+    FileManager *Files, std::shared_ptr<PCHContainerOperations> PCHContainerOps)
+    : CommandLine(std::move(CommandLine)), Action(Action), OwnsAction(false),
+      Files(Files), PCHContainerOps(PCHContainerOps), DiagConsumer(nullptr) {}
+
+ToolInvocation::ToolInvocation(
+    std::vector<std::string> CommandLine, FrontendAction *FAction,
+    FileManager *Files, std::shared_ptr<PCHContainerOperations> PCHContainerOps)
     : CommandLine(std::move(CommandLine)),
-      Action(Action),
-      OwnsAction(false),
-      Files(Files),
-      DiagConsumer(nullptr) {}
-
-ToolInvocation::ToolInvocation(std::vector<std::string> CommandLine,
-                               FrontendAction *FAction, FileManager *Files)
-    : CommandLine(std::move(CommandLine)),
-      Action(new SingleFrontendActionFactory(FAction)),
-      OwnsAction(true),
-      Files(Files),
-      DiagConsumer(nullptr) {}
+      Action(new SingleFrontendActionFactory(FAction)), OwnsAction(true),
+      Files(Files), PCHContainerOps(PCHContainerOps), DiagConsumer(nullptr) {}
 
 ToolInvocation::~ToolInvocation() {
   if (OwnsAction)
@@ -232,13 +231,14 @@ bool ToolInvocation::run() {
     Invocation->getPreprocessorOpts().addRemappedFile(It.getKey(),
                                                       Input.release());
   }
-  return runInvocation(BinaryName, Compilation.get(), Invocation.release());
+  return runInvocation(BinaryName, Compilation.get(), Invocation.release(),
+                       PCHContainerOps);
 }
 
 bool ToolInvocation::runInvocation(
-    const char *BinaryName,
-    clang::driver::Compilation *Compilation,
-    clang::CompilerInvocation *Invocation) {
+    const char *BinaryName, clang::driver::Compilation *Compilation,
+    clang::CompilerInvocation *Invocation,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
   // Show the invocation, with -v.
   if (Invocation->getHeaderSearchOpts().Verbose) {
     llvm::errs() << "clang Invocation:\n";
@@ -246,14 +246,16 @@ bool ToolInvocation::runInvocation(
     llvm::errs() << "\n";
   }
 
-  return Action->runInvocation(Invocation, Files, DiagConsumer);
+  return Action->runInvocation(Invocation, Files, PCHContainerOps,
+                               DiagConsumer);
 }
 
-bool FrontendActionFactory::runInvocation(CompilerInvocation *Invocation,
-                                          FileManager *Files,
-                                          DiagnosticConsumer *DiagConsumer) {
+bool FrontendActionFactory::runInvocation(
+    CompilerInvocation *Invocation, FileManager *Files,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+    DiagnosticConsumer *DiagConsumer) {
   // Create a compiler instance to handle the actual work.
-  clang::CompilerInstance Compiler;
+  clang::CompilerInstance Compiler(PCHContainerOps);
   Compiler.setInvocation(Invocation);
   Compiler.setFileManager(Files);
 
@@ -276,8 +278,10 @@ bool FrontendActionFactory::runInvocatio
 }
 
 ClangTool::ClangTool(const CompilationDatabase &Compilations,
-                     ArrayRef<std::string> SourcePaths)
+                     ArrayRef<std::string> SourcePaths,
+                     std::shared_ptr<PCHContainerOperations> PCHContainerOps)
     : Compilations(Compilations), SourcePaths(SourcePaths),
+      PCHContainerOps(PCHContainerOps),
       Files(new FileManager(FileSystemOptions())), DiagConsumer(nullptr) {
   appendArgumentsAdjuster(getClangStripOutputAdjuster());
   appendArgumentsAdjuster(getClangSyntaxOnlyAdjuster());
@@ -357,7 +361,8 @@ int ClangTool::run(ToolAction *Action) {
       // FIXME: We need a callback mechanism for the tool writer to output a
       // customized message for each file.
       DEBUG({ llvm::dbgs() << "Processing: " << File << ".\n"; });
-      ToolInvocation Invocation(std::move(CommandLine), Action, Files.get());
+      ToolInvocation Invocation(std::move(CommandLine), Action, Files.get(),
+                                PCHContainerOps);
       Invocation.setDiagnosticConsumer(DiagConsumer);
       for (const auto &MappedFile : MappedFileContents)
         Invocation.mapVirtualFile(MappedFile.first, MappedFile.second);
@@ -385,12 +390,14 @@ public:
   ASTBuilderAction(std::vector<std::unique_ptr<ASTUnit>> &ASTs) : ASTs(ASTs) {}
 
   bool runInvocation(CompilerInvocation *Invocation, FileManager *Files,
+                     std::shared_ptr<PCHContainerOperations> PCHContainerOps,
                      DiagnosticConsumer *DiagConsumer) override {
     // FIXME: This should use the provided FileManager.
     std::unique_ptr<ASTUnit> AST = ASTUnit::LoadFromCompilerInvocation(
-        Invocation, CompilerInstance::createDiagnostics(
-                        &Invocation->getDiagnosticOpts(), DiagConsumer,
-                        /*ShouldOwnClient=*/false));
+        Invocation, PCHContainerOps,
+        CompilerInstance::createDiagnostics(&Invocation->getDiagnosticOpts(),
+                                            DiagConsumer,
+                                            /*ShouldOwnClient=*/false));
     if (!AST)
       return false;
 
@@ -406,22 +413,24 @@ int ClangTool::buildASTs(std::vector<std
   return run(&Action);
 }
 
-std::unique_ptr<ASTUnit> buildASTFromCode(const Twine &Code,
-                                          const Twine &FileName) {
-  return buildASTFromCodeWithArgs(Code, std::vector<std::string>(), FileName);
+std::unique_ptr<ASTUnit>
+buildASTFromCode(const Twine &Code, const Twine &FileName,
+                 std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
+  return buildASTFromCodeWithArgs(Code, std::vector<std::string>(), FileName,
+                                  PCHContainerOps);
 }
 
-std::unique_ptr<ASTUnit>
-buildASTFromCodeWithArgs(const Twine &Code,
-                         const std::vector<std::string> &Args,
-                         const Twine &FileName) {
+std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
+    const Twine &Code, const std::vector<std::string> &Args,
+    const Twine &FileName,
+    std::shared_ptr<PCHContainerOperations> PCHContainerOps) {
   SmallString<16> FileNameStorage;
   StringRef FileNameRef = FileName.toNullTerminatedStringRef(FileNameStorage);
 
   std::vector<std::unique_ptr<ASTUnit>> ASTs;
   ASTBuilderAction Action(ASTs);
   ToolInvocation Invocation(getSyntaxOnlyToolArgs(Args, FileNameRef), &Action,
-                            nullptr);
+                            nullptr, PCHContainerOps);
 
   SmallString<1024> CodeStorage;
   Invocation.mapVirtualFile(FileNameRef,

Modified: cfe/trunk/tools/arcmt-test/arcmt-test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/arcmt-test/arcmt-test.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/tools/arcmt-test/arcmt-test.cpp (original)
+++ cfe/trunk/tools/arcmt-test/arcmt-test.cpp Sat Jun 20 13:53:08 2015
@@ -7,6 +7,7 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/ARCMigrate/ARCMT.h"
 #include "clang/Frontend/ASTUnit.h"
 #include "clang/Frontend/TextDiagnosticPrinter.h"
@@ -130,7 +131,8 @@ static bool checkForMigration(StringRef
   if (!CI.getLangOpts()->ObjC1)
     return false;
 
-  arcmt::checkForManualIssues(CI, CI.getFrontendOpts().Inputs[0], 
+  arcmt::checkForManualIssues(CI, CI.getFrontendOpts().Inputs[0],
+                              std::make_shared<RawPCHContainerOperations>(),
                               Diags->getClient());
   return Diags->getClient()->getNumErrors() > 0;
 }
@@ -169,7 +171,8 @@ static bool performTransformations(Strin
   if (!origCI.getLangOpts()->ObjC1)
     return false;
 
-  MigrationProcess migration(origCI, DiagClient);
+  MigrationProcess migration(
+      origCI, std::make_shared<RawPCHContainerOperations>(), DiagClient);
 
   std::vector<TransformFn>
     transforms = arcmt::getAllTransformations(origCI.getLangOpts()->getGC(),

Modified: cfe/trunk/tools/driver/cc1_main.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/driver/cc1_main.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/tools/driver/cc1_main.cpp (original)
+++ cfe/trunk/tools/driver/cc1_main.cpp Sat Jun 20 13:53:08 2015
@@ -14,6 +14,7 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/Option/Arg.h"
+#include "clang/Frontend/PCHContainerOperations.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Frontend/CompilerInstance.h"
@@ -64,7 +65,8 @@ void initializePollyPasses(llvm::PassReg
 #endif
 
 int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) {
-  std::unique_ptr<CompilerInstance> Clang(new CompilerInstance());
+  std::unique_ptr<CompilerInstance> Clang(
+      new CompilerInstance(std::make_shared<RawPCHContainerOperations>()));
   IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
 
   // Initialize targets first, so that --version shows registered targets.

Modified: cfe/trunk/tools/libclang/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndex.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndex.cpp (original)
+++ cfe/trunk/tools/libclang/CIndex.cpp Sat Jun 20 13:53:08 2015
@@ -2889,7 +2889,8 @@ enum CXErrorCode clang_createTranslation
   IntrusiveRefCntPtr<DiagnosticsEngine> Diags =
       CompilerInstance::createDiagnostics(new DiagnosticOptions());
   std::unique_ptr<ASTUnit> AU = ASTUnit::LoadFromASTFile(
-      ast_filename, Diags, FileSystemOpts, CXXIdx->getOnlyLocalDecls(), None,
+      ast_filename, CXXIdx->getPCHContainerOperations(), Diags, FileSystemOpts,
+      CXXIdx->getOnlyLocalDecls(), None,
       /*CaptureDiagnostics=*/true,
       /*AllowPCHWithCompilerErrors=*/true,
       /*UserFilesAreVolatile=*/true);
@@ -3027,7 +3028,8 @@ static void clang_parseTranslationUnit_I
   unsigned NumErrors = Diags->getClient()->getNumErrors();
   std::unique_ptr<ASTUnit> ErrUnit;
   std::unique_ptr<ASTUnit> Unit(ASTUnit::LoadFromCommandLine(
-      Args->data(), Args->data() + Args->size(), Diags,
+      Args->data(), Args->data() + Args->size(),
+      CXXIdx->getPCHContainerOperations(), Diags,
       CXXIdx->getClangResourcesPath(), CXXIdx->getOnlyLocalDecls(),
       /*CaptureDiagnostics=*/true, *RemappedFiles.get(),
       /*RemappedFilesKeepOriginalName=*/true, PrecompilePreamble, TUKind,
@@ -3268,7 +3270,8 @@ static void clang_reparseTranslationUnit
     RemappedFiles->push_back(std::make_pair(UF.Filename, MB.release()));
   }
 
-  if (!CXXUnit->Reparse(*RemappedFiles.get()))
+  if (!CXXUnit->Reparse(CXXIdx->getPCHContainerOperations(),
+                        *RemappedFiles.get()))
     RTUI->result = CXError_Success;
   else if (isASTReadError(CXXUnit))
     RTUI->result = CXError_ASTReadError;

Modified: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp Sat Jun 20 13:53:08 2015
@@ -715,14 +715,12 @@ static void clang_codeCompleteAt_Impl(vo
 
   // Perform completion.
   AST->CodeComplete(complete_filename, complete_line, complete_column,
-                    RemappedFiles,
-                    (options & CXCodeComplete_IncludeMacros),
+                    RemappedFiles, (options & CXCodeComplete_IncludeMacros),
                     (options & CXCodeComplete_IncludeCodePatterns),
-                    IncludeBriefComments,
-                    Capture,
-                    *Results->Diag, Results->LangOpts, *Results->SourceMgr,
-                    *Results->FileMgr, Results->Diagnostics,
-                    Results->TemporaryBuffers);
+                    IncludeBriefComments, Capture,
+                    CXXIdx->getPCHContainerOperations(), *Results->Diag,
+                    Results->LangOpts, *Results->SourceMgr, *Results->FileMgr,
+                    Results->Diagnostics, Results->TemporaryBuffers);
 
   Results->DiagnosticsWrappers.resize(Results->Diagnostics.size());
 

Modified: cfe/trunk/tools/libclang/CIndexer.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexer.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexer.h (original)
+++ cfe/trunk/tools/libclang/CIndexer.h Sat Jun 20 13:53:08 2015
@@ -16,6 +16,8 @@
 #define LLVM_CLANG_TOOLS_LIBCLANG_CINDEXER_H
 
 #include "clang-c/Index.h"
+#include "clang/Frontend/PCHContainerOperations.h"
+#include "clang/Lex/ModuleLoader.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Path.h"
 #include <vector>
@@ -38,11 +40,14 @@ class CIndexer {
   unsigned Options; // CXGlobalOptFlags.
 
   std::string ResourcesPath;
+  std::shared_ptr<PCHContainerOperations> PCHContainerOps;
 
 public:
- CIndexer() : OnlyLocalDecls(false), DisplayDiagnostics(false),
-              Options(CXGlobalOpt_None) { }
-  
+  CIndexer(std::shared_ptr<PCHContainerOperations> PCHContainerOps =
+               std::make_shared<RawPCHContainerOperations>())
+      : OnlyLocalDecls(false), DisplayDiagnostics(false),
+        Options(CXGlobalOpt_None), PCHContainerOps(PCHContainerOps) {}
+
   /// \brief Whether we only want to see "local" declarations (that did not
   /// come from a previous precompiled header). If false, we want to see all
   /// declarations.
@@ -54,6 +59,10 @@ public:
     DisplayDiagnostics = Display;
   }
 
+  std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
+    return PCHContainerOps;
+  }
+
   unsigned getCXGlobalOptFlags() const { return Options; }
   void setCXGlobalOptFlags(unsigned options) { Options = options; }
 

Modified: cfe/trunk/tools/libclang/Indexing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Indexing.cpp?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/Indexing.cpp (original)
+++ cfe/trunk/tools/libclang/Indexing.cpp Sat Jun 20 13:53:08 2015
@@ -590,8 +590,7 @@ static void clang_indexSourceFile_Impl(v
   if (index_options & CXIndexOpt_SuppressWarnings)
     CInvok->getDiagnosticOpts().IgnoreWarnings = true;
 
-  ASTUnit *Unit = ASTUnit::create(CInvok.get(), Diags,
-                                  CaptureDiagnostics,
+  ASTUnit *Unit = ASTUnit::create(CInvok.get(), Diags, CaptureDiagnostics,
                                   /*UserFilesAreVolatile=*/true);
   if (!Unit) {
     ITUI->result = CXError_InvalidArguments;
@@ -644,17 +643,13 @@ static void clang_indexSourceFile_Impl(v
     PPOpts.DetailedRecord = false;
 
   DiagnosticErrorTrap DiagTrap(*Diags);
-  bool Success = ASTUnit::LoadFromCompilerInvocationAction(CInvok.get(), Diags,
-                                                       IndexAction.get(),
-                                                       Unit,
-                                                       Persistent,
-                                                CXXIdx->getClangResourcesPath(),
-                                                       OnlyLocalDecls,
-                                                       CaptureDiagnostics,
-                                                       PrecompilePreamble,
-                                                    CacheCodeCompletionResults,
-                                 /*IncludeBriefCommentsInCodeCompletion=*/false,
-                                                 /*UserFilesAreVolatile=*/true);
+  bool Success = ASTUnit::LoadFromCompilerInvocationAction(
+      CInvok.get(), CXXIdx->getPCHContainerOperations(), Diags,
+      IndexAction.get(), Unit, Persistent, CXXIdx->getClangResourcesPath(),
+      OnlyLocalDecls, CaptureDiagnostics, PrecompilePreamble,
+      CacheCodeCompletionResults,
+      /*IncludeBriefCommentsInCodeCompletion=*/false,
+      /*UserFilesAreVolatile=*/true);
   if (DiagTrap.hasErrorOccurred() && CXXIdx->getDisplayDiagnostics())
     printDiagsToStderr(Unit);
 

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h?rev=240225&r1=240224&r2=240225&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTest.h Sat Jun 20 13:53:08 2015
@@ -80,6 +80,7 @@ testing::AssertionResult matchesConditio
   Args.push_back("-frtti");
   Args.push_back("-fexceptions");
   if (!runToolOnCodeWithArgs(Factory->create(), Code, Args, Filename,
+                             std::make_shared<RawPCHContainerOperations>(),
                              VirtualMappedFiles)) {
     return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
   }





More information about the cfe-commits mailing list