[clang] 6109006 - [clang][DependencyScanning] Relocate CompilerInstanceWithContext to DependencyScanningWorker.cpp (#211407)

via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 31 08:54:26 PDT 2026


Author: Qiongsi Wu
Date: 2026-07-31T08:54:14-07:00
New Revision: 61090066768ecb5f88d0514bb586f24fa22f98c5

URL: https://github.com/llvm/llvm-project/commit/61090066768ecb5f88d0514bb586f24fa22f98c5
DIFF: https://github.com/llvm/llvm-project/commit/61090066768ecb5f88d0514bb586f24fa22f98c5.diff

LOG: [clang][DependencyScanning] Relocate CompilerInstanceWithContext to DependencyScanningWorker.cpp (#211407)

This PR relocates all `CompilerInstanceWithContext` code to
`DependencyScanningWorker.cpp` and hides them as implementation details,
since no public APIs should use `CompilerInstanceWithContext` directly.

---

<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>

Added: 
    

Modified: 
    clang/include/clang/DependencyScanning/DependencyScanningWorker.h
    clang/include/clang/Tooling/DependencyScanningTool.h
    clang/lib/DependencyScanning/DependencyScanningWorker.cpp
    clang/lib/Tooling/DependencyScanningTool.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
index 04c0868fe3225..e30e2280f13af 100644
--- a/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
+++ b/clang/include/clang/DependencyScanning/DependencyScanningWorker.h
@@ -28,10 +28,6 @@ namespace clang {
 
 class DependencyOutputOptions;
 
-namespace tooling {
-class CompilerInstanceWithContext;
-}
-
 namespace dependencies {
 
 class DependencyConsumer;
@@ -64,6 +60,18 @@ class DependencyScanningWorker {
       DiagnosticConsumer &DiagConsumer,
       IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS = nullptr);
 
+  /// By-name scanning over a single cc1 command line. Builds a scanning session
+  /// local to this call, then pulls module names from \p getNextName until it
+  /// returns std::nullopt. Results flow to \p DepConsumer (per-name status via
+  /// finishQuery); diagnostics flow to \p DiagConsumer.
+  /// \returns false if session setup failed, true otherwise.
+  bool computeDependenciesByName(
+      StringRef CWD, ArrayRef<std::string> CC1CommandLine,
+      IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS,
+      DiagnosticConsumer &DiagConsumer, DependencyActionController &Controller,
+      llvm::function_ref<std::optional<std::string>()> getNextName,
+      DependencyConsumer &DepConsumer);
+
   /// Creates the effective VFS that will be used for the scan.
   ///
   /// If provided, OverlayFS will be overlaid on top of the Worker's dependency
@@ -79,6 +87,15 @@ class DependencyScanningWorker {
     return TracingFS.get();
   }
 
+  // MaxNumOfByNameQueries is the upper limit of the number of names the by-name
+  // scanning API (computeDependenciesByName) can drain per call. At the time of
+  // this commit, the estimated number of total unique importable names is
+  // around 3000 from Apple's SDKs. We usually import them in parallel, so it is
+  // unlikely that all names are scanned by the same worker. Therefore the 64k
+  // (20x our estimate) size is sufficient to hold the unique source locations
+  // to report diagnostics per worker.
+  static const int32_t MaxNumOfByNameQueries = 1 << 16;
+
 private:
   /// The parent dependency scanning service.
   DependencyScanningService &Service;
@@ -89,7 +106,7 @@ class DependencyScanningWorker {
   /// The tracing VFS overlaid on top of the base VFS.
   IntrusiveRefCntPtr<llvm::vfs::TracingFileSystem> TracingFS;
 
-  friend tooling::CompilerInstanceWithContext;
+  friend class CompilerInstanceWithContext;
 };
 } // end namespace dependencies
 } // end namespace clang

diff  --git a/clang/include/clang/Tooling/DependencyScanningTool.h b/clang/include/clang/Tooling/DependencyScanningTool.h
index b3ed10f7a50d9..9befa4858eba6 100644
--- a/clang/include/clang/Tooling/DependencyScanningTool.h
+++ b/clang/include/clang/Tooling/DependencyScanningTool.h
@@ -124,8 +124,6 @@ class DependencyScanningTool {
 
 private:
   dependencies::DependencyScanningWorker Worker;
-
-  friend class CompilerInstanceWithContext;
 };
 
 /// Run the dependency scanning worker for the given driver or frontend
@@ -146,79 +144,6 @@ bool computeDependencies(
     dependencies::DependencyActionController &Controller,
     DiagnosticConsumer &DiagConsumer,
     IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS = nullptr);
-
-class CompilerInstanceWithContext {
-  // Context
-  dependencies::DependencyScanningWorker &Worker;
-  llvm::StringRef CWD;
-  std::vector<std::string> CommandLine;
-
-  // Context - Diagnostics engine.
-  DiagnosticConsumer *DiagConsumer = nullptr;
-  std::unique_ptr<dependencies::DiagnosticsEngineWithDiagOpts>
-      DiagEngineWithCmdAndOpts;
-
-  // Context - compiler invocation
-  std::unique_ptr<CompilerInvocation> OriginalInvocation;
-
-  // Context - output options
-  std::unique_ptr<DependencyOutputOptions> OutputOpts;
-
-  // Context - stable directory handling
-  llvm::SmallVector<StringRef> StableDirs;
-  dependencies::PrebuiltModulesAttrsMap PrebuiltModuleASTMap;
-
-  // Compiler Instance
-  std::unique_ptr<CompilerInstance> CIPtr;
-
-  // Source location offset.
-  int32_t SrcLocOffset = 0;
-
-  CompilerInstanceWithContext(dependencies::DependencyScanningWorker &Worker,
-                              StringRef CWD, ArrayRef<std::string> CMD)
-      : Worker(Worker), CWD(CWD), CommandLine(CMD.begin(), CMD.end()) {}
-
-  bool initialize(dependencies::DependencyActionController &Controller,
-                  std::unique_ptr<dependencies::DiagnosticsEngineWithDiagOpts>
-                      DiagEngineWithDiagOpts,
-                  IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS);
-
-public:
-  /// @brief Initialize the compiler instance from an already-lowered cc1
-  ///        commandline (driver-free).
-  /// @param Worker The dependency scanning worker to initialize the compiler
-  ///        instance.
-  /// @param CWD The current working directory.
-  /// @param CC1CommandLine A cc1 command.
-  /// @param DiagEngineWithDiagOpts The diagnostic engine used during scan.
-  /// @param OverlayFS An overlay FS containing the input file, which may be
-  ///        from an in-memory buffer.
-  /// @param Controller A dependency action controller to gather some results.
-  static std::optional<CompilerInstanceWithContext>
-  initializeFromCC1Commandline(
-      dependencies::DependencyScanningWorker &Worker, StringRef CWD,
-      ArrayRef<std::string> CC1CommandLine,
-      std::unique_ptr<dependencies::DiagnosticsEngineWithDiagOpts>
-          DiagEngineWithDiagOpts,
-      IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS,
-      dependencies::DependencyActionController &Controller);
-
-  bool
-  computeDependencies(StringRef ModuleName,
-                      dependencies::DependencyConsumer &Consumer,
-                      dependencies::DependencyActionController &Controller);
-
-  // MaxNumOfQueries is the upper limit of the number of names the by-name
-  // scanning API (computeDependencies) can support after a
-  // CompilerInstanceWithContext is initialized. At the time of this commit, the
-  // estimated number of total unique importable names is around 3000 from
-  // Apple's SDKs. We usually import them in parallel, so it is unlikely that
-  // all names are all scanned by the same dependency scanning worker. Therefore
-  // the 64k (20x bigger than our estimate) size is sufficient to hold the
-  // unique source locations to report diagnostics per worker.
-  static const int32_t MaxNumOfQueries = 1 << 16;
-};
-
 } // end namespace tooling
 } // end namespace clang
 

