https://github.com/jansvoboda11 updated 
https://github.com/llvm/llvm-project/pull/181424

>From c7ecf43a0117d436db64d8890227230591aaa18e Mon Sep 17 00:00:00 2001
From: Jan Svoboda <[email protected]>
Date: Fri, 13 Feb 2026 13:02:22 -0800
Subject: [PATCH 1/3] [clang][deps] Make the service provide the VFS

---
 .../clang/DependencyScanning/DependencyScanningService.h    | 5 +++++
 .../clang/DependencyScanning/DependencyScanningWorker.h     | 4 +---
 clang/include/clang/Tooling/DependencyScanningTool.h        | 6 ++----
 clang/lib/DependencyScanning/DependencyScannerImpl.cpp      | 3 +--
 clang/lib/DependencyScanning/DependencyScanningService.cpp  | 3 ++-
 clang/lib/DependencyScanning/DependencyScanningWorker.cpp   | 5 +++--
 clang/lib/Tooling/DependencyScanningTool.cpp                | 6 ------
 .../DependencyScanning/DependencyScanningWorkerTest.cpp     | 3 ++-
 clang/unittests/Tooling/DependencyScannerTest.cpp           | 6 ++++--
 9 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/clang/include/clang/DependencyScanning/DependencyScanningService.h 
