[clang] [clang] Move VFS overlays from `HeaderSearchOptions` to `FileSystemOptions` (PR #86534)

Jan Svoboda via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 25 10:16:20 PDT 2024


https://github.com/jansvoboda11 created https://github.com/llvm/llvm-project/pull/86534

None

>From 15e732563c77a0990210bc6f9212e6f96d5e727a Mon Sep 17 00:00:00 2001
From: Jan Svoboda <jan_svoboda at apple.com>
Date: Mon, 25 Mar 2024 10:15:33 -0700
Subject: [PATCH] [clang] Move VFS overlays from `HeaderSearchOptions` to
 `FileSystemOptions`

---
 clang/include/clang/Basic/FileSystemOptions.h |   3 +
 clang/include/clang/Lex/HeaderSearchOptions.h |   7 -
 .../include/clang/Serialization/ASTBitCodes.h |   6 +-
 clang/lib/Frontend/ASTUnit.cpp                |  37 ++---
 clang/lib/Frontend/CompilerInstance.cpp       |   4 +-
 clang/lib/Frontend/CompilerInvocation.cpp     |  18 +--
 clang/lib/Frontend/FrontendActions.cpp        |  12 +-
 clang/lib/Lex/HeaderSearch.cpp                |   3 +-
 clang/lib/Serialization/ASTReader.cpp         |  26 ++--
 clang/lib/Serialization/ASTWriter.cpp         |  30 ++---
 .../DependencyScanningWorker.cpp              |  56 ++++----
 .../DependencyScanning/ModuleDepCollector.cpp | 127 +++++++++---------
 12 files changed, 167 insertions(+), 162 deletions(-)

diff --git a/clang/include/clang/Basic/FileSystemOptions.h b/clang/include/clang/Basic/FileSystemOptions.h
index 458af0c7b6592c..d6c895007669cb 100644
--- a/clang/include/clang/Basic/FileSystemOptions.h
+++ b/clang/include/clang/Basic/FileSystemOptions.h
@@ -24,6 +24,9 @@ class FileSystemOptions {
   /// If set, paths are resolved as if the working directory was
   /// set to the value of WorkingDir.
   std::string WorkingDir;
+
+  /// The set of user-provided virtual filesystem overlay files.
+  std::vector<std::string> VFSOverlayFiles;
 };
 
 } // end namespace clang
diff --git a/clang/include/clang/Lex/HeaderSearchOptions.h b/clang/include/clang/Lex/HeaderSearchOptions.h
index 637dc77e5d957e..8832516b2f9288 100644
--- a/clang/include/clang/Lex/HeaderSearchOptions.h
+++ b/clang/include/clang/Lex/HeaderSearchOptions.h
@@ -188,9 +188,6 @@ class HeaderSearchOptions {
   /// of computing the module hash.
   llvm::SmallSetVector<llvm::CachedHashString, 16> ModulesIgnoreMacros;
 
-  /// The set of user-provided virtual filesystem overlay files.
-  std::vector<std::string> VFSOverlayFiles;
-
   /// Include the compiler builtin includes.
   LLVM_PREFERRED_TYPE(bool)
   unsigned UseBuiltinIncludes : 1;
@@ -296,10 +293,6 @@ class HeaderSearchOptions {
     SystemHeaderPrefixes.emplace_back(Prefix, IsSystemHeader);
   }
 
-  void AddVFSOverlayFile(StringRef Name) {
-    VFSOverlayFiles.push_back(std::string(Name));
-  }
-
   void AddPrebuiltModulePath(StringRef Name) {
     PrebuiltModulePaths.push_back(std::string(Name));
   }
diff --git a/clang/include/clang/Serialization/ASTBitCodes.h b/clang/include/clang/Serialization/ASTBitCodes.h
index f31efa5117f0d1..eb2e0b92fca74d 100644
--- a/clang/include/clang/Serialization/ASTBitCodes.h
+++ b/clang/include/clang/Serialization/ASTBitCodes.h
@@ -376,9 +376,6 @@ enum OptionsRecordTypes {
   /// Record code for the target options table.
   TARGET_OPTIONS,
 
-  /// Record code for the filesystem options table.
-  FILE_SYSTEM_OPTIONS,
-
   /// Record code for the headers search options table.
   HEADER_SEARCH_OPTIONS,
 
@@ -397,6 +394,9 @@ enum UnhashedControlBlockRecordTypes {
   /// Record code for the diagnostic options table.
   DIAGNOSTIC_OPTIONS,
 
+  /// Record code for the filesystem options table.
+  FILE_SYSTEM_OPTIONS,
+
   /// Record code for the headers search paths.
   HEADER_SEARCH_PATHS,
 
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 3610a08831e79a..6704e6628ae4ab 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -516,6 +516,7 @@ namespace {
 class ASTInfoCollector : public ASTReaderListener {
   Preprocessor &PP;
   ASTContext *Context;
+  FileSystemOptions &FSOpts;
   HeaderSearchOptions &HSOpts;
   PreprocessorOptions &PPOpts;
   LangOptions &LangOpt;
@@ -523,17 +524,17 @@ class ASTInfoCollector : public ASTReaderListener {
   IntrusiveRefCntPtr<TargetInfo> &Target;
   unsigned &Counter;
   bool InitializedLanguage = false;
-  bool InitializedHeaderSearchPaths = false;
+  bool InitializedFileSystem = false;
 
 public:
   ASTInfoCollector(Preprocessor &PP, ASTContext *Context,
-                   HeaderSearchOptions &HSOpts, PreprocessorOptions &PPOpts,
-                   LangOptions &LangOpt,
+                   FileSystemOptions &FSOpts, HeaderSearchOptions &HSOpts,
+                   PreprocessorOptions &PPOpts, LangOptions &LangOpt,
                    std::shared_ptr<TargetOptions> &TargetOpts,
                    IntrusiveRefCntPtr<TargetInfo> &Target, unsigned &Counter)
-      : PP(PP), Context(Context), HSOpts(HSOpts), PPOpts(PPOpts),
-        LangOpt(LangOpt), TargetOpts(TargetOpts), Target(Target),
-        Counter(Counter) {}
+      : PP(PP), Context(Context), FSOpts(FSOpts), HSOpts(HSOpts),
+        PPOpts(PPOpts), LangOpt(LangOpt), TargetOpts(TargetOpts),
+        Target(Target), Counter(Counter) {}
 
   bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain,
                            bool AllowCompatibleDifferences) override {
@@ -565,7 +566,6 @@ class ASTInfoCollector : public ASTReaderListener {
         this->HSOpts.ForceCheckCXX20ModulesInputFiles;
     llvm::SaveAndRestore X(this->HSOpts.UserEntries);
     llvm::SaveAndRestore Y(this->HSOpts.SystemHeaderPrefixes);
-    llvm::SaveAndRestore Z(this->HSOpts.VFSOverlayFiles);
 
     this->HSOpts = HSOpts;
     this->HSOpts.ForceCheckCXX20ModulesInputFiles =
@@ -574,24 +574,29 @@ class ASTInfoCollector : public ASTReaderListener {
     return false;
   }
 
-  bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
+  bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
                              bool Complain) override {
-    if (InitializedHeaderSearchPaths)
+    if (InitializedFileSystem)
       return false;
 
-    this->HSOpts.UserEntries = HSOpts.UserEntries;
-    this->HSOpts.SystemHeaderPrefixes = HSOpts.SystemHeaderPrefixes;
-    this->HSOpts.VFSOverlayFiles = HSOpts.VFSOverlayFiles;
+    this->FSOpts.VFSOverlayFiles = FSOpts.VFSOverlayFiles;
 
     // Initialize the FileManager. We can't do this in update(), since that
     // performs the initialization too late (once both target and language
     // options are read).
     PP.getFileManager().setVirtualFileSystem(createVFSFromOverlayFiles(
-        HSOpts.VFSOverlayFiles, PP.getDiagnostics(),
+        FSOpts.VFSOverlayFiles, PP.getDiagnostics(),
         PP.getFileManager().getVirtualFileSystemPtr()));
 
-    InitializedHeaderSearchPaths = true;
+    InitializedFileSystem = true;
+
+    return false;
+  }
 
+  bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
+                             bool Complain) override {
+    this->HSOpts.UserEntries = HSOpts.UserEntries;
+    this->HSOpts.SystemHeaderPrefixes = HSOpts.SystemHeaderPrefixes;
     return false;
   }
 
@@ -862,8 +867,8 @@ std::unique_ptr<ASTUnit> ASTUnit::LoadFromASTFile(
 
   unsigned Counter = 0;
   AST->Reader->setListener(std::make_unique<ASTInfoCollector>(
-      *AST->PP, AST->Ctx.get(), *AST->HSOpts, *AST->PPOpts, *AST->LangOpts,
-      AST->TargetOpts, AST->Target, Counter));
+      *AST->PP, AST->Ctx.get(), AST->FileSystemOpts, *AST->HSOpts, *AST->PPOpts,
+      *AST->LangOpts, AST->TargetOpts, AST->Target, Counter));
 
   // Attach the AST reader to the AST context as an external AST
   // source, so that declarations will be deserialized from the
diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp
index 019f847ccbaad0..6d79484654debd 100644
--- a/clang/lib/Frontend/CompilerInstance.cpp
+++ b/clang/lib/Frontend/CompilerInstance.cpp
@@ -261,12 +261,12 @@ static void collectIncludePCH(CompilerInstance &CI,
 
 static void collectVFSEntries(CompilerInstance &CI,
                               std::shared_ptr<ModuleDependencyCollector> MDC) {
-  if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty())
+  if (CI.getFileSystemOpts().VFSOverlayFiles.empty())
     return;
 
   // Collect all VFS found.
   SmallVector<llvm::vfs::YAMLVFSEntry, 16> VFSEntries;
-  for (const std::string &VFSFile : CI.getHeaderSearchOpts().VFSOverlayFiles) {
+  for (const std::string &VFSFile : CI.getFileSystemOpts().VFSOverlayFiles) {
     llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> Buffer =
         llvm::MemoryBuffer::getFile(VFSFile);
     if (!Buffer)
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 0df6a82ccd8933..f3f8a92b2f77e4 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -2319,6 +2319,9 @@ static void GenerateFileSystemArgs(const FileSystemOptions &Opts,
   GENERATE_OPTION_WITH_MARSHALLING(Consumer, __VA_ARGS__)
 #include "clang/Driver/Options.inc"
 #undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
+
+  for (const std::string &F : Opts.VFSOverlayFiles)
+    GenerateArg(Consumer, OPT_ivfsoverlay, F);
 }
 
 static bool ParseFileSystemArgs(FileSystemOptions &Opts, const ArgList &Args,
@@ -2332,6 +2335,9 @@ static bool ParseFileSystemArgs(FileSystemOptions &Opts, const ArgList &Args,
 #include "clang/Driver/Options.inc"
 #undef FILE_SYSTEM_OPTION_WITH_MARSHALLING
 
+  for (const auto *A : Args.filtered(OPT_ivfsoverlay, OPT_vfsoverlay))
+    Opts.VFSOverlayFiles.push_back(std::string(A->getValue()));
+
   return Diags.getNumErrors() == NumErrorsBefore;
 }
 
@@ -3138,9 +3144,6 @@ static void GenerateHeaderSearchArgs(const HeaderSearchOptions &Opts,
                                         : OPT_no_system_header_prefix;
     GenerateArg(Consumer, Opt, P.Prefix);
   }
-
-  for (const std::string &F : Opts.VFSOverlayFiles)
-    GenerateArg(Consumer, OPT_ivfsoverlay, F);
 }
 
 static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
@@ -3279,9 +3282,6 @@ static bool ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args,
     Opts.AddSystemHeaderPrefix(
         A->getValue(), A->getOption().matches(OPT_system_header_prefix));
 
-  for (const auto *A : Args.filtered(OPT_ivfsoverlay, OPT_vfsoverlay))
-    Opts.AddVFSOverlayFile(A->getValue());
-
   return Diags.getNumErrors() == NumErrorsBefore;
 }
 
@@ -4704,7 +4704,7 @@ bool CompilerInvocation::CreateFromArgsImpl(
   // to determine the PGO type.
   if (!Res.getCodeGenOpts().ProfileInstrumentUsePath.empty()) {
     auto FS =
-        createVFSFromOverlayFiles(Res.getHeaderSearchOpts().VFSOverlayFiles,
+        createVFSFromOverlayFiles(Res.getFileSystemOpts().VFSOverlayFiles,
                                   Diags, llvm::vfs::getRealFileSystem());
     setPGOUseInstrumentor(Res.getCodeGenOpts(),
                           Res.getCodeGenOpts().ProfileInstrumentUsePath, *FS,
@@ -4796,7 +4796,7 @@ std::string CompilerInvocation::getModuleHash() const {
   if (hsOpts.ModulesStrictContextHash) {
     HBuilder.addRange(hsOpts.SystemHeaderPrefixes);
     HBuilder.addRange(hsOpts.UserEntries);
-    HBuilder.addRange(hsOpts.VFSOverlayFiles);
+    HBuilder.addRange(getFileSystemOpts().VFSOverlayFiles);
 
     const DiagnosticOptions &diagOpts = getDiagnosticOpts();
 #define DIAGOPT(Name, Bits, Default) HBuilder.add(diagOpts.Name);
@@ -4916,7 +4916,7 @@ IntrusiveRefCntPtr<llvm::vfs::FileSystem>
 clang::createVFSFromCompilerInvocation(
     const CompilerInvocation &CI, DiagnosticsEngine &Diags,
     IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS) {
-  return createVFSFromOverlayFiles(CI.getHeaderSearchOpts().VFSOverlayFiles,
+  return createVFSFromOverlayFiles(CI.getFileSystemOpts().VFSOverlayFiles,
                                    Diags, std::move(BaseFS));
 }
 
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 81fcd8d5ae9bd3..38afde66098a11 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -695,6 +695,15 @@ namespace {
       return false;
     }
 
+    bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
+                               bool Complain) override {
+      Out.indent(2) << "File system options:\n";
+      Out.indent(4) << "VFS overlay files:\n";
+      for (const auto &Overlay : FSOpts.VFSOverlayFiles)
+        Out.indent(6) << Overlay << "\n";
+      return false;
+    }
+
     bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
                                bool Complain) override {
       Out.indent(2) << "Header search paths:\n";
@@ -704,9 +713,6 @@ namespace {
       Out.indent(4) << "System header prefixes:\n";
       for (const auto &Prefix : HSOpts.SystemHeaderPrefixes)
         Out.indent(6) << Prefix.Prefix << "\n";
-      Out.indent(4) << "VFS overlay files:\n";
-      for (const auto &Overlay : HSOpts.VFSOverlayFiles)
-        Out.indent(6) << Overlay << "\n";
       return false;
     }
 
diff --git a/clang/lib/Lex/HeaderSearch.cpp b/clang/lib/Lex/HeaderSearch.cpp
index fcc2b56df166b8..c7d65a1352a04a 100644
--- a/clang/lib/Lex/HeaderSearch.cpp
+++ b/clang/lib/Lex/HeaderSearch.cpp
@@ -155,7 +155,8 @@ std::vector<bool> HeaderSearch::collectVFSUsageAndClear() const {
       RFS->clearHasBeenUsed();
     }
   });
-  assert(VFSUsage.size() == getHeaderSearchOpts().VFSOverlayFiles.size() &&
+  assert(VFSUsage.size() ==
+             FileMgr.getFileSystemOpts().VFSOverlayFiles.size() &&
          "A different number of RedirectingFileSystem's were present than "
          "-ivfsoverlay options passed to Clang!");
   // VFS visit order is the opposite of VFSOverlayFiles order.
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 28e8d27fef08c6..d6678b3d518abd 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -2773,14 +2773,6 @@ ASTReader::ASTReadResult ASTReader::ReadOptionsBlock(
       break;
     }
 
-    case FILE_SYSTEM_OPTIONS: {
-      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
-      if (!AllowCompatibleConfigurationMismatch &&
-          ParseFileSystemOptions(Record, Complain, Listener))
-        Result = ConfigurationMismatch;
-      break;
-    }
-
     case HEADER_SEARCH_OPTIONS: {
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
       if (!AllowCompatibleConfigurationMismatch &&
@@ -4978,6 +4970,13 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl(
         Result = OutOfDate; // Don't return early.  Read the signature.
       break;
     }
+    case FILE_SYSTEM_OPTIONS: {
+      bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
+      if (Listener && !AllowCompatibleConfigurationMismatch &&
+          ParseFileSystemOptions(Record, Complain, *Listener))
+        Result = ConfigurationMismatch;
+      break;
+    }
     case HEADER_SEARCH_PATHS: {
       bool Complain = (ClientLoadCapabilities & ARR_ConfigurationMismatch) == 0;
       if (Listener && !AllowCompatibleConfigurationMismatch &&
@@ -6103,7 +6102,12 @@ bool ASTReader::ParseFileSystemOptions(const RecordData &Record, bool Complain,
                                        ASTReaderListener &Listener) {
   FileSystemOptions FSOpts;
   unsigned Idx = 0;
+
   FSOpts.WorkingDir = ReadString(Record, Idx);
+
+  for (unsigned N = Record[Idx++]; N; --N)
+    FSOpts.VFSOverlayFiles.emplace_back(ReadString(Record, Idx));
+
   return Listener.ReadFileSystemOptions(FSOpts, Complain);
 }
 
@@ -6154,12 +6158,6 @@ bool ASTReader::ParseHeaderSearchPaths(const RecordData &Record, bool Complain,
     HSOpts.SystemHeaderPrefixes.emplace_back(std::move(Prefix), IsSystemHeader);
   }
 
-  // VFS overlay files.
-  for (unsigned N = Record[Idx++]; N; --N) {
-    std::string VFSOverlayFile = ReadString(Record, Idx);
-    HSOpts.VFSOverlayFiles.emplace_back(std::move(VFSOverlayFile));
-  }
-
   return Listener.ReadHeaderSearchPaths(HSOpts, Complain);
 }
 
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 221409d011a38c..7b37547e4b12fe 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -825,7 +825,6 @@ void ASTWriter::WriteBlockInfoBlock() {
   BLOCK(OPTIONS_BLOCK);
   RECORD(LANGUAGE_OPTIONS);
   RECORD(TARGET_OPTIONS);
-  RECORD(FILE_SYSTEM_OPTIONS);
   RECORD(HEADER_SEARCH_OPTIONS);
   RECORD(PREPROCESSOR_OPTIONS);
 
@@ -1065,6 +1064,7 @@ void ASTWriter::WriteBlockInfoBlock() {
   RECORD(SIGNATURE);
   RECORD(AST_BLOCK_HASH);
   RECORD(DIAGNOSTIC_OPTIONS);
+  RECORD(FILE_SYSTEM_OPTIONS);
   RECORD(HEADER_SEARCH_PATHS);
   RECORD(DIAG_PRAGMA_MAPPINGS);
 
@@ -1243,6 +1243,19 @@ void ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
     Record.clear();
   }
 
+  // File system options.
+  const FileSystemOptions &FSOpts =
+      Context.getSourceManager().getFileManager().getFileSystemOpts();
+
+  AddString(FSOpts.WorkingDir, Record);
+
+  Record.push_back(FSOpts.VFSOverlayFiles.size());
+  for (StringRef VFSOverlayFile : FSOpts.VFSOverlayFiles)
+    AddString(VFSOverlayFile, Record);
+
+  Stream.EmitRecord(FILE_SYSTEM_OPTIONS, Record);
+  Record.clear();
+
   // Header search paths.
   if (!HSOpts.ModulesSkipHeaderSearchPaths) {
     // Include entries.
@@ -1262,11 +1275,6 @@ void ASTWriter::writeUnhashedControlBlock(Preprocessor &PP,
       Record.push_back(HSOpts.SystemHeaderPrefixes[I].IsSystemHeader);
     }
 
-    // VFS overlay files.
-    Record.push_back(HSOpts.VFSOverlayFiles.size());
-    for (StringRef VFSOverlayFile : HSOpts.VFSOverlayFiles)
-      AddString(VFSOverlayFile, Record);
-
     Stream.EmitRecord(HEADER_SEARCH_PATHS, Record);
   }
 
@@ -1508,13 +1516,6 @@ void ASTWriter::WriteControlBlock(Preprocessor &PP, ASTContext &Context,
   }
   Stream.EmitRecord(TARGET_OPTIONS, Record);
 
-  // File system options.
-  Record.clear();
-  const FileSystemOptions &FSOpts =
-      Context.getSourceManager().getFileManager().getFileSystemOpts();
-  AddString(FSOpts.WorkingDir, Record);
-  Stream.EmitRecord(FILE_SYSTEM_OPTIONS, Record);
-
   // Header search options.
   Record.clear();
   const HeaderSearchOptions &HSOpts =
@@ -4762,8 +4763,7 @@ void ASTWriter::computeNonAffectingInputFiles() {
   FileManager &FileMgr = PP->getFileManager();
   FileMgr.trackVFSUsage(true);
   // Lookup the paths in the VFS to trigger `-ivfsoverlay` usage tracking.
-  for (StringRef Path :
-       PP->getHeaderSearchInfo().getHeaderSearchOpts().VFSOverlayFiles)
+  for (StringRef Path : FileMgr.getFileSystemOpts().VFSOverlayFiles)
     FileMgr.getVirtualFileSystem().exists(Path);
   for (unsigned I = 1; I != N; ++I) {
     if (IsSLocAffecting[I]) {
diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
index 76f3d950a13b81..163295e8a9687b 100644
--- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -61,25 +61,22 @@ class DependencyConsumerForwarder : public DependencyFileGenerator {
   DependencyConsumer &C;
 };
 
-static bool checkHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
-                                   const HeaderSearchOptions &ExistingHSOpts,
-                                   DiagnosticsEngine *Diags,
-                                   const LangOptions &LangOpts) {
-  if (LangOpts.Modules) {
-    if (HSOpts.VFSOverlayFiles != ExistingHSOpts.VFSOverlayFiles) {
-      if (Diags) {
-        Diags->Report(diag::warn_pch_vfsoverlay_mismatch);
-        auto VFSNote = [&](int Type, ArrayRef<std::string> VFSOverlays) {
-          if (VFSOverlays.empty()) {
-            Diags->Report(diag::note_pch_vfsoverlay_empty) << Type;
-          } else {
-            std::string Files = llvm::join(VFSOverlays, "\n");
-            Diags->Report(diag::note_pch_vfsoverlay_files) << Type << Files;
-          }
-        };
-        VFSNote(0, HSOpts.VFSOverlayFiles);
-        VFSNote(1, ExistingHSOpts.VFSOverlayFiles);
-      }
+static bool checkFileSystemOpts(const FileSystemOptions &FSOpts,
+                                const FileSystemOptions &ExistingFSOpts,
+                                DiagnosticsEngine *Diags) {
+  if (FSOpts.VFSOverlayFiles != ExistingFSOpts.VFSOverlayFiles) {
+    if (Diags) {
+      Diags->Report(diag::warn_pch_vfsoverlay_mismatch);
+      auto VFSNote = [&](int Type, ArrayRef<std::string> VFSOverlays) {
+        if (VFSOverlays.empty()) {
+          Diags->Report(diag::note_pch_vfsoverlay_empty) << Type;
+        } else {
+          std::string Files = llvm::join(VFSOverlays, "\n");
+          Diags->Report(diag::note_pch_vfsoverlay_files) << Type << Files;
+        }
+      };
+      VFSNote(0, FSOpts.VFSOverlayFiles);
+      VFSNote(1, ExistingFSOpts.VFSOverlayFiles);
     }
   }
   return false;
@@ -94,11 +91,11 @@ class PrebuiltModuleListener : public ASTReaderListener {
   PrebuiltModuleListener(PrebuiltModuleFilesT &PrebuiltModuleFiles,
                          llvm::SmallVector<std::string> &NewModuleFiles,
                          PrebuiltModuleVFSMapT &PrebuiltModuleVFSMap,
-                         const HeaderSearchOptions &HSOpts,
+                         const FileSystemOptions &FSOpts,
                          const LangOptions &LangOpts, DiagnosticsEngine &Diags)
       : PrebuiltModuleFiles(PrebuiltModuleFiles),
         NewModuleFiles(NewModuleFiles),
-        PrebuiltModuleVFSMap(PrebuiltModuleVFSMap), ExistingHSOpts(HSOpts),
+        PrebuiltModuleVFSMap(PrebuiltModuleVFSMap), ExistingFSOpts(FSOpts),
         ExistingLangOpts(LangOpts), Diags(Diags) {}
 
   bool needsImportVisitation() const override { return true; }
@@ -113,20 +110,23 @@ class PrebuiltModuleListener : public ASTReaderListener {
     CurrentFile = Filename;
   }
 
-  bool ReadHeaderSearchPaths(const HeaderSearchOptions &HSOpts,
+  bool ReadFileSystemOptions(const FileSystemOptions &FSOpts,
                              bool Complain) override {
-    std::vector<std::string> VFSOverlayFiles = HSOpts.VFSOverlayFiles;
     PrebuiltModuleVFSMap.insert(
-        {CurrentFile, llvm::StringSet<>(VFSOverlayFiles)});
-    return checkHeaderSearchPaths(
-        HSOpts, ExistingHSOpts, Complain ? &Diags : nullptr, ExistingLangOpts);
+        {CurrentFile, llvm::StringSet<>(FSOpts.VFSOverlayFiles)});
+
+    if (!ExistingLangOpts.Modules)
+      return false;
+
+    return checkFileSystemOpts(FSOpts, ExistingFSOpts,
+                               Complain ? &Diags : nullptr);
   }
 
 private:
   PrebuiltModuleFilesT &PrebuiltModuleFiles;
   llvm::SmallVector<std::string> &NewModuleFiles;
   PrebuiltModuleVFSMapT &PrebuiltModuleVFSMap;
-  const HeaderSearchOptions &ExistingHSOpts;
+  const FileSystemOptions &ExistingFSOpts;
   const LangOptions &ExistingLangOpts;
   DiagnosticsEngine &Diags;
   std::string CurrentFile;
@@ -142,7 +142,7 @@ static bool visitPrebuiltModule(StringRef PrebuiltModuleFilename,
   // List of module files to be processed.
   llvm::SmallVector<std::string> Worklist;
   PrebuiltModuleListener Listener(ModuleFiles, Worklist, PrebuiltModuleVFSMap,
-                                  CI.getHeaderSearchOpts(), CI.getLangOpts(),
+                                  CI.getFileSystemOpts(), CI.getLangOpts(),
                                   Diags);
 
   Listener.visitModuleFile(PrebuiltModuleFilename,
diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
index eb5c50c35428fe..00abc2a7253499 100644
--- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -29,72 +29,71 @@ const std::vector<std::string> &ModuleDeps::getBuildArguments() {
   return std::get<std::vector<std::string>>(BuildInfo);
 }
 
+static void optimizeHeaderSearchOpts(HeaderSearchOptions &Opts,
+                                     const serialization::ModuleFile &MF) {
+  // Only preserve search paths that were used during the dependency scan.
+  std::vector<HeaderSearchOptions::Entry> Entries;
+  std::swap(Opts.UserEntries, Entries);
+
+  llvm::BitVector SearchPathUsage(Entries.size());
+  llvm::DenseSet<const serialization::ModuleFile *> Visited;
+  std::function<void(const serialization::ModuleFile *)> VisitMF =
+      [&](const serialization::ModuleFile *MF) {
+        SearchPathUsage |= MF->SearchPathUsage;
+        Visited.insert(MF);
+        for (const serialization::ModuleFile *Import : MF->Imports)
+          if (!Visited.contains(Import))
+            VisitMF(Import);
+      };
+  VisitMF(&MF);
+
+  if (SearchPathUsage.size() != Entries.size())
+    llvm::report_fatal_error(
+        "Inconsistent search path options between modules detected");
+
+  for (auto Idx : SearchPathUsage.set_bits())
+    Opts.UserEntries.push_back(std::move(Entries[Idx]));
+}
+
 static void
-optimizeHeaderSearchOpts(HeaderSearchOptions &Opts, ASTReader &Reader,
-                         const serialization::ModuleFile &MF,
-                         const PrebuiltModuleVFSMapT &PrebuiltModuleVFSMap,
-                         ScanningOptimizations OptimizeArgs) {
-  if (any(OptimizeArgs & ScanningOptimizations::HeaderSearch)) {
-    // Only preserve search paths that were used during the dependency scan.
-    std::vector<HeaderSearchOptions::Entry> Entries;
-    std::swap(Opts.UserEntries, Entries);
-
-    llvm::BitVector SearchPathUsage(Entries.size());
-    llvm::DenseSet<const serialization::ModuleFile *> Visited;
-    std::function<void(const serialization::ModuleFile *)> VisitMF =
-        [&](const serialization::ModuleFile *MF) {
-          SearchPathUsage |= MF->SearchPathUsage;
-          Visited.insert(MF);
+optimizeFileSystemOpts(FileSystemOptions &Opts,
+                       const serialization::ModuleFile &MF,
+                       const PrebuiltModuleVFSMapT &PrebuiltModuleVFSMap) {
+  std::vector<std::string> VFSOverlayFiles;
+  std::swap(Opts.VFSOverlayFiles, VFSOverlayFiles);
+
+  llvm::BitVector VFSUsage(VFSOverlayFiles.size());
+  llvm::DenseSet<const serialization::ModuleFile *> Visited;
+  std::function<void(const serialization::ModuleFile *)> VisitMF =
+      [&](const serialization::ModuleFile *MF) {
+        Visited.insert(MF);
+        if (MF->Kind == serialization::MK_ImplicitModule) {
+          VFSUsage |= MF->VFSUsage;
+          // We only need to recurse into implicit modules. Other module types
+          // will have the correct set of VFSs for anything they depend on.
           for (const serialization::ModuleFile *Import : MF->Imports)
             if (!Visited.contains(Import))
               VisitMF(Import);
-        };
-    VisitMF(&MF);
-
-    if (SearchPathUsage.size() != Entries.size())
-      llvm::report_fatal_error(
-          "Inconsistent search path options between modules detected");
-
-    for (auto Idx : SearchPathUsage.set_bits())
-      Opts.UserEntries.push_back(std::move(Entries[Idx]));
-  }
-  if (any(OptimizeArgs & ScanningOptimizations::VFS)) {
-    std::vector<std::string> VFSOverlayFiles;
-    std::swap(Opts.VFSOverlayFiles, VFSOverlayFiles);
-
-    llvm::BitVector VFSUsage(VFSOverlayFiles.size());
-    llvm::DenseSet<const serialization::ModuleFile *> Visited;
-    std::function<void(const serialization::ModuleFile *)> VisitMF =
-        [&](const serialization::ModuleFile *MF) {
-          Visited.insert(MF);
-          if (MF->Kind == serialization::MK_ImplicitModule) {
-            VFSUsage |= MF->VFSUsage;
-            // We only need to recurse into implicit modules. Other module types
-            // will have the correct set of VFSs for anything they depend on.
-            for (const serialization::ModuleFile *Import : MF->Imports)
-              if (!Visited.contains(Import))
-                VisitMF(Import);
-          } else {
-            // This is not an implicitly built module, so it may have different
-            // VFS options. Fall back to a string comparison instead.
-            auto VFSMap = PrebuiltModuleVFSMap.find(MF->FileName);
-            if (VFSMap == PrebuiltModuleVFSMap.end())
-              return;
-            for (std::size_t I = 0, E = VFSOverlayFiles.size(); I != E; ++I) {
-              if (VFSMap->second.contains(VFSOverlayFiles[I]))
-                VFSUsage[I] = true;
-            }
+        } else {
+          // This is not an implicitly built module, so it may have different
+          // VFS options. Fall back to a string comparison instead.
+          auto VFSMap = PrebuiltModuleVFSMap.find(MF->FileName);
+          if (VFSMap == PrebuiltModuleVFSMap.end())
+            return;
+          for (std::size_t I = 0, E = VFSOverlayFiles.size(); I != E; ++I) {
+            if (VFSMap->second.contains(VFSOverlayFiles[I]))
+              VFSUsage[I] = true;
           }
-        };
-    VisitMF(&MF);
+        }
+      };
+  VisitMF(&MF);
 
-    if (VFSUsage.size() != VFSOverlayFiles.size())
-      llvm::report_fatal_error(
-          "Inconsistent -ivfsoverlay options between modules detected");
+  if (VFSUsage.size() != VFSOverlayFiles.size())
+    llvm::report_fatal_error(
+        "Inconsistent -ivfsoverlay options between modules detected");
 
-    for (auto Idx : VFSUsage.set_bits())
-      Opts.VFSOverlayFiles.push_back(std::move(VFSOverlayFiles[Idx]));
-  }
+  for (auto Idx : VFSUsage.set_bits())
+    Opts.VFSOverlayFiles.push_back(std::move(VFSOverlayFiles[Idx]));
 }
 
 static void optimizeDiagnosticOpts(DiagnosticOptions &Opts,
@@ -607,12 +606,12 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
   CowCompilerInvocation CI =
       MDC.getInvocationAdjustedForModuleBuildWithoutOutputs(
           MD, [&](CowCompilerInvocation &BuildInvocation) {
-            if (any(MDC.OptimizeArgs & (ScanningOptimizations::HeaderSearch |
-                                        ScanningOptimizations::VFS)))
+            if (any(MDC.OptimizeArgs & ScanningOptimizations::HeaderSearch))
               optimizeHeaderSearchOpts(BuildInvocation.getMutHeaderSearchOpts(),
-                                       *MDC.ScanInstance.getASTReader(), *MF,
-                                       MDC.PrebuiltModuleVFSMap,
-                                       MDC.OptimizeArgs);
+                                       *MF);
+            if (any(MDC.OptimizeArgs & ScanningOptimizations::VFS))
+              optimizeFileSystemOpts(BuildInvocation.getMutFileSystemOpts(),
+                                     *MF, MDC.PrebuiltModuleVFSMap);
             if (any(MDC.OptimizeArgs & ScanningOptimizations::SystemWarnings))
               optimizeDiagnosticOpts(
                   BuildInvocation.getMutDiagnosticOpts(),



More information about the cfe-commits mailing list