ilya-biryukov created this revision.
ilya-biryukov added reviewers: bkramer, sammccall.

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.


Repository:
  rC Clang

https://reviews.llvm.org/D41990

Files:
  include/clang/Frontend/PrecompiledPreamble.h
  lib/Frontend/PrecompiledPreamble.cpp

Index: lib/Frontend/PrecompiledPreamble.cpp
===================================================================
--- lib/Frontend/PrecompiledPreamble.cpp
+++ lib/Frontend/PrecompiledPreamble.cpp
@@ -485,20 +485,15 @@
 void PrecompiledPreamble::AddImplicitPreamble(
     CompilerInvocation &CI, IntrusiveRefCntPtr<vfs::FileSystem> &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::FileSystem> &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::FileSystem> &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::FileSystem> &VFS) {
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::FileSystem> &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::FileSystem> &VFS,
+                        llvm::MemoryBuffer *MainFileBuffer) const;
+
 private:
   PrecompiledPreamble(PCHStorage Storage, std::vector<char> 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::FileSystem> &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.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to