Index: include/clang/Frontend/PrecompiledPreamble.h =================================================================== --- include/clang/Frontend/PrecompiledPreamble.h +++ include/clang/Frontend/PrecompiledPreamble.h @@ -104,14 +104,26 @@ /// 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. + /// Callers of this function must ensure that that CanReuse() returns true for + /// the specified file before calling this function. + /// 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 pretend \p MainFileBuffer has a preamble, identical to + /// the PCH stored by this instance. This function is similar to + /// AddImplicitPreamble, but does require checking that CanReuse() returns + /// true prior to calling this function. Using this function allows to avoid + /// the expensive CanReuse() call and rebuild of the preamble, but results of + /// parsing the file may be incorrect. + void OverridePreamble(CompilerInvocation &CI, + IntrusiveRefCntPtr &VFS, + llvm::MemoryBuffer *MainFileBuffer) const; + private: PrecompiledPreamble(PCHStorage Storage, std::vector PreambleBytes, bool PreambleEndsAtStartOfLine, @@ -222,6 +234,12 @@ } }; + /// 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. Index: lib/Frontend/PrecompiledPreamble.cpp =================================================================== --- lib/Frontend/PrecompiledPreamble.cpp +++ lib/Frontend/PrecompiledPreamble.cpp @@ -485,20 +485,15 @@ 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 @@ return Result; } +void PrecompiledPreamble::configurePreamble( + PreambleBounds Bounds, 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 = Bounds.Size; + PreprocessorOpts.PrecompiledPreambleBytes.second = + Bounds.PreambleEndsAtStartOfLine; + PreprocessorOpts.DisablePCHValidation = true; + + setupPreambleStorage(Storage, PreprocessorOpts, VFS); +} + void PrecompiledPreamble::setupPreambleStorage( const PCHStorage &Storage, PreprocessorOptions &PreprocessorOpts, IntrusiveRefCntPtr &VFS) {