diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/ARCMigrate/ARCMT.cpp | 82 | ||||
-rw-r--r-- | clang/lib/ARCMigrate/ARCMTActions.cpp | 12 | ||||
-rw-r--r-- | clang/lib/AST/ASTConsumer.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Frontend/ASTMerge.cpp | 6 | ||||
-rw-r--r-- | clang/lib/Frontend/ASTUnit.cpp | 109 | ||||
-rw-r--r-- | clang/lib/Frontend/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/lib/Frontend/ChainedIncludesSource.cpp | 22 | ||||
-rw-r--r-- | clang/lib/Frontend/CompilerInstance.cpp | 56 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendAction.cpp | 16 | ||||
-rw-r--r-- | clang/lib/Frontend/FrontendActions.cpp | 59 | ||||
-rw-r--r-- | clang/lib/Frontend/InitPreprocessor.cpp | 15 | ||||
-rw-r--r-- | clang/lib/Frontend/PCHContainerOperations.cpp | 70 | ||||
-rw-r--r-- | clang/lib/Serialization/ASTReader.cpp | 55 | ||||
-rw-r--r-- | clang/lib/Serialization/GeneratePCH.cpp | 33 | ||||
-rw-r--r-- | clang/lib/Serialization/GlobalModuleIndex.cpp | 17 | ||||
-rw-r--r-- | clang/lib/Serialization/ModuleManager.cpp | 14 | ||||
-rw-r--r-- | clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp | 2 | ||||
-rw-r--r-- | clang/lib/Tooling/Refactoring.cpp | 7 | ||||
-rw-r--r-- | clang/lib/Tooling/Tooling.cpp | 95 |
19 files changed, 407 insertions, 265 deletions
diff --git a/clang/lib/ARCMigrate/ARCMT.cpp b/clang/lib/ARCMigrate/ARCMT.cpp index f266eaf8396..f33ad21cf02 100644 --- a/clang/lib/ARCMigrate/ARCMT.cpp +++ b/clang/lib/ARCMigrate/ARCMT.cpp @@ -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; diff --git a/clang/lib/ARCMigrate/ARCMTActions.cpp b/clang/lib/ARCMigrate/ARCMTActions.cpp index 0ed36ddf68c..39a922f426c 100644 --- a/clang/lib/ARCMigrate/ARCMTActions.cpp +++ b/clang/lib/ARCMigrate/ARCMTActions.cpp @@ -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. diff --git a/clang/lib/AST/ASTConsumer.cpp b/clang/lib/AST/ASTConsumer.cpp index 55033b238c6..cff82e9b100 100644 --- a/clang/lib/AST/ASTConsumer.cpp +++ b/clang/lib/AST/ASTConsumer.cpp @@ -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; diff --git a/clang/lib/Frontend/ASTMerge.cpp b/clang/lib/Frontend/ASTMerge.cpp index b84df94ef80..f6f1551b423 100644 --- a/clang/lib/Frontend/ASTMerge.cpp +++ b/clang/lib/Frontend/ASTMerge.cpp @@ -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; diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index 4fd330d44b7..01c56bdc4df 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -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); } } } diff --git a/clang/lib/Frontend/CMakeLists.txt b/clang/lib/Frontend/CMakeLists.txt index 7c5fca54d1e..9a3e459640a 100644 --- a/clang/lib/Frontend/CMakeLists.txt +++ b/clang/lib/Frontend/CMakeLists.txt @@ -31,6 +31,7 @@ add_clang_library(clangFrontend LogDiagnosticPrinter.cpp ModuleDependencyCollector.cpp MultiplexConsumer.cpp + PCHContainerOperations.cpp PrintPreprocessedOutput.cpp SerializedDiagnosticPrinter.cpp SerializedDiagnosticReader.cpp diff --git a/clang/lib/Frontend/ChainedIncludesSource.cpp b/clang/lib/Frontend/ChainedIncludesSource.cpp index f3677f8000c..be30d43a843 100644 --- a/clang/lib/Frontend/ChainedIncludesSource.cpp +++ b/clang/lib/Frontend/ChainedIncludesSource.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()); } diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index aef3905b328..6b0fed67618 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -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(); diff --git a/clang/lib/Frontend/FrontendAction.cpp b/clang/lib/Frontend/FrontendAction.cpp index 9bba75541ff..db9dd3b0988 100644 --- a/clang/lib/Frontend/FrontendAction.cpp +++ b/clang/lib/Frontend/FrontendAction.cpp @@ -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; diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index 46cdeebfdbe..6f202a15483 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -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); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index dfc46f47cce..24171468f1b 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -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); diff --git a/clang/lib/Frontend/PCHContainerOperations.cpp b/clang/lib/Frontend/PCHContainerOperations.cpp new file mode 100644 index 00000000000..fd3278b3b14 --- /dev/null +++ b/clang/lib/Frontend/PCHContainerOperations.cpp @@ -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()); +} diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp index 609c25da3eb..d75b5eb73d5 100644 --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -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), diff --git a/clang/lib/Serialization/GeneratePCH.cpp b/clang/lib/Serialization/GeneratePCH.cpp index b5031fdf92a..c50b3f9bb9e 100644 --- a/clang/lib/Serialization/GeneratePCH.cpp +++ b/clang/lib/Serialization/GeneratePCH.cpp @@ -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() { diff --git a/clang/lib/Serialization/GlobalModuleIndex.cpp b/clang/lib/Serialization/GlobalModuleIndex.cpp index 1b52b441134..2c7da3e82a4 100644 --- a/clang/lib/Serialization/GlobalModuleIndex.cpp +++ b/clang/lib/Serialization/GlobalModuleIndex.cpp @@ -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; diff --git a/clang/lib/Serialization/ModuleManager.cpp b/clang/lib/Serialization/ModuleManager.cpp index 30d9c89a124..03d8ed0e246 100644 --- a/clang/lib/Serialization/ModuleManager.cpp +++ b/clang/lib/Serialization/ModuleManager.cpp @@ -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) diff --git a/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp b/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp index 699549f8176..ee2c3f513cd 100644 --- a/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp +++ b/clang/lib/StaticAnalyzer/Frontend/ModelInjector.cpp @@ -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()), diff --git a/clang/lib/Tooling/Refactoring.cpp b/clang/lib/Tooling/Refactoring.cpp index c8173060d8c..d32452f6f29 100644 --- a/clang/lib/Tooling/Refactoring.cpp +++ b/clang/lib/Tooling/Refactoring.cpp @@ -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; } diff --git a/clang/lib/Tooling/Tooling.cpp b/clang/lib/Tooling/Tooling.cpp index e100003cee8..f9cb7c64134 100644 --- a/clang/lib/Tooling/Tooling.cpp +++ b/clang/lib/Tooling/Tooling.cpp @@ -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, |