ioeric updated this revision to Diff 147487. ioeric added a comment. Minor cleanup
Repository: rC Clang https://reviews.llvm.org/D47060 Files: include/clang/Basic/VirtualFileSystem.h lib/Basic/VirtualFileSystem.cpp unittests/Basic/VirtualFileSystemTest.cpp Index: unittests/Basic/VirtualFileSystemTest.cpp =================================================================== --- unittests/Basic/VirtualFileSystemTest.cpp +++ unittests/Basic/VirtualFileSystemTest.cpp @@ -67,6 +67,19 @@ std::error_code setCurrentWorkingDirectory(const Twine &Path) override { return std::error_code(); } + // Map any symlink to "/symlink". + std::error_code getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) const override { + auto I = FilesAndDirs.find(Path.str()); + if (I == FilesAndDirs.end()) + return make_error_code(llvm::errc::no_such_file_or_directory); + if (I->second.isSymlink()) { + Twine("/symlink").toVector(Output); + return std::error_code(); + } + Path.toVector(Output); + return std::error_code(); + } struct DirIterImpl : public clang::vfs::detail::DirIterImpl { std::map<std::string, vfs::Status> &FilesAndDirs; @@ -196,6 +209,35 @@ EXPECT_TRUE(Status->equivalent(*Status2)); } +TEST(VirtualFileSystemTest, GetRealPathInOverlay) { + IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + Lower->addRegularFile("/foo"); + Lower->addSymlink("/lower_link"); + IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); + + IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( + new vfs::OverlayFileSystem(Lower)); + O->pushOverlay(Upper); + + // Regular file. + SmallString<16> RealPath; + EXPECT_FALSE(O->getRealPath("/foo", RealPath)); + EXPECT_EQ(RealPath.str(), "/foo"); + + // Expect no error getting real path for symlink in lower overlay. + EXPECT_FALSE(O->getRealPath("/lower_link", RealPath)); + EXPECT_EQ(RealPath.str(), "/symlink"); + + // Try a non-existing link. + EXPECT_EQ(O->getRealPath("/upper_link", RealPath), + errc::no_such_file_or_directory); + + // Add a new symlink in upper. + Upper->addSymlink("/upper_link"); + EXPECT_FALSE(O->getRealPath("/upper_link", RealPath)); + EXPECT_EQ(RealPath.str(), "/symlink"); +} + TEST(VirtualFileSystemTest, OverlayFiles) { IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem()); IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); Index: lib/Basic/VirtualFileSystem.cpp =================================================================== --- lib/Basic/VirtualFileSystem.cpp +++ lib/Basic/VirtualFileSystem.cpp @@ -381,6 +381,19 @@ return {}; } +std::error_code +OverlayFileSystem::getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) const { + // Not using overlays_begin/end because this method is const. + for (auto I = FSList.rbegin(), E = FSList.rend(); I != E; ++I) { + auto &FS = *I; + if (!FS->exists(Path)) + continue; + return FS->getRealPath(Path, Output); + } + return errc::no_such_file_or_directory; +} + clang::vfs::detail::DirIterImpl::~DirIterImpl() = default; namespace { Index: include/clang/Basic/VirtualFileSystem.h =================================================================== --- include/clang/Basic/VirtualFileSystem.h +++ include/clang/Basic/VirtualFileSystem.h @@ -304,6 +304,8 @@ directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; + std::error_code getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) const override; using iterator = FileSystemList::reverse_iterator;
Index: unittests/Basic/VirtualFileSystemTest.cpp =================================================================== --- unittests/Basic/VirtualFileSystemTest.cpp +++ unittests/Basic/VirtualFileSystemTest.cpp @@ -67,6 +67,19 @@ std::error_code setCurrentWorkingDirectory(const Twine &Path) override { return std::error_code(); } + // Map any symlink to "/symlink". + std::error_code getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) const override { + auto I = FilesAndDirs.find(Path.str()); + if (I == FilesAndDirs.end()) + return make_error_code(llvm::errc::no_such_file_or_directory); + if (I->second.isSymlink()) { + Twine("/symlink").toVector(Output); + return std::error_code(); + } + Path.toVector(Output); + return std::error_code(); + } struct DirIterImpl : public clang::vfs::detail::DirIterImpl { std::map<std::string, vfs::Status> &FilesAndDirs; @@ -196,6 +209,35 @@ EXPECT_TRUE(Status->equivalent(*Status2)); } +TEST(VirtualFileSystemTest, GetRealPathInOverlay) { + IntrusiveRefCntPtr<DummyFileSystem> Lower(new DummyFileSystem()); + Lower->addRegularFile("/foo"); + Lower->addSymlink("/lower_link"); + IntrusiveRefCntPtr<DummyFileSystem> Upper(new DummyFileSystem()); + + IntrusiveRefCntPtr<vfs::OverlayFileSystem> O( + new vfs::OverlayFileSystem(Lower)); + O->pushOverlay(Upper); + + // Regular file. + SmallString<16> RealPath; + EXPECT_FALSE(O->getRealPath("/foo", RealPath)); + EXPECT_EQ(RealPath.str(), "/foo"); + + // Expect no error getting real path for symlink in lower overlay. + EXPECT_FALSE(O->getRealPath("/lower_link", RealPath)); + EXPECT_EQ(RealPath.str(), "/symlink"); + + // Try a non-existing link. + EXPECT_EQ(O->getRealPath("/upper_link", RealPath), + errc::no_such_file_or_directory); + + // Add a new symlink in upper. + Upper->addSymlink("/upper_link"); + EXPECT_FALSE(O->getRealPath("/upper_link", RealPath)); + EXPECT_EQ(RealPath.str(), "/symlink"); +} + TEST(VirtualFileSystemTest, OverlayFiles) { IntrusiveRefCntPtr<DummyFileSystem> Base(new DummyFileSystem()); IntrusiveRefCntPtr<DummyFileSystem> Middle(new DummyFileSystem()); Index: lib/Basic/VirtualFileSystem.cpp =================================================================== --- lib/Basic/VirtualFileSystem.cpp +++ lib/Basic/VirtualFileSystem.cpp @@ -381,6 +381,19 @@ return {}; } +std::error_code +OverlayFileSystem::getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) const { + // Not using overlays_begin/end because this method is const. + for (auto I = FSList.rbegin(), E = FSList.rend(); I != E; ++I) { + auto &FS = *I; + if (!FS->exists(Path)) + continue; + return FS->getRealPath(Path, Output); + } + return errc::no_such_file_or_directory; +} + clang::vfs::detail::DirIterImpl::~DirIterImpl() = default; namespace { Index: include/clang/Basic/VirtualFileSystem.h =================================================================== --- include/clang/Basic/VirtualFileSystem.h +++ include/clang/Basic/VirtualFileSystem.h @@ -304,6 +304,8 @@ directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; + std::error_code getRealPath(const Twine &Path, + SmallVectorImpl<char> &Output) const override; using iterator = FileSystemList::reverse_iterator;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits