[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