Index: include/llvm/Support/VirtualFileSystem.h =================================================================== --- include/llvm/Support/VirtualFileSystem.h +++ include/llvm/Support/VirtualFileSystem.h @@ -279,6 +279,9 @@ /// Check whether a file exists. Provided for convenience. bool exists(const Twine &Path); + /// Is the file mounted on a local filesystem? + virtual std::error_code isLocal(const Twine &Path, bool &Result); + /// Make \a Path an absolute path. /// /// Makes \a Path absolute using the current directory if it is not already. @@ -326,6 +329,7 @@ directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; llvm::ErrorOr getCurrentWorkingDirectory() const override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; + std::error_code isLocal(const Twine &Path, bool &Result) override; std::error_code getRealPath(const Twine &Path, SmallVectorImpl &Output) const override; @@ -463,7 +467,7 @@ /// system. std::error_code getRealPath(const Twine &Path, SmallVectorImpl &Output) const override; - + std::error_code isLocal(const Twine &Path, bool &Result) override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; }; Index: lib/Support/VirtualFileSystem.cpp =================================================================== --- lib/Support/VirtualFileSystem.cpp +++ lib/Support/VirtualFileSystem.cpp @@ -136,6 +136,10 @@ return errc::operation_not_permitted; } +std::error_code FileSystem::isLocal(const Twine &Path, bool &Result) { + return errc::operation_not_permitted; +} + bool FileSystem::exists(const Twine &Path) { auto Status = status(Path); return Status && Status->exists(); @@ -233,6 +237,7 @@ llvm::ErrorOr getCurrentWorkingDirectory() const override; std::error_code setCurrentWorkingDirectory(const Twine &Path) override; + std::error_code isLocal(const Twine &Path, bool &Result) override; std::error_code getRealPath(const Twine &Path, SmallVectorImpl &Output) const override; @@ -288,6 +293,10 @@ return std::error_code(); } +std::error_code RealFileSystem::isLocal(const Twine &Path, bool &Result) { + return llvm::sys::fs::is_local(Path, Result); +} + std::error_code RealFileSystem::getRealPath(const Twine &Path, SmallVectorImpl &Output) const { @@ -377,6 +386,13 @@ return {}; } +std::error_code OverlayFileSystem::isLocal(const Twine &Path, bool &Result) { + for (auto &FS : FSList) + if (FS->exists(Path)) + return FS->isLocal(Path, Result); + return errc::no_such_file_or_directory; +} + std::error_code OverlayFileSystem::getRealPath(const Twine &Path, SmallVectorImpl &Output) const { @@ -913,6 +929,11 @@ return {}; } +std::error_code InMemoryFileSystem::isLocal(const Twine &Path, bool &Result) { + Result = false; + return {}; +} + } // namespace vfs } // namespace llvm @@ -1170,6 +1191,10 @@ return ExternalFS->setCurrentWorkingDirectory(Path); } + std::error_code isLocal(const Twine &Path, bool &Result) override { + return ExternalFS->isLocal(Path, Result); + } + directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override { ErrorOr E = lookupPath(Dir); if (!E) { Index: unittests/Support/VirtualFileSystemTest.cpp =================================================================== --- unittests/Support/VirtualFileSystemTest.cpp +++ unittests/Support/VirtualFileSystemTest.cpp @@ -885,6 +885,17 @@ getPosixPath(NormalizedFS.getCurrentWorkingDirectory().get())); } +TEST_F(InMemoryFileSystemTest, IsLocal) { + FS.setCurrentWorkingDirectory("/b"); + FS.addFile("c", 0, MemoryBuffer::getMemBuffer("")); + + std::error_code EC; + bool IsLocal = true; + EC = FS.isLocal("c", IsLocal); + ASSERT_FALSE(EC); + ASSERT_FALSE(IsLocal); +} + #if !defined(_WIN32) TEST_F(InMemoryFileSystemTest, GetRealPath) { SmallString<16> Path;