diff  --git a/clang/lib/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/DependencyScanning/DependencyScanningWorker.cpp
index f0b90f029b83f..0921f8a96eaac 100644
--- a/clang/lib/DependencyScanning/DependencyScanningWorker.cpp
+++ b/clang/lib/DependencyScanning/DependencyScanningWorker.cpp
@@ -9,8 +9,11 @@
 #include "clang/DependencyScanning/DependencyScanningWorker.h"
 #include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/DiagnosticFrontend.h"
+#include "clang/DependencyScanning/DependencyActionController.h"
 #include "clang/DependencyScanning/DependencyConsumer.h"
 #include "clang/DependencyScanning/DependencyScannerImpl.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Lex/Preprocessor.h"
 #include "clang/Serialization/ObjectFilePCHContainerReader.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/ScopeExit.h"
@@ -19,6 +22,227 @@
 using namespace clang;
 using namespace dependencies;
 
+namespace clang {
+namespace dependencies {
+class CompilerInstanceWithContext {
+  // Context
+  DependencyScanningWorker &Worker;
+  llvm::StringRef CWD;
+  std::vector<std::string> CommandLine;
+
+  // Context - Diagnostics engine.
+  DiagnosticConsumer *DiagConsumer = nullptr;
+  std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithCmdAndOpts;
+
+  // Context - compiler invocation
+  std::unique_ptr<CompilerInvocation> OriginalInvocation;
+
+  // Context - output options
+  std::unique_ptr<DependencyOutputOptions> OutputOpts;
+
+  // Context - stable directory handling
+  llvm::SmallVector<StringRef> StableDirs;
+  PrebuiltModulesAttrsMap PrebuiltModuleASTMap;
+
+  // Compiler Instance
+  std::unique_ptr<CompilerInstance> CIPtr;
+
+  // Source location offset.
+  int32_t SrcLocOffset = 0;
+
+  CompilerInstanceWithContext(DependencyScanningWorker &Worker, StringRef CWD,
+                              ArrayRef<std::string> CMD)
+      : Worker(Worker), CWD(CWD), CommandLine(CMD.begin(), CMD.end()) {}
+
+  bool initialize(
+      DependencyActionController &Controller,
+      std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
+      IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS) {
+    {
+      auto LogLine = Worker.Service.getLogger().log();
+      LogLine.logArray("init_compiler_instance_with_context:", " ",
+                       CommandLine);
+    }
+    assert(DiagEngineWithDiagOpts && "Valid diagnostics engine required!");
+    DiagEngineWithCmdAndOpts = std::move(DiagEngineWithDiagOpts);
+    DiagConsumer = DiagEngineWithCmdAndOpts->DiagEngine->getClient();
+
+    assert(OverlayFS && "OverlayFS required!");
+    auto FS = Worker.makeEffectiveVFS(CWD, std::move(OverlayFS));
+
+    OriginalInvocation = createCompilerInvocation(
+        CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine);
+    if (!OriginalInvocation) {
+      DiagEngineWithCmdAndOpts->DiagEngine->Report(
+          diag::err_fe_expected_compiler_job)
+          << llvm::join(CommandLine, " ");
+      return false;
+    }
+
+    if (any(Worker.Service.getOpts().OptimizeArgs &
+            ScanningOptimizations::Macros))
+      canonicalizeDefines(OriginalInvocation->getPreprocessorOpts());
+
+    // Create the CompilerInstance.
+    std::shared_ptr<ModuleCache> ModCache = makeInProcessModuleCache(
+        Worker.Service.getModuleCacheEntries(), Worker.Service.getLogger());
+    CIPtr = std::make_unique<CompilerInstance>(
+        createScanCompilerInvocation(*OriginalInvocation, Worker.Service,
+                                     Controller),
+        Worker.PCHContainerOps, std::move(ModCache));
+    auto &CI = *CIPtr;
+
+    initializeScanCompilerInstance(
+        CI, std::move(FS), DiagEngineWithCmdAndOpts->DiagEngine->getClient(),
+        Worker.Service, Worker.DepFS);
+
+    StableDirs = getInitialStableDirs(CI);
+    auto MaybePrebuiltModulesASTMap =
+        computePrebuiltModulesASTMap(CI, StableDirs);
+    if (!MaybePrebuiltModulesASTMap)
+      return false;
+
+    PrebuiltModuleASTMap = std::move(*MaybePrebuiltModulesASTMap);
+    OutputOpts = createDependencyOutputOptions(*OriginalInvocation);
+
+    // We do not create the target in initializeScanCompilerInstance because
+    // setting it here is unique for by-name lookups. We create the target only
+    // once here, and the information is reused for all computeDependencies
+    // calls. We do not need to call createTarget explicitly if we go through
+    // CompilerInstance::ExecuteAction to perform scanning.
+    return CI.createTarget();
+  }
+
+public:
+  static std::optional<CompilerInstanceWithContext>
+  initializeFromCC1Commandline(
+      DependencyScanningWorker &Worker, StringRef CWD,
+      ArrayRef<std::string> CC1CommandLine,
+      std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
+      IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS,
+      DependencyActionController &Controller) {
+    CompilerInstanceWithContext CIWC(Worker, CWD, CC1CommandLine);
+    if (!CIWC.initialize(Controller, std::move(DiagEngineWithDiagOpts),
+                         std::move(OverlayFS)))
+      return std::nullopt;
+    return std::move(CIWC);
+  }
+
+  bool computeDependencies(StringRef ModuleName, DependencyConsumer &Consumer,
+                           DependencyActionController &Controller) {
+    Worker.Service.getLogger().log() << "start scan_by_name: " << ModuleName;
+    llvm::scope_exit ExitLogging([&] {
+      Worker.Service.getLogger().log() << "finish scan_by_name: " << ModuleName;
+    });
+    if (SrcLocOffset >= DependencyScanningWorker::MaxNumOfByNameQueries)
+      llvm::report_fatal_error("exceeded maximum by-name scans for worker");
+
+    assert(CIPtr && "CIPtr must be initialized before calling this method");
+    auto &CI = *CIPtr;
+
+    // We need to reset the diagnostics, so that the diagnostics issued
+    // during a previous computeDependencies call do not affect the current
+    // call. If we do not reset, we may inherit fatal errors from a previous
+    // call.
+    CI.getDiagnostics().Reset();
+
+    // We create this cleanup object because computeDependencies may exit
+    // early with errors.
+    llvm::scope_exit CleanUp([&]() {
+      CI.clearDependencyCollectors();
+      // The preprocessor may not be created at the entry of this method,
+      // but it must have been created when this method returns, whether
+      // there are errors during scanning or not.
+      CI.getPreprocessor().removePPCallbacks();
+    });
+
+    auto MDC = initializeScanInstanceDependencyCollector(
+        CI, std::make_unique<DependencyOutputOptions>(*OutputOpts),
+        Worker.Service,
+        /* The MDC's constructor makes a copy of the OriginalInvocation, so
+        we can pass it in without worrying that it might be changed across
+        invocations of computeDependencies. */
+        *OriginalInvocation, Controller, PrebuiltModuleASTMap, StableDirs);
+
+    CompilerInvocation ModuleInvocation(*OriginalInvocation);
+    if (!Controller.initialize(CI, ModuleInvocation))
+      return false;
+
+    if (!SrcLocOffset) {
+      // When SrcLocOffset is zero, we are at the beginning of the fake source
+      // file. In this case, we call BeginSourceFile to initialize.
+      std::unique_ptr<FrontendAction> Action =
+          std::make_unique<PreprocessOnlyAction>();
+      auto *InputFile = CI.getFrontendOpts().Inputs.begin();
+      bool ActionBeginSucceeded = Action->BeginSourceFile(CI, *InputFile);
+      assert(ActionBeginSucceeded && "Action BeginSourceFile must succeed");
+      (void)ActionBeginSucceeded;
+    }
+
+    Preprocessor &PP = CI.getPreprocessor();
+    SourceManager &SM = PP.getSourceManager();
+    FileID MainFileID = SM.getMainFileID();
+    SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID);
+    SourceLocation IDLocation = FileStart.getLocWithOffset(SrcLocOffset);
+    PPCallbacks *CB = nullptr;
+    if (!SrcLocOffset) {
+      // We need to call EnterSourceFile when SrcLocOffset is zero to initialize
+      // the preprocessor.
+      bool PPFailed = PP.EnterSourceFile(MainFileID, nullptr, SourceLocation());
+      assert(!PPFailed && "Preprocess must be able to enter the main file.");
+      (void)PPFailed;
+      CB = MDC->getPPCallbacks();
+    } else {
+      // When SrcLocOffset is non-zero, the preprocessor has already been
+      // initialized through a previous call of computeDependencies. We want to
+      // preserve the PP's state, hence we do not call EnterSourceFile again.
+      MDC->attachToPreprocessor(PP);
+      CB = MDC->getPPCallbacks();
+
+      FileID PrevFID;
+      SrcMgr::CharacteristicKind FileType =
+          SM.getFileCharacteristic(IDLocation);
+      CB->LexedFileChanged(MainFileID,
+                           PPChainedCallbacks::LexedFileChangeReason::EnterFile,
+                           FileType, PrevFID, IDLocation);
+    }
+
+    // FIXME: Scan modules asynchronously here as well.
+
+    SrcLocOffset++;
+    SmallVector<IdentifierLoc, 2> Path;
+    IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName);
+    Path.emplace_back(IDLocation, ModuleID);
+    auto ModResult = CI.loadModule(IDLocation, Path, Module::Hidden, false);
+
+    assert(CB && "Must have PPCallbacks after module loading");
+    CB->moduleImport(SourceLocation(), Path, ModResult);
+
+    if (!ModResult)
+      return false;
+
+    if (CI.getDiagnostics().hasErrorOccurred())
+      return false;
+
+    MDC->run(Consumer);
+    MDC->applyDiscoveredDependencies(ModuleInvocation);
+
+    bool Success = ModuleInvocation.withCowRef<bool>(
+        [&](CowCompilerInvocation &CowModuleInvocation) {
+          return Controller.finalize(CI, CowModuleInvocation);
+        });
+    if (!Success)
+      return false;
+
+    Consumer.handleBuildCommand(
+        {CommandLine[0], ModuleInvocation.getCC1CommandLine()});
+
+    return true;
+  }
+};
+} // namespace dependencies
+} // namespace clang
+
 DependencyScanningWorker::DependencyScanningWorker(
     DependencyScanningService &Service)
     : Service(Service) {
@@ -108,3 +332,29 @@ bool DependencyScanningWorker::computeDependencies(
 
   return Success && Action.hasScanned();
 }
+
+bool DependencyScanningWorker::computeDependenciesByName(
+    StringRef CWD, ArrayRef<std::string> CC1CommandLine,
+    IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS,
+    DiagnosticConsumer &DiagConsumer, DependencyActionController &Controller,
+    llvm::function_ref<std::optional<std::string>()> getNextName,
+    DependencyConsumer &DepConsumer) {
+  auto FS = makeEffectiveVFS(CWD, OverlayFS);
+  auto DiagEngine = std::make_unique<DiagnosticsEngineWithDiagOpts>(
+      CC1CommandLine, FS, DiagConsumer);
+  std::optional<CompilerInstanceWithContext> CIWC =
+      CompilerInstanceWithContext::initializeFromCC1Commandline(
+          *this, CWD, CC1CommandLine, std::move(DiagEngine),
+          std::move(OverlayFS), Controller);
+  if (!CIWC)
+    return false;
+
+  bool AllScansSucceeded = true;
+  while (std::optional<std::string> NextName = getNextName()) {
+    bool Success =
+        CIWC->computeDependencies(*NextName, DepConsumer, Controller);
+    DepConsumer.finishQuery(*NextName, Success);
+    AllScansSucceeded = AllScansSucceeded && Success;
+  }
+  return AllScansSucceeded;
+}

diff  --git a/clang/lib/Tooling/DependencyScanningTool.cpp b/clang/lib/Tooling/DependencyScanningTool.cpp
index 5ffd8c0b02115..fb3a42bc00187 100644
--- a/clang/lib/Tooling/DependencyScanningTool.cpp
+++ b/clang/lib/Tooling/DependencyScanningTool.cpp
@@ -13,10 +13,7 @@
 #include "clang/Driver/Compilation.h"
 #include "clang/Driver/Driver.h"
 #include "clang/Driver/Tool.h"
-#include "clang/Frontend/FrontendActions.h"
 #include "clang/Frontend/Utils.h"
-#include "clang/Lex/Preprocessor.h"
-#include "llvm/ADT/ScopeExit.h"
 #include "llvm/ADT/SmallVectorExtras.h"
 #include "llvm/ADT/iterator.h"
 #include "llvm/TargetParser/Host.h"
@@ -280,7 +277,7 @@ initVFSForByNameScanning(ArrayRef<std::string> CommandLine) {
   // locations for the diagnostics. Therefore, sharing this global buffer across
   // threads is ok.
   static const std::string FakeInput(
-      CompilerInstanceWithContext::MaxNumOfQueries, ' ');
+      DependencyScanningWorker::MaxNumOfByNameQueries, ' ');
 
   StringRef InputPath =
       llvm::sys::path::is_style_windows(llvm::sys::path::Style::native)
@@ -367,207 +364,7 @@ bool DependencyScanningTool::getByNameDependencies(
     CC1CommandLine.assign(MaybeFirstCC1->begin(), MaybeFirstCC1->end());
   }
 
-  // Build one scanning session (a CIWC reused across all input names) and pull
-  // names until getNextName is exhausted.
-  auto DiagEngineWithOpts = std::make_unique<DiagnosticsEngineWithDiagOpts>(
-      CC1CommandLine, FS, DiagConsumer);
-  std::optional<CompilerInstanceWithContext> CIWC =
-      CompilerInstanceWithContext::initializeFromCC1Commandline(
-          Worker, CWD, CC1CommandLine, std::move(DiagEngineWithOpts),
-          std::move(OverlayFS), Controller);
-  if (!CIWC)
-    return false;
-
-  bool AllScansSucceeded = true;
-  while (std::optional<std::string> NextName = getNextName()) {
-    bool Success =
-        CIWC->computeDependencies(*NextName, DepConsumer, Controller);
-    DepConsumer.finishQuery(*NextName, Success);
-    AllScansSucceeded = AllScansSucceeded && Success;
-  }
-  return AllScansSucceeded;
-}
-
-std::optional<CompilerInstanceWithContext>
-CompilerInstanceWithContext::initializeFromCC1Commandline(
-    DependencyScanningWorker &Worker, StringRef CWD,
-    ArrayRef<std::string> CC1CommandLine,
-    std::unique_ptr<dependencies::DiagnosticsEngineWithDiagOpts>
-        DiagEngineWithDiagOpts,
-    IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS,
-    DependencyActionController &Controller) {
-  CompilerInstanceWithContext CIWC(Worker, CWD, CC1CommandLine);
-  if (!CIWC.initialize(Controller, std::move(DiagEngineWithDiagOpts),
-                       std::move(OverlayFS)))
-    return std::nullopt;
-  return std::move(CIWC);
-}
-
-bool CompilerInstanceWithContext::initialize(
-    DependencyActionController &Controller,
-    std::unique_ptr<DiagnosticsEngineWithDiagOpts> DiagEngineWithDiagOpts,
-    IntrusiveRefCntPtr<llvm::vfs::FileSystem> OverlayFS) {
-  {
-    auto LogLine = Worker.Service.getLogger().log();
-    LogLine.logArray("init_compiler_instance_with_context:", " ", CommandLine);
-  }
-  assert(DiagEngineWithDiagOpts && "Valid diagnostics engine required!");
-  DiagEngineWithCmdAndOpts = std::move(DiagEngineWithDiagOpts);
-  DiagConsumer = DiagEngineWithCmdAndOpts->DiagEngine->getClient();
-
-  assert(OverlayFS && "OverlayFS required!");
-  auto FS = Worker.makeEffectiveVFS(CWD, std::move(OverlayFS));
-
-  OriginalInvocation = createCompilerInvocation(
-      CommandLine, *DiagEngineWithCmdAndOpts->DiagEngine);
-  if (!OriginalInvocation) {
-    DiagEngineWithCmdAndOpts->DiagEngine->Report(
-        diag::err_fe_expected_compiler_job)
-        << llvm::join(CommandLine, " ");
-    return false;
-  }
-
-  if (any(Worker.Service.getOpts().OptimizeArgs &
-          ScanningOptimizations::Macros))
-    canonicalizeDefines(OriginalInvocation->getPreprocessorOpts());
-
-  // Create the CompilerInstance.
-  std::shared_ptr<ModuleCache> ModCache = makeInProcessModuleCache(
-      Worker.Service.getModuleCacheEntries(), Worker.Service.getLogger());
-  CIPtr = std::make_unique<CompilerInstance>(
-      createScanCompilerInvocation(*OriginalInvocation, Worker.Service,
-                                   Controller),
-      Worker.PCHContainerOps, std::move(ModCache));
-  auto &CI = *CIPtr;
-
-  initializeScanCompilerInstance(
-      CI, std::move(FS), DiagEngineWithCmdAndOpts->DiagEngine->getClient(),
-      Worker.Service, Worker.DepFS);
-
-  StableDirs = getInitialStableDirs(CI);
-  auto MaybePrebuiltModulesASTMap =
-      computePrebuiltModulesASTMap(CI, StableDirs);
-  if (!MaybePrebuiltModulesASTMap)
-    return false;
-
-  PrebuiltModuleASTMap = std::move(*MaybePrebuiltModulesASTMap);
-  OutputOpts = createDependencyOutputOptions(*OriginalInvocation);
-
-  // We do not create the target in initializeScanCompilerInstance because
-  // setting it here is unique for by-name lookups. We create the target only
-  // once here, and the information is reused for all computeDependencies calls.
-  // We do not need to call createTarget explicitly if we go through
-  // CompilerInstance::ExecuteAction to perform scanning.
-  return CI.createTarget();
-}
-
-bool CompilerInstanceWithContext::computeDependencies(
-    StringRef ModuleName, DependencyConsumer &Consumer,
-    DependencyActionController &Controller) {
-  Worker.Service.getLogger().log() << "start scan_by_name: " << ModuleName;
-  llvm::scope_exit ExitLogging([&] {
-    Worker.Service.getLogger().log() << "finish scan_by_name: " << ModuleName;
-  });
-  if (SrcLocOffset >= MaxNumOfQueries)
-    llvm::report_fatal_error("exceeded maximum by-name scans for worker");
-
-  assert(CIPtr && "CIPtr must be initialized before calling this method");
-  auto &CI = *CIPtr;
-
-  // We need to reset the diagnostics, so that the diagnostics issued
-  // during a previous computeDependencies call do not affect the current call.
-  // If we do not reset, we may inherit fatal errors from a previous call.
-  CI.getDiagnostics().Reset();
-
-  // We create this cleanup object because computeDependencies may exit
-  // early with errors.
-  llvm::scope_exit CleanUp([&]() {
-    CI.clearDependencyCollectors();
-    // The preprocessor may not be created at the entry of this method,
-    // but it must have been created when this method returns, whether
-    // there are errors during scanning or not.
-    CI.getPreprocessor().removePPCallbacks();
-  });
-
-  auto MDC = initializeScanInstanceDependencyCollector(
-      CI, std::make_unique<DependencyOutputOptions>(*OutputOpts),
-      Worker.Service,
-      /* The MDC's constructor makes a copy of the OriginalInvocation, so
-      we can pass it in without worrying that it might be changed across
-      invocations of computeDependencies. */
-      *OriginalInvocation, Controller, PrebuiltModuleASTMap, StableDirs);
-
-  CompilerInvocation ModuleInvocation(*OriginalInvocation);
-  if (!Controller.initialize(CI, ModuleInvocation))
-    return false;
-
-  if (!SrcLocOffset) {
-    // When SrcLocOffset is zero, we are at the beginning of the fake source
-    // file. In this case, we call BeginSourceFile to initialize.
-    std::unique_ptr<FrontendAction> Action =
-        std::make_unique<PreprocessOnlyAction>();
-    auto *InputFile = CI.getFrontendOpts().Inputs.begin();
-    bool ActionBeginSucceeded = Action->BeginSourceFile(CI, *InputFile);
-    assert(ActionBeginSucceeded && "Action BeginSourceFile must succeed");
-    (void)ActionBeginSucceeded;
-  }
-
-  Preprocessor &PP = CI.getPreprocessor();
-  SourceManager &SM = PP.getSourceManager();
-  FileID MainFileID = SM.getMainFileID();
-  SourceLocation FileStart = SM.getLocForStartOfFile(MainFileID);
-  SourceLocation IDLocation = FileStart.getLocWithOffset(SrcLocOffset);
-  PPCallbacks *CB = nullptr;
-  if (!SrcLocOffset) {
-    // We need to call EnterSourceFile when SrcLocOffset is zero to initialize
-    // the preprocessor.
-    bool PPFailed = PP.EnterSourceFile(MainFileID, nullptr, SourceLocation());
-    assert(!PPFailed && "Preprocess must be able to enter the main file.");
-    (void)PPFailed;
-    CB = MDC->getPPCallbacks();
-  } else {
-    // When SrcLocOffset is non-zero, the preprocessor has already been
-    // initialized through a previous call of computeDependencies. We want to
-    // preserve the PP's state, hence we do not call EnterSourceFile again.
-    MDC->attachToPreprocessor(PP);
-    CB = MDC->getPPCallbacks();
-
-    FileID PrevFID;
-    SrcMgr::CharacteristicKind FileType = SM.getFileCharacteristic(IDLocation);
-    CB->LexedFileChanged(MainFileID,
-                         PPChainedCallbacks::LexedFileChangeReason::EnterFile,
-                         FileType, PrevFID, IDLocation);
-  }
-
-  // FIXME: Scan modules asynchronously here as well.
-
-  SrcLocOffset++;
-  SmallVector<IdentifierLoc, 2> Path;
-  IdentifierInfo *ModuleID = PP.getIdentifierInfo(ModuleName);
-  Path.emplace_back(IDLocation, ModuleID);
-  auto ModResult = CI.loadModule(IDLocation, Path, Module::Hidden, false);
-
-  assert(CB && "Must have PPCallbacks after module loading");
-  CB->moduleImport(SourceLocation(), Path, ModResult);
-
-  if (!ModResult)
-    return false;
-
-  if (CI.getDiagnostics().hasErrorOccurred())
-    return false;
-
-  MDC->run(Consumer);
-  MDC->applyDiscoveredDependencies(ModuleInvocation);
-
-  bool Success = ModuleInvocation.withCowRef<bool>(
-      [&](CowCompilerInvocation &CowModuleInvocation) {
-        return Controller.finalize(CI, CowModuleInvocation);
-      });
-  if (!Success)
-    return false;
-
-  Consumer.handleBuildCommand(
-      {CommandLine[0], ModuleInvocation.getCC1CommandLine()});
-
-  return true;
+  return Worker.computeDependenciesByName(CWD, CC1CommandLine,
+                                          std::move(OverlayFS), DiagConsumer,
+                                          Controller, getNextName, DepConsumer);
 }


        


More information about the cfe-commits mailing list