1 //===- DependencyScanningWorker.h - clang-scan-deps worker ===---*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H 10 #define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H 11 12 #include "clang/Basic/DiagnosticOptions.h" 13 #include "clang/Basic/FileManager.h" 14 #include "clang/Basic/LLVM.h" 15 #include "clang/Frontend/PCHContainerOperations.h" 16 #include "clang/Tooling/DependencyScanning/DependencyScanningService.h" 17 #include "clang/Tooling/DependencyScanning/ModuleDepCollector.h" 18 #include "llvm/Support/Error.h" 19 #include "llvm/Support/FileSystem.h" 20 #include <optional> 21 #include <string> 22 23 namespace clang { 24 25 class DependencyOutputOptions; 26 27 namespace tooling { 28 namespace dependencies { 29 30 class DependencyScanningWorkerFilesystem; 31 32 /// A command-line tool invocation that is part of building a TU. 33 /// 34 /// \see TranslationUnitDeps::Commands. 35 struct Command { 36 std::string Executable; 37 std::vector<std::string> Arguments; 38 }; 39 40 class DependencyConsumer { 41 public: 42 virtual ~DependencyConsumer() {} 43 44 virtual void handleProvidedAndRequiredStdCXXModules( 45 std::optional<P1689ModuleInfo> Provided, 46 std::vector<P1689ModuleInfo> Requires) {} 47 48 virtual void handleBuildCommand(Command Cmd) {} 49 50 virtual void 51 handleDependencyOutputOpts(const DependencyOutputOptions &Opts) = 0; 52 53 virtual void handleFileDependency(StringRef Filename) = 0; 54 55 virtual void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) = 0; 56 57 virtual void handleModuleDependency(ModuleDeps MD) = 0; 58 59 virtual void handleContextHash(std::string Hash) = 0; 60 }; 61 62 /// Dependency scanner callbacks that are used during scanning to influence the 63 /// behaviour of the scan - for example, to customize the scanned invocations. 64 class DependencyActionController { 65 public: 66 virtual ~DependencyActionController(); 67 68 virtual std::string lookupModuleOutput(const ModuleID &ID, 69 ModuleOutputKind Kind) = 0; 70 }; 71 72 /// An individual dependency scanning worker that is able to run on its own 73 /// thread. 74 /// 75 /// The worker computes the dependencies for the input files by preprocessing 76 /// sources either using a fast mode where the source files are minimized, or 77 /// using the regular processing run. 78 class DependencyScanningWorker { 79 public: 80 DependencyScanningWorker(DependencyScanningService &Service, 81 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS); 82 83 /// Run the dependency scanning tool for a given clang driver command-line, 84 /// and report the discovered dependencies to the provided consumer. If \p 85 /// ModuleName isn't empty, this function reports the dependencies of module 86 /// \p ModuleName. 87 /// 88 /// \returns false if clang errors occurred (with diagnostics reported to 89 /// \c DiagConsumer), true otherwise. 90 bool computeDependencies(StringRef WorkingDirectory, 91 const std::vector<std::string> &CommandLine, 92 DependencyConsumer &DepConsumer, 93 DependencyActionController &Controller, 94 DiagnosticConsumer &DiagConsumer, 95 std::optional<StringRef> ModuleName = std::nullopt); 96 /// \returns A \c StringError with the diagnostic output if clang errors 97 /// occurred, success otherwise. 98 llvm::Error computeDependencies( 99 StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, 100 DependencyConsumer &Consumer, DependencyActionController &Controller, 101 std::optional<StringRef> ModuleName = std::nullopt); 102 103 bool shouldEagerLoadModules() const { return EagerLoadModules; } 104 105 private: 106 std::shared_ptr<PCHContainerOperations> PCHContainerOps; 107 /// The file system to be used during the scan. 108 /// This is either \c FS passed in the constructor (when performing canonical 109 /// preprocessing), or \c DepFS (when performing dependency directives scan). 110 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS; 111 /// When performing dependency directives scan, this is the caching (and 112 /// dependency-directives-extracting) filesystem overlaid on top of \c FS 113 /// (passed in the constructor). 114 llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS; 115 ScanningOutputFormat Format; 116 /// Whether to optimize the modules' command-line arguments. 117 bool OptimizeArgs; 118 /// Whether to set up command-lines to load PCM files eagerly. 119 bool EagerLoadModules; 120 }; 121 122 } // end namespace dependencies 123 } // end namespace tooling 124 } // end namespace clang 125 126 #endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H 127