mirror of
https://github.com/intel/llvm.git
synced 2026-01-27 06:06:34 +08:00
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 llvm-svn: 240225
This commit is contained in:
@@ -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(CompilerInvocation &origCI,
|
||||
/// 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> getAllTransformations(LangOptions::GCMode OrigGCMode,
|
||||
|
||||
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 {
|
||||
|
||||
@@ -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.
|
||||
///
|
||||
|
||||
@@ -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 ModuleLoader {
|
||||
/// \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 ModuleLoader {
|
||||
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);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
76
clang/include/clang/Frontend/PCHContainerOperations.h
Normal file
76
clang/include/clang/Frontend/PCHContainerOperations.h
Normal file
@@ -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
|
||||
@@ -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(HeaderSearch &HS,
|
||||
|
||||
/// 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.
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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<FrontendActionFactory> newFrontendActionFactory(
|
||||
/// \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::string, std::string>> FileContentMappings;
|
||||
/// \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>).
|
||||
|
||||
@@ -166,7 +166,8 @@ static bool HasARCRuntime(CompilerInvocation &origCI) {
|
||||
}
|
||||
|
||||
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(CompilerInvocation &origCI) {
|
||||
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 CapturedDiagList &arcDiags,
|
||||
// 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(CompilerInvocation &origCI,
|
||||
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(CompilerInvocation &origCI,
|
||||
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(CompilerInvocation &origCI,
|
||||
// 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(CompilerInvocation &origCI,
|
||||
|
||||
// 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(CompilerInvocation &origCI,
|
||||
}
|
||||
}
|
||||
|
||||
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 CompilerInvocation &CI,
|
||||
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(TransformFn trans,
|
||||
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;
|
||||
|
||||
@@ -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 *WrappedAction)
|
||||
|
||||
bool ModifyAction::BeginInvocation(CompilerInstance &CI) {
|
||||
return !arcmt::applyTransformations(CI.getInvocation(), getCurrentInput(),
|
||||
CI.getPCHContainerOperations(),
|
||||
CI.getDiagnostics().getClient());
|
||||
}
|
||||
|
||||
@@ -36,12 +38,10 @@ ModifyAction::ModifyAction(FrontendAction *WrappedAction)
|
||||
: 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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -648,7 +648,9 @@ void ASTUnit::ConfigureDiags(IntrusiveRefCntPtr<DiagnosticsEngine> Diags,
|
||||
}
|
||||
|
||||
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::LoadFromASTFile(
|
||||
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 : public PCHGenerator {
|
||||
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(SmallVectorImpl<StoredDiagnostic> &
|
||||
///
|
||||
/// \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 LangOptions &LangOpts,
|
||||
/// 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::getMainBufferWithPrecompiledPreamble(
|
||||
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(CompilerInvocation *CI,
|
||||
}
|
||||
|
||||
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::LoadFromCompilerInvocationAction(
|
||||
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::LoadFromCompilerInvocationAction(
|
||||
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(bool PrecompilePreamble) {
|
||||
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(bool PrecompilePreamble) {
|
||||
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::LoadFromCompilerInvocation(
|
||||
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<RemappedFile> RemappedFiles) {
|
||||
// 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<RemappedFile> RemappedFiles) {
|
||||
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::ProcessCodeCompleteResults(Sema &S,
|
||||
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 File, unsigned Line, unsigned Column,
|
||||
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 File, unsigned Line, unsigned Column,
|
||||
if (!llvm::sys::fs::getUniqueID(MainPath, MainID)) {
|
||||
if (CompleteFileID == MainID && Line > 1)
|
||||
OverrideMainBuffer = getMainBufferWithPrecompiledPreamble(
|
||||
*CCInvocation, false, Line - 1);
|
||||
PCHContainerOps, *CCInvocation, false, Line - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ add_clang_library(clangFrontend
|
||||
LogDiagnosticPrinter.cpp
|
||||
ModuleDependencyCollector.cpp
|
||||
MultiplexConsumer.cpp
|
||||
PCHContainerOperations.cpp
|
||||
PrintPreprocessedOutput.cpp
|
||||
SerializedDiagnosticPrinter.cpp
|
||||
SerializedDiagnosticReader.cpp
|
||||
|
||||
@@ -80,8 +80,9 @@ createASTReader(CompilerInstance &CI, StringRef pchFile,
|
||||
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> clang::createChainedIncludesSource(
|
||||
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> clang::createChainedIncludesSource(
|
||||
&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> clang::createChainedIncludesSource(
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
|
||||
@@ -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::createPreprocessor(TranslationUnitKind TUKind) {
|
||||
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::createPCHExternalASTSource(
|
||||
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(CompilerInstance &ImportingInstance,
|
||||
|
||||
// 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::createModuleManager() {
|
||||
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(StringRef FileName) {
|
||||
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::loadGlobalModuleIndex(
|
||||
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::loadGlobalModuleIndex(
|
||||
}
|
||||
if (RecreateIndex) {
|
||||
GlobalModuleIndex::writeIndex(
|
||||
getFileManager(),
|
||||
getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
|
||||
getFileManager(), *getPCHContainerOperations(),
|
||||
getPreprocessor().getHeaderSearchInfo().getModuleCachePath());
|
||||
ModuleManager->resetForReload();
|
||||
ModuleManager->loadGlobalIndex();
|
||||
GlobalIndex = ModuleManager->getGlobalIndex();
|
||||
|
||||
@@ -191,7 +191,8 @@ bool FrontendAction::BeginSourceFile(CompilerInstance &CI,
|
||||
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(CompilerInstance &CI,
|
||||
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;
|
||||
|
||||
@@ -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::ComputeASTConsumerArguments(
|
||||
// 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(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;
|
||||
|
||||
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::BeginSourceFileAction(CompilerInstance &CI,
|
||||
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::ComputeASTConsumerArguments(
|
||||
// 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);
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@@ -97,10 +97,11 @@ static void AddImplicitIncludePTH(MacroBuilder &Builder, Preprocessor &PP,
|
||||
/// \brief Add an implicit \#include using the original file used to generate
|
||||
/// a PCH file.
|
||||
static void AddImplicitIncludePCH(MacroBuilder &Builder, Preprocessor &PP,
|
||||
const PCHContainerOperations &PCHContainerOps,
|
||||
StringRef ImplicitIncludePCH) {
|
||||
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(const TargetInfo &TI,
|
||||
/// 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(Preprocessor &PP,
|
||||
|
||||
// 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);
|
||||
|
||||
|
||||
70
clang/lib/Frontend/PCHContainerOperations.cpp
Normal file
70
clang/lib/Frontend/PCHContainerOperations.cpp
Normal file
@@ -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());
|
||||
}
|
||||
@@ -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 FileName,
|
||||
|
||||
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 readASTFileSignature(llvm::BitstreamReader &StreamFile){
|
||||
/// \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::getOriginalSourceFile(const std::string &ASTFileName,
|
||||
|
||||
// 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(StringRef Filename,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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::pushExternalDeclIntoScope(NamedDecl *D, DeclarationName Name) {
|
||||
}
|
||||
}
|
||||
|
||||
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),
|
||||
|
||||
@@ -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(ASTContext &Ctx) {
|
||||
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() {
|
||||
|
||||
@@ -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::loadModuleFile(const FileEntry *File) {
|
||||
|
||||
// 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::writeIndex(llvm::BitstreamWriter &Stream) {
|
||||
}
|
||||
|
||||
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(FileManager &FileMgr, StringRef Path) {
|
||||
}
|
||||
|
||||
// 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;
|
||||
|
||||
@@ -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 FileName, ModuleKind Type,
|
||||
|
||||
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(ModuleFile *MF) {
|
||||
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)
|
||||
|
||||
@@ -76,7 +76,7 @@ void ModelInjector::onBodySynthesis(const NamedDecl *D) {
|
||||
|
||||
// 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()),
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -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<std::string> &ExtraArgs,
|
||||
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)
|
||||
: 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)
|
||||
@@ -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::runInvocation(CompilerInvocation *Invocation,
|
||||
}
|
||||
|
||||
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::unique_ptr<ASTUnit>> &ASTs) {
|
||||
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,
|
||||
|
||||
@@ -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 resourcesPath,
|
||||
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(StringRef resourcesPath,
|
||||
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(),
|
||||
|
||||
@@ -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::PassRegistry &Registry);
|
||||
#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.
|
||||
|
||||
@@ -2889,7 +2889,8 @@ enum CXErrorCode clang_createTranslationUnit2(CXIndex CIdx,
|
||||
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_Impl(void *UserData) {
|
||||
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_Impl(void *UserData) {
|
||||
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;
|
||||
|
||||
@@ -715,14 +715,12 @@ static void clang_codeCompleteAt_Impl(void *UserData) {
|
||||
|
||||
// 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());
|
||||
|
||||
|
||||
@@ -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; }
|
||||
|
||||
|
||||
@@ -590,8 +590,7 @@ static void clang_indexSourceFile_Impl(void *UserData) {
|
||||
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(void *UserData) {
|
||||
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);
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ testing::AssertionResult matchesConditionally(
|
||||
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 << "\"";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user