From ca37e4fc6c52875fd2dbbf00dac4640288f48b72 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Thu, 18 Jan 2018 15:16:53 +0000 Subject: [PATCH] [Frontend] Allow to use PrecompiledPreamble without calling CanReuse Summary: The new method 'OverridePreamble' allows to override the preamble of any source file without checking if preamble bounds or dependencies were changed. This is used for completion in clangd. Reviewers: bkramer, sammccall Reviewed By: sammccall Subscribers: cfe-commits Differential Revision: https://reviews.llvm.org/D41990 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@322853 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Frontend/PrecompiledPreamble.h | 22 ++++++++-- lib/Frontend/PrecompiledPreamble.cpp | 42 ++++++++++++++------ 2 files changed, 47 insertions(+), 17 deletions(-) diff --git a/include/clang/Frontend/PrecompiledPreamble.h b/include/clang/Frontend/PrecompiledPreamble.h index 130fe60704..f1898f573f 100644 --- a/include/clang/Frontend/PrecompiledPreamble.h +++ b/include/clang/Frontend/PrecompiledPreamble.h @@ -104,14 +104,22 @@ public: /// Changes options inside \p CI to use PCH from this preamble. Also remaps /// main file to \p MainFileBuffer and updates \p VFS to ensure the preamble /// is accessible. - /// For in-memory preambles, PrecompiledPreamble instance continues to own - /// the MemoryBuffer with the Preamble after this method returns. The caller - /// is reponsible for making sure the PrecompiledPreamble instance outlives - /// the compiler run and the AST that will be using the PCH. + /// Requires that CanReuse() is true. + /// For in-memory preambles, PrecompiledPreamble instance continues to own the + /// MemoryBuffer with the Preamble after this method returns. The caller is + /// reponsible for making sure the PrecompiledPreamble instance outlives the + /// compiler run and the AST that will be using the PCH. void AddImplicitPreamble(CompilerInvocation &CI, IntrusiveRefCntPtr &VFS, llvm::MemoryBuffer *MainFileBuffer) const; + /// Configure \p CI to use this preamble. + /// Like AddImplicitPreamble, but doesn't assume CanReuse() is true. + /// If this preamble does not match the file, it may parse differently. + void OverridePreamble(CompilerInvocation &CI, + IntrusiveRefCntPtr &VFS, + llvm::MemoryBuffer *MainFileBuffer) const; + private: PrecompiledPreamble(PCHStorage Storage, std::vector PreambleBytes, bool PreambleEndsAtStartOfLine, @@ -222,6 +230,12 @@ private: } }; + /// Helper function to set up PCH for the preamble into \p CI and \p VFS to + /// with the specified \p Bounds. + void configurePreamble(PreambleBounds Bounds, CompilerInvocation &CI, + IntrusiveRefCntPtr &VFS, + llvm::MemoryBuffer *MainFileBuffer) const; + /// Sets up the PreprocessorOptions and changes VFS, so that PCH stored in \p /// Storage is accessible to clang. This method is an implementation detail of /// AddImplicitPreamble. diff --git a/lib/Frontend/PrecompiledPreamble.cpp b/lib/Frontend/PrecompiledPreamble.cpp index 7e1323fd83..d761f6ee45 100644 --- a/lib/Frontend/PrecompiledPreamble.cpp +++ b/lib/Frontend/PrecompiledPreamble.cpp @@ -485,20 +485,15 @@ bool PrecompiledPreamble::CanReuse(const CompilerInvocation &Invocation, void PrecompiledPreamble::AddImplicitPreamble( CompilerInvocation &CI, IntrusiveRefCntPtr &VFS, llvm::MemoryBuffer *MainFileBuffer) const { - assert(VFS && "VFS must not be null"); - - auto &PreprocessorOpts = CI.getPreprocessorOpts(); - - // Remap main file to point to MainFileBuffer. - auto MainFilePath = CI.getFrontendOpts().Inputs[0].getFile(); - PreprocessorOpts.addRemappedFile(MainFilePath, MainFileBuffer); - - // Configure ImpicitPCHInclude. - PreprocessorOpts.PrecompiledPreambleBytes.first = PreambleBytes.size(); - PreprocessorOpts.PrecompiledPreambleBytes.second = PreambleEndsAtStartOfLine; - PreprocessorOpts.DisablePCHValidation = true; + PreambleBounds Bounds(PreambleBytes.size(), PreambleEndsAtStartOfLine); + configurePreamble(Bounds, CI, VFS, MainFileBuffer); +} - setupPreambleStorage(Storage, PreprocessorOpts, VFS); +void PrecompiledPreamble::OverridePreamble( + CompilerInvocation &CI, IntrusiveRefCntPtr &VFS, + llvm::MemoryBuffer *MainFileBuffer) const { + auto Bounds = ComputePreambleBounds(*CI.getLangOpts(), MainFileBuffer, 0); + configurePreamble(Bounds, CI, VFS, MainFileBuffer); } PrecompiledPreamble::PrecompiledPreamble( @@ -681,6 +676,27 @@ PrecompiledPreamble::PreambleFileHash::createForMemoryBuffer( return Result; } +void PrecompiledPreamble::configurePreamble( + PreambleBounds Bounds, CompilerInvocation &CI, + IntrusiveRefCntPtr &VFS, + llvm::MemoryBuffer *MainFileBuffer) const { + assert(VFS); + + auto &PreprocessorOpts = CI.getPreprocessorOpts(); + + // Remap main file to point to MainFileBuffer. + auto MainFilePath = CI.getFrontendOpts().Inputs[0].getFile(); + PreprocessorOpts.addRemappedFile(MainFilePath, MainFileBuffer); + + // Configure ImpicitPCHInclude. + PreprocessorOpts.PrecompiledPreambleBytes.first = Bounds.Size; + PreprocessorOpts.PrecompiledPreambleBytes.second = + Bounds.PreambleEndsAtStartOfLine; + PreprocessorOpts.DisablePCHValidation = true; + + setupPreambleStorage(Storage, PreprocessorOpts, VFS); +} + void PrecompiledPreamble::setupPreambleStorage( const PCHStorage &Storage, PreprocessorOptions &PreprocessorOpts, IntrusiveRefCntPtr &VFS) { -- 2.40.0