10b57cec5SDimitry Andric //===- DependencyScanningWorker.h - clang-scan-deps worker ===---*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 904eeddc0SDimitry Andric #ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H 1004eeddc0SDimitry Andric #define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include "clang/Basic/DiagnosticOptions.h" 13a7dea167SDimitry Andric #include "clang/Basic/FileManager.h" 140b57cec5SDimitry Andric #include "clang/Basic/LLVM.h" 150b57cec5SDimitry Andric #include "clang/Frontend/PCHContainerOperations.h" 16480093f4SDimitry Andric #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" 17480093f4SDimitry Andric #include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" 180b57cec5SDimitry Andric #include "llvm/Support/Error.h" 190b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h" 20bdd1243dSDimitry Andric #include <optional> 210b57cec5SDimitry Andric #include <string> 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace clang { 24a7dea167SDimitry Andric 25a7dea167SDimitry Andric class DependencyOutputOptions; 26a7dea167SDimitry Andric 270b57cec5SDimitry Andric namespace tooling { 280b57cec5SDimitry Andric namespace dependencies { 290b57cec5SDimitry Andric 30a7dea167SDimitry Andric class DependencyScanningWorkerFilesystem; 31a7dea167SDimitry Andric 32bdd1243dSDimitry Andric /// A command-line tool invocation that is part of building a TU. 33bdd1243dSDimitry Andric /// 3406c3fb27SDimitry Andric /// \see TranslationUnitDeps::Commands. 35bdd1243dSDimitry Andric struct Command { 36bdd1243dSDimitry Andric std::string Executable; 37bdd1243dSDimitry Andric std::vector<std::string> Arguments; 38bdd1243dSDimitry Andric }; 39bdd1243dSDimitry Andric 40a7dea167SDimitry Andric class DependencyConsumer { 41a7dea167SDimitry Andric public: 42a7dea167SDimitry Andric virtual ~DependencyConsumer() {} 43a7dea167SDimitry Andric 441ac55f4cSDimitry Andric virtual void handleProvidedAndRequiredStdCXXModules( 451ac55f4cSDimitry Andric std::optional<P1689ModuleInfo> Provided, 461ac55f4cSDimitry Andric std::vector<P1689ModuleInfo> Requires) {} 471ac55f4cSDimitry Andric 481ac55f4cSDimitry Andric virtual void handleBuildCommand(Command Cmd) {} 49bdd1243dSDimitry Andric 50fe6060f1SDimitry Andric virtual void 51fe6060f1SDimitry Andric handleDependencyOutputOpts(const DependencyOutputOptions &Opts) = 0; 52fe6060f1SDimitry Andric 53fe6060f1SDimitry Andric virtual void handleFileDependency(StringRef Filename) = 0; 54fe6060f1SDimitry Andric 55fe6060f1SDimitry Andric virtual void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) = 0; 56a7dea167SDimitry Andric 57480093f4SDimitry Andric virtual void handleModuleDependency(ModuleDeps MD) = 0; 58480093f4SDimitry Andric 59*5f757f3fSDimitry Andric virtual void handleDirectModuleDependency(ModuleID MD) = 0; 60*5f757f3fSDimitry Andric 61480093f4SDimitry Andric virtual void handleContextHash(std::string Hash) = 0; 6206c3fb27SDimitry Andric }; 6306c3fb27SDimitry Andric 6406c3fb27SDimitry Andric /// Dependency scanner callbacks that are used during scanning to influence the 6506c3fb27SDimitry Andric /// behaviour of the scan - for example, to customize the scanned invocations. 6606c3fb27SDimitry Andric class DependencyActionController { 6706c3fb27SDimitry Andric public: 6806c3fb27SDimitry Andric virtual ~DependencyActionController(); 69bdd1243dSDimitry Andric 70bdd1243dSDimitry Andric virtual std::string lookupModuleOutput(const ModuleID &ID, 71bdd1243dSDimitry Andric ModuleOutputKind Kind) = 0; 72a7dea167SDimitry Andric }; 73a7dea167SDimitry Andric 740b57cec5SDimitry Andric /// An individual dependency scanning worker that is able to run on its own 750b57cec5SDimitry Andric /// thread. 760b57cec5SDimitry Andric /// 770b57cec5SDimitry Andric /// The worker computes the dependencies for the input files by preprocessing 780b57cec5SDimitry Andric /// sources either using a fast mode where the source files are minimized, or 790b57cec5SDimitry Andric /// using the regular processing run. 800b57cec5SDimitry Andric class DependencyScanningWorker { 810b57cec5SDimitry Andric public: 82fcaf7f86SDimitry Andric DependencyScanningWorker(DependencyScanningService &Service, 83fcaf7f86SDimitry Andric llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS); 840b57cec5SDimitry Andric 85349cc55cSDimitry Andric /// Run the dependency scanning tool for a given clang driver command-line, 86349cc55cSDimitry Andric /// and report the discovered dependencies to the provided consumer. If \p 87349cc55cSDimitry Andric /// ModuleName isn't empty, this function reports the dependencies of module 88349cc55cSDimitry Andric /// \p ModuleName. 890b57cec5SDimitry Andric /// 90bdd1243dSDimitry Andric /// \returns false if clang errors occurred (with diagnostics reported to 91bdd1243dSDimitry Andric /// \c DiagConsumer), true otherwise. 92bdd1243dSDimitry Andric bool computeDependencies(StringRef WorkingDirectory, 93bdd1243dSDimitry Andric const std::vector<std::string> &CommandLine, 94bdd1243dSDimitry Andric DependencyConsumer &DepConsumer, 9506c3fb27SDimitry Andric DependencyActionController &Controller, 96bdd1243dSDimitry Andric DiagnosticConsumer &DiagConsumer, 97bdd1243dSDimitry Andric std::optional<StringRef> ModuleName = std::nullopt); 980b57cec5SDimitry Andric /// \returns A \c StringError with the diagnostic output if clang errors 99a7dea167SDimitry Andric /// occurred, success otherwise. 10006c3fb27SDimitry Andric llvm::Error computeDependencies( 10106c3fb27SDimitry Andric StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, 10206c3fb27SDimitry Andric DependencyConsumer &Consumer, DependencyActionController &Controller, 103bdd1243dSDimitry Andric std::optional<StringRef> ModuleName = std::nullopt); 104bdd1243dSDimitry Andric 105bdd1243dSDimitry Andric bool shouldEagerLoadModules() const { return EagerLoadModules; } 1060b57cec5SDimitry Andric 1070b57cec5SDimitry Andric private: 1080b57cec5SDimitry Andric std::shared_ptr<PCHContainerOperations> PCHContainerOps; 109bdd1243dSDimitry Andric /// The file system to be used during the scan. 110bdd1243dSDimitry Andric /// This is either \c FS passed in the constructor (when performing canonical 111bdd1243dSDimitry Andric /// preprocessing), or \c DepFS (when performing dependency directives scan). 112bdd1243dSDimitry Andric llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS; 113bdd1243dSDimitry Andric /// When performing dependency directives scan, this is the caching (and 114bdd1243dSDimitry Andric /// dependency-directives-extracting) filesystem overlaid on top of \c FS 115bdd1243dSDimitry Andric /// (passed in the constructor). 116a7dea167SDimitry Andric llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS; 117480093f4SDimitry Andric ScanningOutputFormat Format; 118349cc55cSDimitry Andric /// Whether to optimize the modules' command-line arguments. 119*5f757f3fSDimitry Andric ScanningOptimizations OptimizeArgs; 120bdd1243dSDimitry Andric /// Whether to set up command-lines to load PCM files eagerly. 121bdd1243dSDimitry Andric bool EagerLoadModules; 1220b57cec5SDimitry Andric }; 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric } // end namespace dependencies 1250b57cec5SDimitry Andric } // end namespace tooling 1260b57cec5SDimitry Andric } // end namespace clang 1270b57cec5SDimitry Andric 12804eeddc0SDimitry Andric #endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H 129