nik updated this revision to Diff 99740.

https://reviews.llvm.org/D33045

Files:
  include/clang/Frontend/ASTUnit.h
  lib/Frontend/ASTUnit.cpp
  tools/libclang/CIndexCodeCompletion.cpp

Index: tools/libclang/CIndexCodeCompletion.cpp
===================================================================
--- tools/libclang/CIndexCodeCompletion.cpp
+++ tools/libclang/CIndexCodeCompletion.cpp
@@ -680,6 +680,7 @@
   }
 
   // Parse the resulting source file to find code-completion results.
+  AST->recreateFileManager();
   AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults(
       &AST->getFileManager());
   Results->Results = nullptr;
Index: lib/Frontend/ASTUnit.cpp
===================================================================
--- lib/Frontend/ASTUnit.cpp
+++ lib/Frontend/ASTUnit.cpp
@@ -241,6 +241,10 @@
   this->PP = std::move(PP);
 }
 
+void ASTUnit::recreateFileManager() {
+    FileMgr = new FileManager(FileMgr->getFileSystemOpts());
+}
+
 /// \brief Determine the set of code-completion contexts in which this 
 /// declaration should be shown.
 static unsigned getDeclShowContexts(const NamedDecl *ND,
@@ -1311,6 +1315,10 @@
 /// this routine will determine if it is still valid and, if so, avoid 
 /// rebuilding the precompiled preamble.
 ///
+/// The caller is required to recreate the FileMgr before calling this routine
+/// to ensure a clean stat cache and on the other hand that the stats done here
+/// can be reused for e.g. Reparse().
+///
 /// \param AllowRebuild When true (the default), this routine is
 /// allowed to rebuild the precompiled preamble if it is found to be
 /// out-of-date.
@@ -1368,59 +1376,58 @@
         if (AnyFileChanged)
           break;
 
-        vfs::Status Status;
-        if (FileMgr->getNoncachedStatValue(R.second, Status)) {
+        const FileEntry *fileEntry = FileMgr->getFile(R.second);
+        if (!fileEntry) {
           // If we can't stat the file we're remapping to, assume that something
           // horrible happened.
           AnyFileChanged = true;
           break;
         }
 
-        OverriddenFiles[Status.getUniqueID()] = PreambleFileHash::createForFile(
-            Status.getSize(),
-            llvm::sys::toTimeT(Status.getLastModificationTime()));
+        OverriddenFiles[fileEntry->getUniqueID()] = PreambleFileHash::createForFile(
+            fileEntry->getSize(),
+            fileEntry->getModificationTime());
       }
 
       for (const auto &RB : PreprocessorOpts.RemappedFileBuffers) {
         if (AnyFileChanged)
           break;
 
-        vfs::Status Status;
-        if (FileMgr->getNoncachedStatValue(RB.first, Status)) {
+        const FileEntry *fileEntry = FileMgr->getFile(RB.first);
+        if (!fileEntry) {
           AnyFileChanged = true;
           break;
         }
 
-        OverriddenFiles[Status.getUniqueID()] =
+        OverriddenFiles[fileEntry->getUniqueID()] =
             PreambleFileHash::createForMemoryBuffer(RB.second);
       }
        
       // Check whether anything has changed.
       for (llvm::StringMap<PreambleFileHash>::iterator
              F = FilesInPreamble.begin(), FEnd = FilesInPreamble.end();
            !AnyFileChanged && F != FEnd; 
            ++F) {
-        vfs::Status Status;
-        if (FileMgr->getNoncachedStatValue(F->first(), Status)) {
+        const FileEntry *fileEntry = FileMgr->getFile(F->first());
+        if (!fileEntry) {
           // If we can't stat the file, assume that something horrible happened.
           AnyFileChanged = true;
           break;
         }
 
         std::map<llvm::sys::fs::UniqueID, PreambleFileHash>::iterator Overridden
-          = OverriddenFiles.find(Status.getUniqueID());
+          = OverriddenFiles.find(fileEntry->getUniqueID());
         if (Overridden != OverriddenFiles.end()) {
           // This file was remapped; check whether the newly-mapped file 
           // matches up with the previous mapping.
           if (Overridden->second != F->second)
             AnyFileChanged = true;
           continue;
         }
-        
+
         // The file was not remapped; check whether it has changed on disk.
-        if (Status.getSize() != uint64_t(F->second.Size) ||
-            llvm::sys::toTimeT(Status.getLastModificationTime()) !=
-                F->second.ModTime)
+        if (fileEntry->getSize() != F->second.Size ||
+            fileEntry->getModificationTime() != F->second.ModTime)
           AnyFileChanged = true;
       }
           
@@ -1873,6 +1880,8 @@
   getDiagnostics().Reset();
   ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
 
+  recreateFileManager();
+
   std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
   if (PrecompilePreambleAfterNParses > 0) {
     PreambleRebuildCounter = PrecompilePreambleAfterNParses;
@@ -2040,15 +2049,16 @@
                                                       RemappedFile.second);
   }
 
+  recreateFileManager();
+
   // If we have a preamble file lying around, or if we might try to
   // build a precompiled preamble, do so now.
   std::unique_ptr<llvm::MemoryBuffer> OverrideMainBuffer;
   if (!getPreambleFile(this).empty() || PreambleRebuildCounter > 0)
     OverrideMainBuffer =
         getMainBufferWithPrecompiledPreamble(PCHContainerOps, *Invocation);
 
   // Clear out the diagnostics state.
-  FileMgr.reset();
   getDiagnostics().Reset();
   ProcessWarningOptions(getDiagnostics(), Invocation->getDiagnosticOpts());
   if (OverrideMainBuffer)
Index: include/clang/Frontend/ASTUnit.h
===================================================================
--- include/clang/Frontend/ASTUnit.h
+++ include/clang/Frontend/ASTUnit.h
@@ -518,6 +518,8 @@
   const FileManager &getFileManager() const { return *FileMgr; }
         FileManager &getFileManager()       { return *FileMgr; }
 
+  void recreateFileManager();
+
   const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; }
 
   IntrusiveRefCntPtr<ASTReader> getASTReader() const;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to