b/clang/include/clang/DependencyScanning/DependencyScanningService.h
index 509b6a579ecb4..20ba86bd097b0 100644
--- a/clang/include/clang/DependencyScanning/DependencyScanningService.h
+++ b/clang/include/clang/DependencyScanning/DependencyScanningService.h
@@ -80,6 +80,11 @@ enum class ScanningOptimizations {
 struct DependencyScanningServiceOptions {
   DependencyScanningServiceOptions();
 
+  /// The function invoked to create each worker's VFS. This function and the
+  /// VFS itself must be thread-safe whenever using multiple workers
+  /// concurrently or whenever \c AsyncScanModules is true.
+  std::function<IntrusiveRefCntPtr<llvm::vfs::FileSystem>()>
+      MakeVFS; // = [] { return llvm::vfs::createPhysicalFileSystem(); }
   /// Whether to use optimized dependency directive scan or full preprocessing.
   ScanningMode Mode = ScanningMode::DependencyDirectivesScan;
   /// What output format are we expected to produce.
diff --git a/clang/include/clang/DependencyScanning/DependencyScanningWorker.h 
b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
index 2a48f342335de..e1e0c14c7b52c 100644
--- a/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
+++ b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
@@ -87,9 +87,7 @@ class DependencyScanningWorker {
   /// Construct a dependency scanning worker.
   ///
   /// @param Service The parent service. Must outlive the worker.
-  /// @param BaseFS The filesystem for the worker to use.
-  DependencyScanningWorker(DependencyScanningService &Service,
-                           IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS);
+  DependencyScanningWorker(DependencyScanningService &Service);
 
   ~DependencyScanningWorker();
 
diff --git a/clang/include/clang/Tooling/DependencyScanningTool.h 
b/clang/include/clang/Tooling/DependencyScanningTool.h
index fe719aceaef1d..96d21866dd7f9 100644
--- a/clang/include/clang/Tooling/DependencyScanningTool.h
+++ b/clang/include/clang/Tooling/DependencyScanningTool.h
@@ -36,10 +36,8 @@ class DependencyScanningTool {
   /// Construct a dependency scanning tool.
   ///
   /// @param Service  The parent service. Must outlive the tool.
-  /// @param FS The filesystem for the tool to use. Defaults to the physical 
FS.
-  DependencyScanningTool(dependencies::DependencyScanningService &Service,
-                         llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
-                             llvm::vfs::createPhysicalFileSystem());
+  DependencyScanningTool(dependencies::DependencyScanningService &Service)
+      : Worker(Service) {}
 
   /// Print out the dependency information into a string using the dependency
   /// file format that is specified in the options (-MD is the default) and
diff --git a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp 
b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
index 28fa2571a24dc..3cb63a1a055ce 100644
--- a/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
+++ b/clang/lib/DependencyScanning/DependencyScannerImpl.cpp
@@ -620,10 +620,9 @@ struct AsyncModuleCompile : PPCallbacks {
     if (!LockErr && !Owned)
       return;
     // We should build the PCM.
-    // FIXME: Pass the correct BaseFS to the worker FS.
     IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS =
         llvm::makeIntrusiveRefCnt<DependencyScanningWorkerFilesystem>(
-            Service.getSharedCache(), llvm::vfs::getRealFileSystem());
+            Service.getSharedCache(), Service.getOpts().MakeVFS());
     VFS = createVFSFromCompilerInvocation(CI.getInvocation(),
                                           CI.getDiagnostics(), std::move(VFS));
     auto DC = std::make_unique<DiagnosticConsumer>();
diff --git a/clang/lib/DependencyScanning/DependencyScanningService.cpp 
b/clang/lib/DependencyScanning/DependencyScanningService.cpp
index 3651b9b20a70f..eb06c86040f0a 100644
--- a/clang/lib/DependencyScanning/DependencyScanningService.cpp
+++ b/clang/lib/DependencyScanning/DependencyScanningService.cpp
@@ -14,5 +14,6 @@ using namespace clang;
 using namespace dependencies;
 
 DependencyScanningServiceOptions::DependencyScanningServiceOptions()
-    : BuildSessionTimestamp(
+    : MakeVFS([] { return llvm::vfs::createPhysicalFileSystem(); }),
+      BuildSessionTimestamp(
           llvm::sys::toTimeT(std::chrono::system_clock::now())) {}
diff --git a/clang/lib/DependencyScanning/DependencyScanningWorker.cpp 
b/clang/lib/DependencyScanning/DependencyScanningWorker.cpp
index 7d0c93138d78c..60e5103fde6ef 100644
--- a/clang/lib/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/DependencyScanning/DependencyScanningWorker.cpp
@@ -20,8 +20,7 @@ using namespace clang;
 using namespace dependencies;
 
 DependencyScanningWorker::DependencyScanningWorker(
-    DependencyScanningService &Service,
-    llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS)
+    DependencyScanningService &Service)
     : Service(Service) {
   PCHContainerOps = std::make_shared<PCHContainerOperations>();
   // We need to read object files from PCH built outside the scanner.
@@ -30,6 +29,8 @@ DependencyScanningWorker::DependencyScanningWorker(
   // The scanner itself writes only raw ast files.
   PCHContainerOps->registerWriter(std::make_unique<RawPCHContainerWriter>());
 
+  auto BaseFS = Service.getOpts().MakeVFS();
+
   if (Service.getOpts().TraceVFS)
     BaseFS = llvm::makeIntrusiveRefCnt<llvm::vfs::TracingFileSystem>(
         std::move(BaseFS));
diff --git a/clang/lib/Tooling/DependencyScanningTool.cpp 
b/clang/lib/Tooling/DependencyScanningTool.cpp
index cc4c88fc42f5a..2ae149e8fb2cf 100644
--- a/clang/lib/Tooling/DependencyScanningTool.cpp
+++ b/clang/lib/Tooling/DependencyScanningTool.cpp
@@ -14,7 +14,6 @@
 #include "clang/Frontend/Utils.h"
 #include "llvm/ADT/SmallVectorExtras.h"
 #include "llvm/ADT/iterator.h"
-#include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/TargetParser/Host.h"
 #include <optional>
 
@@ -22,11 +21,6 @@ using namespace clang;
 using namespace tooling;
 using namespace dependencies;
 
-DependencyScanningTool::DependencyScanningTool(
-    DependencyScanningService &Service,
-    llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS)
-    : Worker(Service, std::move(FS)) {}
-
 namespace {
 /// Prints out all of the gathered dependencies into a string.
 class MakeDependencyPrinterConsumer : public DependencyConsumer {
diff --git 
a/clang/unittests/DependencyScanning/DependencyScanningWorkerTest.cpp 
b/clang/unittests/DependencyScanning/DependencyScanningWorkerTest.cpp
index ca51fc3f6fbcb..9fbebcbc4e1ca 100644
--- a/clang/unittests/DependencyScanning/DependencyScanningWorkerTest.cpp
+++ b/clang/unittests/DependencyScanning/DependencyScanningWorkerTest.cpp
@@ -32,9 +32,10 @@ TEST(DependencyScanner, ScanDepsWithDiagConsumer) {
   VFS->addFile(AsmPath, 0, llvm::MemoryBuffer::getMemBuffer(""));
 
   DependencyScanningServiceOptions Opts;
+  Opts.MakeVFS = [&] { return VFS; };
   Opts.Format = ScanningOutputFormat::Make;
   DependencyScanningService Service(std::move(Opts));
-  DependencyScanningWorker Worker(Service, VFS);
+  DependencyScanningWorker Worker(Service);
 
   llvm::DenseSet<ModuleID> AlreadySeen;
   FullDependencyConsumer DC(AlreadySeen);
diff --git a/clang/unittests/Tooling/DependencyScannerTest.cpp 
b/clang/unittests/Tooling/DependencyScannerTest.cpp
index a764a206c4670..79fd5a312d2b9 100644
--- a/clang/unittests/Tooling/DependencyScannerTest.cpp
+++ b/clang/unittests/Tooling/DependencyScannerTest.cpp
@@ -229,9 +229,10 @@ TEST(DependencyScanner, ScanDepsWithFS) {
                llvm::MemoryBuffer::getMemBuffer("#include \"header.h\"\n"));
 
   DependencyScanningServiceOptions Opts;
+  Opts.MakeVFS = [&] { return VFS; };
   Opts.Format = ScanningOutputFormat::Make;
   DependencyScanningService Service(std::move(Opts));
-  DependencyScanningTool ScanTool(Service, VFS);
+  DependencyScanningTool ScanTool(Service);
 
   TextDiagnosticBuffer DiagConsumer;
   std::optional<std::string> DepFile =
@@ -287,9 +288,10 @@ TEST(DependencyScanner, ScanDepsWithModuleLookup) {
   auto InterceptFS = llvm::makeIntrusiveRefCnt<InterceptorFS>(VFS);
 
   DependencyScanningServiceOptions Opts;
+  Opts.MakeVFS = [&] { return InterceptFS; };
   Opts.Format = ScanningOutputFormat::Make;
   DependencyScanningService Service(std::move(Opts));
-  DependencyScanningTool ScanTool(Service, InterceptFS);
+  DependencyScanningTool ScanTool(Service);
 
   // This will fail with "fatal error: module 'Foo' not found" but it doesn't
   // matter, the point of the test is to check that files are not read

>From 818ccffce0344958f71d23b1cfdb8ba86f266a25 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <[email protected]>
Date: Mon, 16 Feb 2026 08:58:18 -0800
Subject: [PATCH 2/3] Fix ScanningProjectModules.cpp

---
 clang-tools-extra/clangd/ScanningProjectModules.cpp | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/clang-tools-extra/clangd/ScanningProjectModules.cpp 
b/clang-tools-extra/clangd/ScanningProjectModules.cpp
index e2d710e3794d4..6c485586bd14a 100644
--- a/clang-tools-extra/clangd/ScanningProjectModules.cpp
+++ b/clang-tools-extra/clangd/ScanningProjectModules.cpp
@@ -35,8 +35,9 @@ class ModuleDependencyScanner {
   ModuleDependencyScanner(
       std::shared_ptr<const clang::tooling::CompilationDatabase> CDB,
       const ThreadsafeFS &TFS)
-      : CDB(CDB), TFS(TFS), Service([] {
+      : CDB(CDB), TFS(TFS), Service([this] {
           dependencies::DependencyScanningServiceOptions Opts;
+          Opts.MakeVFS = [&] { return this->TFS.view(this->FilePathDirRef); };
           Opts.Mode = dependencies::ScanningMode::CanonicalPreprocessing;
           Opts.Format = dependencies::ScanningOutputFormat::P1689;
           return Opts;
@@ -84,6 +85,9 @@ class ModuleDependencyScanner {
   // Whether the scanner has scanned the project globally.
   bool GlobalScanned = false;
 
+  /// The CWD for the TFS view used in the corresponding scanning tool.
+  PathRef FilePathDirRef;
+
   clang::dependencies::DependencyScanningService Service;
 
   // TODO: Add a scanning cache.
@@ -111,7 +115,8 @@ ModuleDependencyScanner::scan(PathRef FilePath,
 
   llvm::SmallString<128> FilePathDir(FilePath);
   llvm::sys::path::remove_filename(FilePathDir);
-  DependencyScanningTool ScanningTool(Service, TFS.view(FilePathDir));
+  FilePathDirRef = FilePathDir;
+  DependencyScanningTool ScanningTool(Service);
 
   std::string S;
   llvm::raw_string_ostream OS(S);

>From 5d50cd95626406c2d111efe5702e7632556e9904 Mon Sep 17 00:00:00 2001
From: Jan Svoboda <[email protected]>
Date: Mon, 16 Feb 2026 09:04:50 -0800
Subject: [PATCH 3/3] Simplify ScanningProjectModules.cpp

Passing the input file directory to TFS.view() doesn't do anything besides 
setting the view's CWD. The scanner immediately overwrites it with the actual 
CWD as provided by the compilation database.
---
 clang-tools-extra/clangd/ScanningProjectModules.cpp | 11 ++---------
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/clang-tools-extra/clangd/ScanningProjectModules.cpp 
b/clang-tools-extra/clangd/ScanningProjectModules.cpp
index 6c485586bd14a..b1338634e0c29 100644
--- a/clang-tools-extra/clangd/ScanningProjectModules.cpp
+++ b/clang-tools-extra/clangd/ScanningProjectModules.cpp
@@ -35,9 +35,9 @@ class ModuleDependencyScanner {
   ModuleDependencyScanner(
       std::shared_ptr<const clang::tooling::CompilationDatabase> CDB,
       const ThreadsafeFS &TFS)
-      : CDB(CDB), TFS(TFS), Service([this] {
+      : CDB(CDB), Service([&TFS] {
           dependencies::DependencyScanningServiceOptions Opts;
-          Opts.MakeVFS = [&] { return this->TFS.view(this->FilePathDirRef); };
+          Opts.MakeVFS = [&] { return TFS.view(std::nullopt); };
           Opts.Mode = dependencies::ScanningMode::CanonicalPreprocessing;
           Opts.Format = dependencies::ScanningOutputFormat::P1689;
           return Opts;
@@ -80,14 +80,10 @@ class ModuleDependencyScanner {
 
 private:
   std::shared_ptr<const clang::tooling::CompilationDatabase> CDB;
-  const ThreadsafeFS &TFS;
 
   // Whether the scanner has scanned the project globally.
   bool GlobalScanned = false;
 
-  /// The CWD for the TFS view used in the corresponding scanning tool.
-  PathRef FilePathDirRef;
-
   clang::dependencies::DependencyScanningService Service;
 
   // TODO: Add a scanning cache.
@@ -113,9 +109,6 @@ ModuleDependencyScanner::scan(PathRef FilePath,
 
   using namespace clang::tooling;
 
-  llvm::SmallString<128> FilePathDir(FilePath);
-  llvm::sys::path::remove_filename(FilePathDir);
-  FilePathDirRef = FilePathDir;
   DependencyScanningTool ScanningTool(Service);
 
   std::string S;

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to