alexfh created this revision. alexfh added a reviewer: sammccall. Herald added subscribers: dexonsmith, usaxena95, kadircet, arphaman, hiraditya. alexfh requested review of this revision. Herald added projects: clang, LLVM. Herald added a subscriber: llvm-commits.
Currently, status() calls always resolve symlinks. This patch adds a parameter to control this behavior. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D97288 Files: clang-tools-extra/clangd/FS.cpp clang-tools-extra/clangd/unittests/ClangdTests.cpp clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp clang/unittests/Driver/DistroTest.cpp llvm/include/llvm/Support/VirtualFileSystem.h llvm/lib/Support/FileCollector.cpp llvm/lib/Support/VirtualFileSystem.cpp llvm/unittests/Support/VirtualFileSystemTest.cpp
Index: llvm/unittests/Support/VirtualFileSystemTest.cpp =================================================================== --- llvm/unittests/Support/VirtualFileSystemTest.cpp +++ llvm/unittests/Support/VirtualFileSystemTest.cpp @@ -57,7 +57,7 @@ public: DummyFileSystem() : FSID(getNextFSID()), FileID(0) {} - ErrorOr<vfs::Status> status(const Twine &Path) override { + ErrorOr<vfs::Status> status(const Twine &Path, bool Follow = true) override { auto I = findEntry(Path); if (I == FilesAndDirs.end()) return make_error_code(llvm::errc::no_such_file_or_directory); Index: llvm/lib/Support/VirtualFileSystem.cpp =================================================================== --- llvm/lib/Support/VirtualFileSystem.cpp +++ llvm/lib/Support/VirtualFileSystem.cpp @@ -252,7 +252,7 @@ } } - ErrorOr<Status> status(const Twine &Path) override; + ErrorOr<Status> status(const Twine &Path, bool Follow = true) override; ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override; directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; @@ -284,11 +284,12 @@ } // namespace -ErrorOr<Status> RealFileSystem::status(const Twine &Path) { +ErrorOr<Status> RealFileSystem::status(const Twine &Path, + bool Follow /*= true*/) { SmallString<256> Storage; sys::fs::file_status RealStatus; if (std::error_code EC = - sys::fs::status(adjustPath(Path, Storage), RealStatus)) + sys::fs::status(adjustPath(Path, Storage), RealStatus, Follow)) return EC; return Status::copyWithNewName(RealStatus, Path); } @@ -397,10 +398,11 @@ FS->setCurrentWorkingDirectory(getCurrentWorkingDirectory().get()); } -ErrorOr<Status> OverlayFileSystem::status(const Twine &Path) { +ErrorOr<Status> OverlayFileSystem::status(const Twine &Path, + bool Follow /*= true*/) { // FIXME: handle symlinks that cross file systems for (iterator I = overlays_begin(), E = overlays_end(); I != E; ++I) { - ErrorOr<Status> Status = (*I)->status(Path); + ErrorOr<Status> Status = (*I)->status(Path, Follow); if (Status || Status.getError() != llvm::errc::no_such_file_or_directory) return Status; } @@ -879,7 +881,9 @@ cast<detail::InMemoryFile>(*ToNode)); } -llvm::ErrorOr<Status> InMemoryFileSystem::status(const Twine &Path) { +llvm::ErrorOr<Status> InMemoryFileSystem::status(const Twine &Path, + bool Follow /*= true*/) { + // FIXME: Follow is not implemented for InMemoryFileSystem. auto Node = lookupInMemoryNode(*this, Root.get(), Path); if (Node) return detail::getNodeStatus(*Node, Path); @@ -1956,7 +1960,8 @@ return Status::copyWithNewName(DE->getStatus(), Path); } -ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path_) { +ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path_, + bool Follow /*= true*/) { SmallString<256> Path; Path_.toVector(Path); @@ -1966,13 +1971,13 @@ ErrorOr<RedirectingFileSystem::LookupResult> Result = lookupPath(Path); if (!Result) { if (shouldFallBackToExternalFS(Result.getError())) - return ExternalFS->status(Path); + return ExternalFS->status(Path, Follow); return Result.getError(); } ErrorOr<Status> S = status(Path, *Result); if (!S && shouldFallBackToExternalFS(S.getError(), Result->E)) - S = ExternalFS->status(Path); + S = ExternalFS->status(Path, Follow); return S; } Index: llvm/lib/Support/FileCollector.cpp =================================================================== --- llvm/lib/Support/FileCollector.cpp +++ llvm/lib/Support/FileCollector.cpp @@ -258,8 +258,9 @@ std::shared_ptr<FileCollector> Collector) : FS(std::move(FS)), Collector(std::move(Collector)) {} - llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path) override { - auto Result = FS->status(Path); + llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path, + bool Follow /*= true*/) override { + auto Result = FS->status(Path, Follow); if (Result && Result->exists()) Collector->addFile(Path); return Result; Index: llvm/include/llvm/Support/VirtualFileSystem.h =================================================================== --- llvm/include/llvm/Support/VirtualFileSystem.h +++ llvm/include/llvm/Support/VirtualFileSystem.h @@ -247,7 +247,12 @@ virtual ~FileSystem(); /// Get the status of the entry at \p Path, if one exists. - virtual llvm::ErrorOr<Status> status(const Twine &Path) = 0; + /// + /// @param Path Input path. + /// @param Follow When true, follows symlinks. Otherwise, the symlink itself + /// is statted. + virtual llvm::ErrorOr<Status> status(const Twine &Path, + bool Follow = true) = 0; /// Get a \p File object for the file at \p Path, if one exists. virtual llvm::ErrorOr<std::unique_ptr<File>> @@ -332,7 +337,7 @@ /// Pushes a file system on top of the stack. void pushOverlay(IntrusiveRefCntPtr<FileSystem> FS); - llvm::ErrorOr<Status> status(const Twine &Path) override; + llvm::ErrorOr<Status> status(const Twine &Path, bool Follow = true) override; llvm::ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override; directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; @@ -372,8 +377,8 @@ explicit ProxyFileSystem(IntrusiveRefCntPtr<FileSystem> FS) : FS(std::move(FS)) {} - llvm::ErrorOr<Status> status(const Twine &Path) override { - return FS->status(Path); + llvm::ErrorOr<Status> status(const Twine &Path, bool Follow = true) override { + return FS->status(Path, Follow); } llvm::ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override { @@ -475,7 +480,7 @@ /// Return true if this file system normalizes . and .. in paths. bool useNormalizedPaths() const { return UseNormalizedPaths; } - llvm::ErrorOr<Status> status(const Twine &Path) override; + llvm::ErrorOr<Status> status(const Twine &Path, bool Follow = true) override; llvm::ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override; directory_iterator dir_begin(const Twine &Dir, std::error_code &EC) override; @@ -828,7 +833,7 @@ create(ArrayRef<std::pair<std::string, std::string>> RemappedFiles, bool UseExternalNames, FileSystem &ExternalFS); - ErrorOr<Status> status(const Twine &Path) override; + ErrorOr<Status> status(const Twine &Path, bool Follow = true) override; ErrorOr<std::unique_ptr<File>> openFileForRead(const Twine &Path) override; std::error_code getRealPath(const Twine &Path, Index: clang/unittests/Driver/DistroTest.cpp =================================================================== --- clang/unittests/Driver/DistroTest.cpp +++ clang/unittests/Driver/DistroTest.cpp @@ -348,9 +348,10 @@ public: CountingFileSystem() : ProxyFileSystem(llvm::vfs::getRealFileSystem()) {} - llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path) override { + llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path, + bool Follow = true) override { ++Count; - return llvm::vfs::ProxyFileSystem::status(Path); + return llvm::vfs::ProxyFileSystem::status(Path, Follow); } llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>> Index: clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp =================================================================== --- clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp +++ clang/lib/Tooling/DependencyScanning/DependencyScanningFilesystem.cpp @@ -197,7 +197,8 @@ } llvm::ErrorOr<llvm::vfs::Status> -DependencyScanningWorkerFilesystem::status(const Twine &Path) { +DependencyScanningWorkerFilesystem::status(const Twine &Path, + bool Follow /*= true*/) { SmallString<256> OwnedFilename; StringRef Filename = Path.toStringRef(OwnedFilename); const llvm::ErrorOr<const CachedFileSystemEntry *> Result = Index: clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h =================================================================== --- clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h +++ clang/include/clang/Tooling/DependencyScanning/DependencyScanningFilesystem.h @@ -149,7 +149,8 @@ : ProxyFileSystem(std::move(FS)), SharedCache(SharedCache), PPSkipMappings(PPSkipMappings) {} - llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path) override; + llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path, + bool Follow = true) override; llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>> openFileForRead(const Twine &Path) override; Index: clang-tools-extra/clangd/unittests/ClangdTests.cpp =================================================================== --- clang-tools-extra/clangd/unittests/ClangdTests.cpp +++ clang-tools-extra/clangd/unittests/ClangdTests.cpp @@ -1015,9 +1015,10 @@ ++CountStats[llvm::sys::path::filename(Path.str())]; return ProxyFileSystem::openFileForRead(Path); } - llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path) override { + llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path, + bool Follow = true) override { ++CountStats[llvm::sys::path::filename(Path.str())]; - return ProxyFileSystem::status(Path); + return ProxyFileSystem::status(Path, Follow); } private: Index: clang-tools-extra/clangd/FS.cpp =================================================================== --- clang-tools-extra/clangd/FS.cpp +++ clang-tools-extra/clangd/FS.cpp @@ -76,8 +76,9 @@ return File; } - llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path) override { - auto S = getUnderlyingFS().status(Path); + llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path, + bool Follow = true) override { + auto S = getUnderlyingFS().status(Path, Follow); if (S) StatCache.update(getUnderlyingFS(), *S); return S; @@ -99,10 +100,11 @@ const PreambleFileStatusCache &StatCache) : ProxyFileSystem(std::move(FS)), StatCache(StatCache) {} - llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path) override { + llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path, + bool Follow = true) override { if (auto S = StatCache.lookup(Path.str())) return *S; - return getUnderlyingFS().status(Path); + return getUnderlyingFS().status(Path, Follow); } private:
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits