tapaswenipathak updated this revision to Diff 438550.
tapaswenipathak added a comment.

omit an unrelated change.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D126266/new/

https://reviews.llvm.org/D126266

Files:
  clang/include/clang/Basic/FileEntry.h
  clang/include/clang/Basic/FileManager.h
  clang/include/clang/Basic/SourceManager.h
  clang/lib/Basic/FileManager.cpp
  clang/lib/Basic/SourceManager.cpp
  clang/unittests/Basic/FileManagerTest.cpp
  clang/unittests/Basic/SourceManagerTest.cpp

Index: clang/unittests/Basic/SourceManagerTest.cpp
===================================================================
--- clang/unittests/Basic/SourceManagerTest.cpp
+++ clang/unittests/Basic/SourceManagerTest.cpp
@@ -26,6 +26,14 @@
 
 using namespace clang;
 
+void clang::SourceManagerTestHelper(SourceManager &SourceMgr, FileManager &FileMgr) {
+  FileID mainFileID = SourceMgr.getMainFileID();
+  const SrcMgr::ContentCache *Cache =
+    &(SourceMgr.getSLocEntry(mainFileID).getFile().getContentCache());
+  //EXPECT_FALSE(Cache->Buffer);
+  ASSERT_TRUE(FileMgr.FileEntriesToReread.empty());
+}
+
 namespace {
 
 // The test fixture.
@@ -51,6 +59,36 @@
   IntrusiveRefCntPtr<TargetInfo> Target;
 };
 
