namespace clang {
class ASTContext;
class DiagnosticConsumer;
+ class PCHContainerOperations;
namespace arcmt {
class MigrationPass;
/// 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.
/// 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.
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 {
class FileManager;
class HeaderSearch;
class Preprocessor;
+class PCHContainerOperations;
class SourceManager;
class TargetInfo;
class ASTFrontendAction;
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;
unsigned MaxLines);
std::unique_ptr<llvm::MemoryBuffer> getMainBufferWithPrecompiledPreamble(
+ std::shared_ptr<PCHContainerOperations> PCHContainerOps,
const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild = true,
unsigned MaxLines = 0);
void RealizeTopLevelDeclsFromPreamble();
///
/// \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,
///
/// \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
/// \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.
///
/// 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,
/// \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);
///
/// \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.
///
// 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,
/// 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.
/// 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.
///
#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"
/// \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;
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
void setModuleDepCollector(
std::shared_ptr<ModuleDependencyCollector> Collector);
+ std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
+ return ThePCHContainerOperations;
+ }
+
/// }
/// @name Code Completion
/// {
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);
/// 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 {
/// 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 {
--- /dev/null
+//===--- 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
class HeaderSearchOptions;
class IdentifierTable;
class LangOptions;
+class PCHContainerOperations;
class Preprocessor;
class PreprocessorOptions;
class PreprocessorOutputOptions;
/// 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.
SourceManager &SourceMgr;
FileManager &FileMgr;
+ const PCHContainerOperations &PCHContainerOps;
DiagnosticsEngine &Diags;
/// \brief The semantic analysis object that will be processing the
/// \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 "/".
///
/// \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;
/// \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,
#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"
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
class FileEntry;
class FileManager;
class IdentifierIterator;
+class PCHContainerOperations;
namespace serialization {
class ModuleFile;
/// \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);
};
}
class GlobalModuleIndex;
class ModuleMap;
+class PCHContainerOperations;
namespace serialization {
/// \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;
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
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.
#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"
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.
/// \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.
/// \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.
/// \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
/// \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();
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;
/// 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();
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>).
}
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();
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();
// 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;
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);
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;
// 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;
// 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,
}
}
-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> > &
/// \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(
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());
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;
bool CheckAction::BeginInvocation(CompilerInstance &CI) {
if (arcmt::checkForManualIssues(CI.getInvocation(), getCurrentInput(),
+ CI.getPCHContainerOperations(),
CI.getDiagnostics().getClient()))
return false; // errors, stop the action.
bool ModifyAction::BeginInvocation(CompilerInstance &CI) {
return !arcmt::applyTransformations(CI.getInvocation(), getCurrentInput(),
+ CI.getPCHContainerOperations(),
CI.getDiagnostics().getClient());
}
: 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.
//===----------------------------------------------------------------------===//
#include "clang/AST/ASTConsumer.h"
+#include "llvm/Bitcode/BitstreamReader.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclGroup.h"
using namespace clang;
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;
}
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) {
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,
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;
}
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
///
/// \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>
/// Otherwise, returns a NULL pointer.
std::unique_ptr<llvm::MemoryBuffer>
ASTUnit::getMainBufferWithPrecompiledPreamble(
+ std::shared_ptr<PCHContainerOperations> PCHContainerOps,
const CompilerInvocation &PreambleInvocationIn, bool AllowRebuild,
unsigned MaxLines) {
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>
}
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;
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>
return AST;
}
-bool ASTUnit::LoadFromCompilerInvocation(bool PrecompilePreamble) {
+bool ASTUnit::LoadFromCompilerInvocation(
+ std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+ bool PrecompilePreamble) {
if (!Invocation)
return true;
std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
if (PrecompilePreamble) {
PreambleRebuildCounter = 2;
- OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(*Invocation);
+ OverrideMainBuffer =
+ getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation);
}
SimpleTimer ParsingTimer(WantTiming);
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.
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,
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) {
return AST.release();
}
-bool ASTUnit::Reparse(ArrayRef<RemappedFile> RemappedFiles) {
+bool ASTUnit::Reparse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
+ ArrayRef<RemappedFile> RemappedFiles) {
if (!Invocation)
return true;
// 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());
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.
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;
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>
if (!llvm::sys::fs::getUniqueID(MainPath, MainID)) {
if (CompleteFileID == MainID && Line > 1)
OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
- *CCInvocation, false, Line - 1);
+ PCHContainerOps, *CCInvocation, false, Line - 1);
}
}
}
LogDiagnosticPrinter.cpp
ModuleDependencyCollector.cpp
MultiplexConsumer.cpp
+ PCHContainerOperations.cpp
PrintPreprocessedOutput.cpp
SerializedDiagnosticPrinter.cpp
SerializedDiagnosticReader.cpp
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]));
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(
&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));
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());
}
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?");
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(),
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.
// 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(
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());
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)
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();
}
if (RecreateIndex) {
GlobalModuleIndex::writeIndex(
- getFileManager(),
- getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
+ getFileManager(), *getPCHContainerOperations(),
+ getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
ModuleManager->resetForReload();
ModuleManager->loadGlobalIndex();
GlobalIndex = ModuleManager->getGlobalIndex();
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;
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;
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;
#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"
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;
// 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);
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> &
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
// 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,
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
Out << "Information for module file '" << getCurrentFile() << "':\n";
DumpModuleInfoListener Listener(Out);
- ASTReader::readASTFileControlBlock(getCurrentFile(),
- getCompilerInstance().getFileManager(),
- Listener);
+ ASTReader::readASTFileControlBlock(
+ getCurrentFile(), getCompilerInstance().getFileManager(),
+ *getCompilerInstance().getPCHContainerOperations(), Listener);
}
//===----------------------------------------------------------------------===//
/// \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;
/// 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);
// 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);
--- /dev/null
+//===--- 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());
+}
#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"
ModuleFile &F = *M;
BitstreamCursor &Stream = F.Stream;
+ PCHContainerOps.ExtractPCH(F.Buffer->getMemBufferRef(), F.StreamFile);
Stream.init(&F.StreamFile);
F.SizeInBits = F.Buffer->getBufferSize() * 8;
/// \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) {
// 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.
};
}
-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.
}
}
-
-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
}
}
-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),
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() {
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() {
//===----------------------------------------------------------------------===//
#include "ASTReaderInternals.h"
+#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Basic/FileManager.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Serialization/ASTBitCodes.h"
/// \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;
}
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.
///
// 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.
}
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);
}
// 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;
// modules for the ASTReader.
//
//===----------------------------------------------------------------------===//
+#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/Lex/HeaderSearch.h"
#include "clang/Lex/ModuleMap.h"
#include "clang/Serialization/GlobalModuleIndex.h"
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) {
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)
// 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()),
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; }
}
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>
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,
}
-ToolInvocation::ToolInvocation(std::vector<std::string> CommandLine,
- ToolAction *Action, FileManager *Files)
- : CommandLine(std::move(CommandLine)),
- Action(Action),
- OwnsAction(false),
- Files(Files),
- DiagConsumer(nullptr) {}
+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)
+ToolInvocation::ToolInvocation(
+ std::vector<std::string> CommandLine, FrontendAction *FAction,
+ FileManager *Files, std::shared_ptr<PCHContainerOperations> PCHContainerOps)
: 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)
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";
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);
}
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());
// 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);
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;
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,
//
//===----------------------------------------------------------------------===//
+#include "clang/Frontend/PCHContainerOperations.h"
#include "clang/ARCMigrate/ARCMT.h"
#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
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;
}
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(),
//===----------------------------------------------------------------------===//
#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"
#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.
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);
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,
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;
// 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());
#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>
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.
DisplayDiagnostics = Display;
}
+ std::shared_ptr<PCHContainerOperations> getPCHContainerOperations() const {
+ return PCHContainerOps;
+ }
+
unsigned getCXGlobalOptFlags() const { return Options; }
void setCXGlobalOptFlags(unsigned options) { Options = options; }
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;
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);
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 << "\"";
}