clang  19.0.0git
DependencyScanningTool.h
Go to the documentation of this file.
1 //===- DependencyScanningTool.h - clang-scan-deps service -----------------===//
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_DEPENDENCYSCANNINGTOOL_H
10 #define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H
11 
16 #include "llvm/ADT/DenseSet.h"
17 #include "llvm/ADT/MapVector.h"
18 #include <optional>
19 #include <string>
20 #include <vector>
21 
22 namespace clang {
23 namespace tooling {
24 namespace dependencies {
25 
26 /// A callback to lookup module outputs for "-fmodule-file=", "-o" etc.
28  llvm::function_ref<std::string(const ModuleID &, ModuleOutputKind)>;
29 
30 /// Graph of modular dependencies.
31 using ModuleDepsGraph = std::vector<ModuleDeps>;
32 
33 /// The full dependencies and module graph for a specific input.
35  /// The graph of direct and transitive modular dependencies.
37 
38  /// The identifier of the C++20 module this translation unit exports.
39  ///
40  /// If the translation unit is not a module then \c ID.ModuleName is empty.
42 
43  /// A collection of absolute paths to files that this translation unit
44  /// directly depends on, not including transitive dependencies.
45  std::vector<std::string> FileDeps;
46 
47  /// A collection of prebuilt modules this translation unit directly depends
48  /// on, not including transitive dependencies.
49  std::vector<PrebuiltModuleDep> PrebuiltModuleDeps;
50 
51  /// A list of modules this translation unit directly depends on, not including
52  /// transitive dependencies.
53  ///
54  /// This may include modules with a different context hash when it can be
55  /// determined that the differences are benign for this compilation.
56  std::vector<ModuleID> ClangModuleDeps;
57 
58  /// The sequence of commands required to build the translation unit. Commands
59  /// should be executed in order.
60  ///
61  /// FIXME: If we add support for multi-arch builds in clang-scan-deps, we
62  /// should make the dependencies between commands explicit to enable parallel
63  /// builds of each architecture.
64  std::vector<Command> Commands;
65 
66  /// Deprecated driver command-line. This will be removed in a future version.
67  std::vector<std::string> DriverCommandLine;
68 };
69 
70 struct P1689Rule {
71  std::string PrimaryOutput;
72  std::optional<P1689ModuleInfo> Provides;
73  std::vector<P1689ModuleInfo> Requires;
74 };
75 
76 /// The high-level implementation of the dependency discovery tool that runs on
77 /// an individual worker thread.
79 public:
80  /// Construct a dependency scanning tool.
83  llvm::vfs::createPhysicalFileSystem());
84 
85  /// Print out the dependency information into a string using the dependency
86  /// file format that is specified in the options (-MD is the default) and
87  /// return it.
88  ///
89  /// \returns A \c StringError with the diagnostic output if clang errors
90  /// occurred, dependency file contents otherwise.
92  getDependencyFile(const std::vector<std::string> &CommandLine, StringRef CWD);
93 
94  /// Collect the module dependency in P1689 format for C++20 named modules.
95  ///
96  /// \param MakeformatOutput The output parameter for dependency information
97  /// in make format if the command line requires to generate make-format
98  /// dependency information by `-MD -MF <dep_file>`.
99  ///
100  /// \param MakeformatOutputPath The output parameter for the path to
101  /// \param MakeformatOutput.
102  ///
103  /// \returns A \c StringError with the diagnostic output if clang errors
104  /// occurred, P1689 dependency format rules otherwise.
107  StringRef CWD, std::string &MakeformatOutput,
108  std::string &MakeformatOutputPath);
111  StringRef CWD) {
112  std::string MakeformatOutput;
113  std::string MakeformatOutputPath;
114 
115  return getP1689ModuleDependencyFile(Command, CWD, MakeformatOutput,
116  MakeformatOutputPath);
117  }
118 
119  /// Given a Clang driver command-line for a translation unit, gather the
120  /// modular dependencies and return the information needed for explicit build.
121  ///
122  /// \param AlreadySeen This stores modules which have previously been
123  /// reported. Use the same instance for all calls to this
124  /// function for a single \c DependencyScanningTool in a
125  /// single build. Use a different one for different tools,
126  /// and clear it between builds.
127  /// \param LookupModuleOutput This function is called to fill in
128  /// "-fmodule-file=", "-o" and other output
129  /// arguments for dependencies.
130  ///
131  /// \returns a \c StringError with the diagnostic output if clang errors
132  /// occurred, \c TranslationUnitDeps otherwise.
134  getTranslationUnitDependencies(const std::vector<std::string> &CommandLine,
135  StringRef CWD,
136  const llvm::DenseSet<ModuleID> &AlreadySeen,
137  LookupModuleOutputCallback LookupModuleOutput);
138 
139  /// Given a compilation context specified via the Clang driver command-line,
140  /// gather modular dependencies of module with the given name, and return the
141  /// information needed for explicit build.
143  StringRef ModuleName, const std::vector<std::string> &CommandLine,
144  StringRef CWD, const llvm::DenseSet<ModuleID> &AlreadySeen,
145  LookupModuleOutputCallback LookupModuleOutput);
146 
147 private:
149 };
150 
152 public:
154  : AlreadySeen(AlreadySeen) {}
155 
156  void handleBuildCommand(Command Cmd) override {
157  Commands.push_back(std::move(Cmd));
158  }
159 
161 
162  void handleFileDependency(StringRef File) override {
163  Dependencies.push_back(std::string(File));
164  }
165 
167  PrebuiltModuleDeps.emplace_back(std::move(PMD));
168  }
169 
170  void handleModuleDependency(ModuleDeps MD) override {
171  ClangModuleDeps[MD.ID] = std::move(MD);
172  }
173 
175  DirectModuleDeps.push_back(ID);
176  }
177 
178  void handleContextHash(std::string Hash) override {
179  ContextHash = std::move(Hash);
180  }
181 
184 
185 private:
186  std::vector<std::string> Dependencies;
187  std::vector<PrebuiltModuleDep> PrebuiltModuleDeps;
188  llvm::MapVector<ModuleID, ModuleDeps> ClangModuleDeps;
189  std::vector<ModuleID> DirectModuleDeps;
190  std::vector<Command> Commands;
191  std::string ContextHash;
192  std::vector<std::string> OutputPaths;
193  const llvm::DenseSet<ModuleID> &AlreadySeen;
194 };
195 
196 /// A simple dependency action controller that uses a callback. If no callback
197 /// is provided, it is assumed that looking up module outputs is unreachable.
199 public:
200  virtual ~CallbackActionController();
201 
203  : LookupModuleOutput(std::move(LMO)) {
204  if (!LookupModuleOutput) {
205  LookupModuleOutput = [](const ModuleID &,
206  ModuleOutputKind) -> std::string {
207  llvm::report_fatal_error("unexpected call to lookupModuleOutput");
208  };
209  }
210  }
211 
212  std::string lookupModuleOutput(const ModuleID &ID,
213  ModuleOutputKind Kind) override {
214  return LookupModuleOutput(ID, Kind);
215  }
216 
217 private:
218  LookupModuleOutputCallback LookupModuleOutput;
219 };
220 
221 } // end namespace dependencies
222 } // end namespace tooling
223 } // end namespace clang
224 
225 #endif // LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H
static char ID
Definition: Arena.cpp:183
CompileCommand Cmd
DependencyOutputOptions - Options for controlling the compiler dependency file generation.
A simple dependency action controller that uses a callback.
std::string lookupModuleOutput(const ModuleID &ID, ModuleOutputKind Kind) override
Dependency scanner callbacks that are used during scanning to influence the behaviour of the scan - f...
The dependency scanning service contains shared configuration and state that is used by the individua...
The high-level implementation of the dependency discovery tool that runs on an individual worker thre...
llvm::Expected< P1689Rule > getP1689ModuleDependencyFile(const clang::tooling::CompileCommand &Command, StringRef CWD)
llvm::Expected< P1689Rule > getP1689ModuleDependencyFile(const clang::tooling::CompileCommand &Command, StringRef CWD, std::string &MakeformatOutput, std::string &MakeformatOutputPath)
Collect the module dependency in P1689 format for C++20 named modules.
llvm::Expected< std::string > getDependencyFile(const std::vector< std::string > &CommandLine, StringRef CWD)
Print out the dependency information into a string using the dependency file format that is specified...
llvm::Expected< ModuleDepsGraph > getModuleDependencies(StringRef ModuleName, const std::vector< std::string > &CommandLine, StringRef CWD, const llvm::DenseSet< ModuleID > &AlreadySeen, LookupModuleOutputCallback LookupModuleOutput)
Given a compilation context specified via the Clang driver command-line, gather modular dependencies ...
llvm::Expected< TranslationUnitDeps > getTranslationUnitDependencies(const std::vector< std::string > &CommandLine, StringRef CWD, const llvm::DenseSet< ModuleID > &AlreadySeen, LookupModuleOutputCallback LookupModuleOutput)
Given a Clang driver command-line for a translation unit, gather the modular dependencies and return ...
DependencyScanningTool(DependencyScanningService &Service, llvm::IntrusiveRefCntPtr< llvm::vfs::FileSystem > FS=llvm::vfs::createPhysicalFileSystem())
Construct a dependency scanning tool.
An individual dependency scanning worker that is able to run on its own thread.
FullDependencyConsumer(const llvm::DenseSet< ModuleID > &AlreadySeen)
void handleDependencyOutputOpts(const DependencyOutputOptions &) override
void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) override
ModuleOutputKind
An output from a module compilation, such as the path of the module file.
std::vector< ModuleDeps > ModuleDepsGraph
Graph of modular dependencies.
llvm::function_ref< std::string(const ModuleID &, ModuleOutputKind)> LookupModuleOutputCallback
A callback to lookup module outputs for "-fmodule-file=", "-o" etc.
The JSON file list parser is used to communicate input to InstallAPI.
Definition: Format.h:5433
Specifies the working directory and command of a compilation.
A command-line tool invocation that is part of building a TU.
ModuleID ID
The identifier of the module.
This is used to identify a specific module.
std::vector< P1689ModuleInfo > Requires
std::optional< P1689ModuleInfo > Provides
Modular dependency that has already been built prior to the dependency scan.
The full dependencies and module graph for a specific input.
std::vector< PrebuiltModuleDep > PrebuiltModuleDeps
A collection of prebuilt modules this translation unit directly depends on, not including transitive ...
std::vector< Command > Commands
The sequence of commands required to build the translation unit.
std::vector< std::string > FileDeps
A collection of absolute paths to files that this translation unit directly depends on,...
ModuleDepsGraph ModuleGraph
The graph of direct and transitive modular dependencies.
ModuleID ID
The identifier of the C++20 module this translation unit exports.
std::vector< ModuleID > ClangModuleDeps
A list of modules this translation unit directly depends on, not including transitive dependencies.
std::vector< std::string > DriverCommandLine
Deprecated driver command-line. This will be removed in a future version.