File indexing completed on 2026-05-10 08:37:11
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H
0010 #define LLVM_CLANG_TOOLING_DEPENDENCYSCANNING_DEPENDENCYSCANNINGTOOL_H
0011
0012 #include "clang/Tooling/DependencyScanning/DependencyScanningService.h"
0013 #include "clang/Tooling/DependencyScanning/DependencyScanningWorker.h"
0014 #include "clang/Tooling/DependencyScanning/ModuleDepCollector.h"
0015 #include "clang/Tooling/JSONCompilationDatabase.h"
0016 #include "llvm/ADT/DenseSet.h"
0017 #include "llvm/ADT/MapVector.h"
0018 #include <functional>
0019 #include <optional>
0020 #include <string>
0021 #include <vector>
0022
0023 namespace clang {
0024 namespace tooling {
0025 namespace dependencies {
0026
0027
0028 using LookupModuleOutputCallback =
0029 std::function<std::string(const ModuleID &, ModuleOutputKind)>;
0030
0031
0032 using ModuleDepsGraph = std::vector<ModuleDeps>;
0033
0034
0035 struct TranslationUnitDeps {
0036
0037 ModuleDepsGraph ModuleGraph;
0038
0039
0040
0041
0042 ModuleID ID;
0043
0044
0045
0046 std::vector<std::string> FileDeps;
0047
0048
0049
0050 std::vector<PrebuiltModuleDep> PrebuiltModuleDeps;
0051
0052
0053
0054
0055
0056
0057 std::vector<ModuleID> ClangModuleDeps;
0058
0059
0060
0061
0062
0063
0064
0065 std::vector<Command> Commands;
0066
0067
0068 std::vector<std::string> DriverCommandLine;
0069 };
0070
0071 struct P1689Rule {
0072 std::string PrimaryOutput;
0073 std::optional<P1689ModuleInfo> Provides;
0074 std::vector<P1689ModuleInfo> Requires;
0075 };
0076
0077
0078
0079 class DependencyScanningTool {
0080 public:
0081
0082 DependencyScanningTool(DependencyScanningService &Service,
0083 llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS =
0084 llvm::vfs::createPhysicalFileSystem());
0085
0086
0087
0088
0089
0090
0091
0092 llvm::Expected<std::string>
0093 getDependencyFile(const std::vector<std::string> &CommandLine, StringRef CWD);
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 llvm::Expected<P1689Rule>
0107 getP1689ModuleDependencyFile(const clang::tooling::CompileCommand &Command,
0108 StringRef CWD, std::string &MakeformatOutput,
0109 std::string &MakeformatOutputPath);
0110 llvm::Expected<P1689Rule>
0111 getP1689ModuleDependencyFile(const clang::tooling::CompileCommand &Command,
0112 StringRef CWD) {
0113 std::string MakeformatOutput;
0114 std::string MakeformatOutputPath;
0115
0116 return getP1689ModuleDependencyFile(Command, CWD, MakeformatOutput,
0117 MakeformatOutputPath);
0118 }
0119
0120
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134 llvm::Expected<TranslationUnitDeps>
0135 getTranslationUnitDependencies(const std::vector<std::string> &CommandLine,
0136 StringRef CWD,
0137 const llvm::DenseSet<ModuleID> &AlreadySeen,
0138 LookupModuleOutputCallback LookupModuleOutput);
0139
0140
0141
0142
0143 llvm::Expected<ModuleDepsGraph> getModuleDependencies(
0144 StringRef ModuleName, const std::vector<std::string> &CommandLine,
0145 StringRef CWD, const llvm::DenseSet<ModuleID> &AlreadySeen,
0146 LookupModuleOutputCallback LookupModuleOutput);
0147
0148 llvm::vfs::FileSystem &getWorkerVFS() const { return Worker.getVFS(); }
0149
0150 private:
0151 DependencyScanningWorker Worker;
0152 };
0153
0154 class FullDependencyConsumer : public DependencyConsumer {
0155 public:
0156 FullDependencyConsumer(const llvm::DenseSet<ModuleID> &AlreadySeen)
0157 : AlreadySeen(AlreadySeen) {}
0158
0159 void handleBuildCommand(Command Cmd) override {
0160 Commands.push_back(std::move(Cmd));
0161 }
0162
0163 void handleDependencyOutputOpts(const DependencyOutputOptions &) override {}
0164
0165 void handleFileDependency(StringRef File) override {
0166 Dependencies.push_back(std::string(File));
0167 }
0168
0169 void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD) override {
0170 PrebuiltModuleDeps.emplace_back(std::move(PMD));
0171 }
0172
0173 void handleModuleDependency(ModuleDeps MD) override {
0174 ClangModuleDeps[MD.ID] = std::move(MD);
0175 }
0176
0177 void handleDirectModuleDependency(ModuleID ID) override {
0178 DirectModuleDeps.push_back(ID);
0179 }
0180
0181 void handleContextHash(std::string Hash) override {
0182 ContextHash = std::move(Hash);
0183 }
0184
0185 TranslationUnitDeps takeTranslationUnitDeps();
0186 ModuleDepsGraph takeModuleGraphDeps();
0187
0188 private:
0189 std::vector<std::string> Dependencies;
0190 std::vector<PrebuiltModuleDep> PrebuiltModuleDeps;
0191 llvm::MapVector<ModuleID, ModuleDeps> ClangModuleDeps;
0192 std::vector<ModuleID> DirectModuleDeps;
0193 std::vector<Command> Commands;
0194 std::string ContextHash;
0195 std::vector<std::string> OutputPaths;
0196 const llvm::DenseSet<ModuleID> &AlreadySeen;
0197 };
0198
0199
0200
0201 class CallbackActionController : public DependencyActionController {
0202 public:
0203 virtual ~CallbackActionController();
0204
0205 CallbackActionController(LookupModuleOutputCallback LMO)
0206 : LookupModuleOutput(std::move(LMO)) {
0207 if (!LookupModuleOutput) {
0208 LookupModuleOutput = [](const ModuleID &,
0209 ModuleOutputKind) -> std::string {
0210 llvm::report_fatal_error("unexpected call to lookupModuleOutput");
0211 };
0212 }
0213 }
0214
0215 std::string lookupModuleOutput(const ModuleID &ID,
0216 ModuleOutputKind Kind) override {
0217 return LookupModuleOutput(ID, Kind);
0218 }
0219
0220 private:
0221 LookupModuleOutputCallback LookupModuleOutput;
0222 };
0223
0224 }
0225 }
0226 }
0227
0228 #endif