r348006 - [clang] Fill RealPathName for virtual files.
Kadir Cetinkaya via cfe-commits
cfe-commits at lists.llvm.org
Fri Nov 30 09:10:11 PST 2018
Author: kadircet
Date: Fri Nov 30 09:10:11 2018
New Revision: 348006
URL: http://llvm.org/viewvc/llvm-project?rev=348006&view=rev
Log:
[clang] Fill RealPathName for virtual files.
Summary:
Absolute path information for virtual files were missing even if we
have already stat'd the files. This patch puts that information for virtual
files that can succesffully be stat'd.
Reviewers: ilya-biryukov
Subscribers: cfe-commits
Differential Revision: https://reviews.llvm.org/D55054
Modified:
cfe/trunk/include/clang/Basic/FileManager.h
cfe/trunk/lib/Basic/FileManager.cpp
cfe/trunk/unittests/Basic/FileManagerTest.cpp
Modified: cfe/trunk/include/clang/Basic/FileManager.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/FileManager.h?rev=348006&r1=348005&r2=348006&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/FileManager.h (original)
+++ cfe/trunk/include/clang/Basic/FileManager.h Fri Nov 30 09:10:11 2018
@@ -104,6 +104,10 @@ public:
void closeFile() const {
File.reset(); // rely on destructor to close File
}
+
+ // Only for use in tests to see if deferred opens are happening, rather than
+ // relying on RealPathName being empty.
+ bool isOpenForTests() const { return File != nullptr; }
};
struct FileData;
@@ -173,6 +177,9 @@ class FileManager : public RefCountedBas
/// or a directory) as virtual directories.
void addAncestorsAsVirtualDirs(StringRef Path);
+ /// Fills the RealPathName in file entry.
+ void fillRealPathName(FileEntry *UFE, llvm::StringRef FileName);
+
public:
FileManager(const FileSystemOptions &FileSystemOpts,
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS = nullptr);
Modified: cfe/trunk/lib/Basic/FileManager.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/FileManager.cpp?rev=348006&r1=348005&r2=348006&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/FileManager.cpp (original)
+++ cfe/trunk/lib/Basic/FileManager.cpp Fri Nov 30 09:10:11 2018
@@ -293,16 +293,8 @@ const FileEntry *FileManager::getFile(St
// If we opened the file for the first time, record the resulting info.
// Do this even if the cache entry was valid, maybe we didn't previously open.
if (F && !UFE.File) {
- if (auto PathName = F->getName()) {
- llvm::SmallString<128> AbsPath(*PathName);
- // This is not the same as `VFS::getRealPath()`, which resolves symlinks
- // but can be very expensive on real file systems.
- // FIXME: the semantic of RealPathName is unclear, and the name might be
- // misleading. We need to clean up the interface here.
- makeAbsolutePath(AbsPath);
- llvm::sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true);
- UFE.RealPathName = AbsPath.str();
- }
+ if (auto PathName = F->getName())
+ fillRealPathName(&UFE, *PathName);
UFE.File = std::move(F);
assert(!UFE.DeferredOpen && "we just opened it!");
}
@@ -395,6 +387,7 @@ FileManager::getVirtualFile(StringRef Fi
UFE->UniqueID = Data.UniqueID;
UFE->IsNamedPipe = Data.IsNamedPipe;
UFE->InPCH = Data.InPCH;
+ fillRealPathName(UFE, Data.Name);
}
if (!UFE) {
@@ -438,6 +431,17 @@ bool FileManager::makeAbsolutePath(Small
return Changed;
}
+void FileManager::fillRealPathName(FileEntry *UFE, llvm::StringRef FileName) {
+ llvm::SmallString<128> AbsPath(FileName);
+ // This is not the same as `VFS::getRealPath()`, which resolves symlinks
+ // but can be very expensive on real file systems.
+ // FIXME: the semantic of RealPathName is unclear, and the name might be
+ // misleading. We need to clean up the interface here.
+ makeAbsolutePath(AbsPath);
+ llvm::sys::path::remove_dots(AbsPath, /*remove_dot_dot=*/true);
+ UFE->RealPathName = AbsPath.str();
+}
+
llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
FileManager::getBufferForFile(const FileEntry *Entry, bool isVolatile,
bool ShouldCloseOpenFile) {
Modified: cfe/trunk/unittests/Basic/FileManagerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Basic/FileManagerTest.cpp?rev=348006&r1=348005&r2=348006&view=diff
==============================================================================
--- cfe/trunk/unittests/Basic/FileManagerTest.cpp (original)
+++ cfe/trunk/unittests/Basic/FileManagerTest.cpp Fri Nov 30 09:10:11 2018
@@ -235,22 +235,18 @@ TEST_F(FileManagerTest, getFileDefersOpe
ASSERT_TRUE(file != nullptr);
ASSERT_TRUE(file->isValid());
// "real path name" reveals whether the file was actually opened.
- EXPECT_EQ("", file->tryGetRealPathName());
+ EXPECT_FALSE(file->isOpenForTests());
file = manager.getFile("/tmp/test", /*OpenFile=*/true);
ASSERT_TRUE(file != nullptr);
ASSERT_TRUE(file->isValid());
-#ifdef _WIN32
- EXPECT_EQ("/tmp\\test", file->tryGetRealPathName());
-#else
- EXPECT_EQ("/tmp/test", file->tryGetRealPathName());
-#endif
+ EXPECT_TRUE(file->isOpenForTests());
// However we should never try to open a file previously opened as virtual.
ASSERT_TRUE(manager.getVirtualFile("/tmp/testv", 5, 0));
ASSERT_TRUE(manager.getFile("/tmp/testv", /*OpenFile=*/false));
file = manager.getFile("/tmp/testv", /*OpenFile=*/true);
- EXPECT_EQ("", file->tryGetRealPathName());
+ EXPECT_FALSE(file->isOpenForTests());
}
// The following tests apply to Unix-like system only.
@@ -353,4 +349,19 @@ TEST_F(FileManagerTest, makeAbsoluteUses
EXPECT_EQ(Path, ExpectedResult);
}
+// getVirtualFile should always fill the real path.
+TEST_F(FileManagerTest, getVirtualFileFillsRealPathName) {
+ // Inject fake files into the file system.
+ auto statCache = llvm::make_unique<FakeStatCache>();
+ statCache->InjectDirectory("/tmp", 42);
+ statCache->InjectFile("/tmp/test", 43);
+ manager.addStatCache(std::move(statCache));
+
+ // Check for real path.
+ const FileEntry *file = manager.getVirtualFile("/tmp/test", 123, 1);
+ ASSERT_TRUE(file != nullptr);
+ ASSERT_TRUE(file->isValid());
+ EXPECT_EQ(file->tryGetRealPathName(), "/tmp/test");
+}
+
} // anonymous namespace
More information about the cfe-commits
mailing list