diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2019-08-30 22:59:25 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2019-08-30 22:59:25 +0000 |
commit | 1d98bab4c4d1810b10e329ad3d185334a4320121 (patch) | |
tree | 205d96b692696cb53aa0aa879cbdd64d11ca5dc3 /unittests/Basic/FileManagerTest.cpp | |
parent | 0c07d3746df825eed1a45bf91ddbd085dbbafe87 (diff) | |
download | clang-1d98bab4c4d1810b10e329ad3d185334a4320121.tar.gz |
ASTReader: Bypass overridden files when reading PCHs
If contents of a file that is part of a PCM are overridden when reading
it, but weren't overridden when the PCM was being built, the ASTReader
will emit an error. Now it creates a separate FileEntry for recovery,
bypassing the overridden content instead of discarding it. The
pre-existing testcase clang/test/PCH/remap-file-from-pch.cpp confirms
that the new recovery method works correctly.
This resolves a long-standing FIXME to avoid hypothetically invalidating
another precompiled module that's already using the overridden contents.
This also removes ContentCache-related API that would be unsafe to use
across `CompilerInstance`s in an implicit modules build. This helps to
unblock us sinking it from SourceManager into FileManager in the future,
which would allow us to delete `InMemoryModuleCache`.
https://reviews.llvm.org/D66710
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@370546 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/Basic/FileManagerTest.cpp')
-rw-r--r-- | unittests/Basic/FileManagerTest.cpp | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/unittests/Basic/FileManagerTest.cpp b/unittests/Basic/FileManagerTest.cpp index c55403ad65..9195cc0088 100644 --- a/unittests/Basic/FileManagerTest.cpp +++ b/unittests/Basic/FileManagerTest.cpp @@ -397,4 +397,54 @@ TEST_F(FileManagerTest, getFileDontOpenRealPath) { EXPECT_EQ((*file)->tryGetRealPathName(), ExpectedResult); } +TEST_F(FileManagerTest, getBypassFile) { + SmallString<64> CustomWorkingDir; +#ifdef _WIN32 + CustomWorkingDir = "C:/"; +#else + CustomWorkingDir = "/"; +#endif + + auto FS = IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem>( + new llvm::vfs::InMemoryFileSystem); + // setCurrentworkingdirectory must finish without error. + ASSERT_TRUE(!FS->setCurrentWorkingDirectory(CustomWorkingDir)); + + FileSystemOptions Opts; + FileManager Manager(Opts, FS); + + // Inject fake files into the file system. + auto Cache = std::make_unique<FakeStatCache>(); + Cache->InjectDirectory("/tmp", 42); + Cache->InjectFile("/tmp/test", 43); + Manager.setStatCache(std::move(Cache)); + + // Set up a virtual file with a different size than FakeStatCache uses. + const FileEntry *File = Manager.getVirtualFile("/tmp/test", /*Size=*/10, 0); + ASSERT_TRUE(File); + FileEntryRef Ref("/tmp/test", *File); + EXPECT_TRUE(Ref.isValid()); + EXPECT_EQ(Ref.getSize(), 10); + + // Calling a second time should not affect the UID or size. + unsigned VirtualUID = Ref.getUID(); + EXPECT_EQ(*expectedToOptional(Manager.getFileRef("/tmp/test")), Ref); + EXPECT_EQ(Ref.getUID(), VirtualUID); + EXPECT_EQ(Ref.getSize(), 10); + + // Bypass the file. + llvm::Optional<FileEntryRef> BypassRef = Manager.getBypassFile(Ref); + ASSERT_TRUE(BypassRef); + EXPECT_TRUE(BypassRef->isValid()); + EXPECT_EQ(BypassRef->getName(), Ref.getName()); + + // Check that it's different in the right ways. + EXPECT_NE(&BypassRef->getFileEntry(), File); + EXPECT_NE(BypassRef->getUID(), VirtualUID); + EXPECT_NE(BypassRef->getSize(), Ref.getSize()); + + // The virtual file should still be returned when searching. + EXPECT_EQ(*expectedToOptional(Manager.getFileRef("/tmp/test")), Ref); +} + } // anonymous namespace |