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
  • [PATCH] D97288: Ad... Alexander Kornienko via Phabricator via cfe-commits

Reply via email to