tapaswenipathak updated this revision to Diff 438535.
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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits