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 handleDirectModuleDependency(ModuleID MD) = 0; |
60 | |
61 | virtual void handleContextHash(std::string Hash) = 0; |
62 | }; |
63 | |
64 | /// Dependency scanner callbacks that are used during scanning to influence the |
65 | /// behaviour of the scan - for example, to customize the scanned invocations. |
66 | class DependencyActionController { |
67 | public: |
68 | virtual ~DependencyActionController(); |
69 | |
70 | virtual std::string lookupModuleOutput(const ModuleID &ID, |
71 | ModuleOutputKind Kind) = 0; |
72 | }; |
73 | |
74 | /// An individual dependency scanning worker that is able to run on its own |
75 | /// thread. |
76 | /// |
77 | /// The worker computes the dependencies for the input files by preprocessing |
78 | /// sources either using a fast mode where the source files are minimized, or |
79 | /// using the regular processing run. |
80 | class DependencyScanningWorker { |
81 | public: |
82 | DependencyScanningWorker(DependencyScanningService &Service, |
83 | llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS); |
84 | |
85 | /// Run the dependency scanning tool for a given clang driver command-line, |
86 | /// and report the discovered dependencies to the provided consumer. If \p |
87 | /// ModuleName isn't empty, this function reports the dependencies of module |
88 | /// \p ModuleName. |
89 | /// |
90 | /// \returns false if clang errors occurred (with diagnostics reported to |
91 | /// \c DiagConsumer), true otherwise. |
92 | bool computeDependencies(StringRef WorkingDirectory, |
93 | const std::vector<std::string> &CommandLine, |
94 | DependencyConsumer &DepConsumer, |
95 | DependencyActionController &Controller, |
96 | DiagnosticConsumer &DiagConsumer, |
97 | std::optional<StringRef> ModuleName = std::nullopt); |
98 | /// \returns A \c StringError with the diagnostic output if clang errors |
99 | /// occurred, success otherwise. |
100 | llvm::Error computeDependencies( |
101 | StringRef WorkingDirectory, const std::vector<std::string> &CommandLine, |
102 | DependencyConsumer &Consumer, DependencyActionController &Controller, |
103 | std::optional<StringRef> ModuleName = std::nullopt); |
104 | |
105 | bool shouldEagerLoadModules() const { return EagerLoadModules; } |
106 | |
107 | private: |
108 | std::shared_ptr<PCHContainerOperations> PCHContainerOps; |
109 | /// The file system to be used during the scan. |
110 | /// This is either \c FS passed in the constructor (when performing canonical |
111 | /// preprocessing), or \c DepFS (when performing dependency directives scan). |
112 | llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS; |
113 | /// When performing dependency directives scan, this is the caching (and |
114 | /// dependency-directives-extracting) filesystem overlaid on top of \c FS |
115 | /// (passed in the constructor). |
116 | llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS; |
117 | ScanningOutputFormat Format; |
118 | /// Whether to optimize the modules' command-line arguments. |
119 | ScanningOptimizations OptimizeArgs; |
120 | /// Whether to set up command-lines to load PCM files eagerly. |
121 | bool EagerLoadModules; |
122 | }; |
123 | |
124 | } // end namespace dependencies |
125 | } // end namespace tooling |
126 | } // end namespace clang |
127 | |
128 | #endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGWORKER_H |
129 | |