+// Test for invalidate cache success, making the file entry invalid, until
+// reread
+TEST_F(SourceManagerTest, invalidateCacheSuccess) {
+  const char *Source = "int x;";
+
+  std::unique_ptr<llvm::MemoryBuffer> Buf =
+      llvm::MemoryBuffer::getMemBuffer(Source);
+  const FileEntry *SourceFile =
+      FileMgr.getVirtualFile("mainFile.cpp", Buf->getBufferSize(), 0);
+
+  FileID mainFileID = SourceMgr.createFileID(std::move(Buf));
+  SourceMgr.overrideFileContents(SourceFile, std::move(Buf));
+  SourceMgr.setMainFileID(mainFileID);
+
+  SourceMgr.invalidateCache(mainFileID);
+
+  EXPECT_FALSE(SourceFile->isValid());
+  EXPECT_FALSE(mainFileID.isInvalid());
+
+  const SrcMgr::ContentCache *Cache =
+    &(SourceMgr.getSLocEntry(mainFileID).getFile().getContentCache());
+
+  EXPECT_EQ(SourceMgr.getNonBuiltinFilenameForID(mainFileID), None);
+  //EXPECT_EQ(SourceMgr.getBufferDataIfLoaded(mainFileID), None);
+
+  EXPECT_FALSE(Cache->IsBufferInvalid);
+
+  SourceManagerTestHelper(SourceMgr, FileMgr);
+}
+
 TEST_F(SourceManagerTest, isBeforeInTranslationUnit) {
   const char *source =
     "#define M(x) [x]\n"
Index: clang/unittests/Basic/FileManagerTest.cpp
===================================================================
--- clang/unittests/Basic/FileManagerTest.cpp
+++ clang/unittests/Basic/FileManagerTest.cpp
@@ -18,6 +18,10 @@
 using namespace llvm;
 using namespace clang;
 
+void clang::FileManagerTestHelper(FileManager &manager){
+  ASSERT_TRUE(!manager.FileEntriesToReread.empty());
+}
+
 namespace {
 
 // Used to create a fake file system for running the tests with such
@@ -99,6 +103,29 @@
   FileManager manager;
 };
 
+// If file entry valid, mark the file entry invalid, until reread.
+TEST_F(FileManagerTest, invalidateCacheSuccess) {
+  auto statCache = std::make_unique<FakeStatCache>();
+  statCache->InjectFile("file.cpp", 42);
+
+  manager.setStatCache(std::move(statCache));
+  manager.getVirtualFile("file.cpp", 100, 0);
+  auto file = manager.getFile("file.cpp");
+
+  // Check for file null assertion success
+  //manager.invalidateCache(NULL);
+
+  auto FileRef = manager.getFileRef("file.cpp");
+
+  ASSERT_FALSE(!FileRef);
+
+  FileEntry *FileEntryObj = const_cast<FileEntry*>(&FileRef->getFileEntry());
+  manager.invalidateCache(FileEntryObj);
+  FileManagerTestHelper(manager);
+
+  ASSERT_FALSE(FileEntryObj->isValid());
+}
+
 // When a virtual file is added, its getDir() field has correct name.
 TEST_F(FileManagerTest, getVirtualFileSetsTheDirFieldCorrectly) {
   FileEntryRef file = manager.getVirtualFileRef("foo.cpp", 42, 0);
Index: clang/lib/Basic/SourceManager.cpp
===================================================================
--- clang/lib/Basic/SourceManager.cpp
+++ clang/lib/Basic/SourceManager.cpp
@@ -358,6 +358,25 @@
   return false;
 }
 
+void SourceManager::invalidateCache(FileID FID) {
+  const FileEntry* Entry = getFileEntryForID(FID);
+  if (!Entry)
+    return;
+  if (ContentCache *&E = FileInfos[Entry]) {
+    E->setBuffer(nullptr);
+    E = 0;
+  }
+  if (!FID.isInvalid()) {
+    const SrcMgr::SLocEntry& SLocE = getSLocEntry(FID);
+    if (SLocE.isFile()) {
+      SrcMgr::ContentCache& CC =
+        const_cast<SrcMgr::ContentCache&>(SLocE.getFile().getContentCache());
+      CC.setBuffer(nullptr);
+    }
+  }
+  getFileManager().invalidateCache(const_cast<FileEntry*>(Entry));
+}
+
 void SourceManager::initializeForReplay(const SourceManager &Old) {
   assert(MainFileID.isInvalid() && "expected uninitialized SourceManager");
 
Index: clang/lib/Basic/FileManager.cpp
===================================================================
--- clang/lib/Basic/FileManager.cpp
+++ clang/lib/Basic/FileManager.cpp
@@ -635,6 +635,12 @@
   return std::error_code();
 }
 
+void FileManager::invalidateCache(FileEntry *Entry) {
+  assert(Entry && "Cannot invalidate a NULL FileEntry");
+  FileEntriesToReread.insert(Entry->getLastRef());
+  Entry->IsValid = false;
+}
+
 void FileManager::GetUniqueIDMapping(
     SmallVectorImpl<const FileEntry *> &UIDToFiles) const {
   UIDToFiles.clear();
Index: clang/include/clang/Basic/SourceManager.h
===================================================================
--- clang/include/clang/Basic/SourceManager.h
+++ clang/include/clang/Basic/SourceManager.h
@@ -260,6 +260,7 @@
   // If BufStr has an invalid BOM, returns the BOM name; otherwise, returns
   // nullptr
   static const char *getInvalidBOM(StringRef BufStr);
+  friend void SourceManagerTestHelper(SourceManager &, FileManager &);
 };
 
 // Assert that the \c ContentCache objects will always be 8-byte aligned so
@@ -797,6 +798,8 @@
   ~SourceManager();
 
   void clearIDTables();
+  friend void SourceManagerTestHelper(SourceManager &, FileManager &);
+  void invalidateCache(FileID FID);
 
   /// Initialize this source manager suitably to replay the compilation
   /// described by \p Old. Requires that \p Old outlive \p *this.
Index: clang/include/clang/Basic/FileManager.h
===================================================================
--- clang/include/clang/Basic/FileManager.h
+++ clang/include/clang/Basic/FileManager.h
@@ -18,6 +18,7 @@
 #include "clang/Basic/FileEntry.h"
 #include "clang/Basic/FileSystemOptions.h"
 #include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceManager.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/PointerUnion.h"
@@ -32,6 +33,7 @@
 #include <map>
 #include <memory>
 #include <string>
+#include <set>
 
 namespace llvm {
 
@@ -94,6 +96,11 @@
   llvm::StringMap<llvm::ErrorOr<FileEntryRef::MapValue>, llvm::BumpPtrAllocator>
       SeenFileEntries;
 
+  std::set<const FileEntry*> FileEntriesToReread;
+
+  friend void FileManagerTestHelper(FileManager &);
+  friend void SourceManagerTestHelper(SourceManager &, FileManager &);
+
   /// A mirror of SeenFileEntries to give fake answers for getBypassFile().
   ///
   /// Don't bother hooking up a BumpPtrAllocator. This should be rarely used,
@@ -295,6 +302,9 @@
   std::error_code getNoncachedStatValue(StringRef Path,
                                         llvm::vfs::Status &Result);
 
+  /// Remove the real file \p Entry from the cache.
+  void invalidateCache(FileEntry *Entry);
+
   /// If path is not absolute and FileSystemOptions set the working
   /// directory, the path is modified to be relative to the given
   /// working directory.
Index: clang/include/clang/Basic/FileEntry.h
===================================================================
--- clang/include/clang/Basic/FileEntry.h
+++ clang/include/clang/Basic/FileEntry.h
@@ -341,6 +341,7 @@
   llvm::sys::fs::UniqueID UniqueID;
   unsigned UID = 0; // A unique (small) ID for the file.
   bool IsNamedPipe = false;
+  bool IsValid = false;
 
   /// The open file, if it is owned by the \p FileEntry.
   mutable std::unique_ptr<llvm::vfs::File> File;
@@ -362,6 +363,7 @@
   FileEntryRef getLastRef() const { return *LastRef; }
 
   StringRef tryGetRealPathName() const { return RealPathName; }
+  bool isValid() const { return IsValid; }
   off_t getSize() const { return Size; }
   unsigned getUID() const { return UID; }
   const llvm::sys::fs::UniqueID &getUniqueID() const { return UniqueID; }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to