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); } _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
