15#include "llvm/ADT/SmallVectorExtras.h"
16#include "llvm/ADT/iterator.h"
17#include "llvm/Support/VirtualFileSystem.h"
18#include "llvm/TargetParser/Host.h"
28 : Worker(Service,
std::move(FS)) {}
34 void handleBuildCommand(
Command)
override {}
38 this->Opts = std::make_unique<DependencyOutputOptions>(Opts);
41 void handleFileDependency(StringRef
File)
override {
42 Dependencies.push_back(std::string(
File));
48 void handlePrebuiltModuleDependency(PrebuiltModuleDep PMD)
override {}
49 void handleModuleDependency(ModuleDeps MD)
override {}
50 void handleDirectModuleDependency(ModuleID ID)
override {}
51 void handleVisibleModule(std::string ModuleName)
override {}
52 void handleContextHash(std::string Hash)
override {}
54 void printDependencies(std::string &S) {
55 assert(Opts &&
"Handled dependency output options.");
57 class DependencyPrinter :
public DependencyFileGenerator {
59 DependencyPrinter(DependencyOutputOptions &Opts,
60 ArrayRef<std::string> Dependencies)
61 : DependencyFileGenerator(Opts) {
62 for (
const auto &Dep : Dependencies)
66 void printDependencies(std::string &S) {
67 llvm::raw_string_ostream
OS(S);
68 outputDependencyFile(OS);
72 DependencyPrinter
Generator(*Opts, Dependencies);
77 std::unique_ptr<DependencyOutputOptions> Opts;
78 std::vector<std::string> Dependencies;
82static std::pair<std::unique_ptr<driver::Driver>,
83 std::unique_ptr<driver::Compilation>>
86 llvm::BumpPtrAllocator &Alloc) {
88 Argv.reserve(ArgStrs.size());
89 for (
const std::string &Arg : ArgStrs)
90 Argv.push_back(Arg.c_str());
92 std::unique_ptr<driver::Driver> Driver = std::make_unique<driver::Driver>(
93 Argv[0], llvm::sys::getDefaultTargetTriple(), Diags,
94 "clang LLVM compiler", FS);
95 Driver->setTitle(
"clang_based_tool");
102 Diags.
Report(diag::err_drv_expand_response_file)
103 << llvm::toString(std::move(E));
104 return std::make_pair(
nullptr,
nullptr);
107 std::unique_ptr<driver::Compilation> Compilation(
108 Driver->BuildCompilation(Argv));
110 return std::make_pair(
nullptr,
nullptr);
112 if (Compilation->containsError())
113 return std::make_pair(
nullptr,
nullptr);
115 if (Compilation->getJobs().empty()) {
116 Diags.
Report(diag::err_fe_expected_compiler_job)
117 << llvm::join(ArgStrs,
" ");
118 return std::make_pair(
nullptr,
nullptr);
121 return std::make_pair(std::move(Driver), std::move(Compilation));
130 Out.reserve(Args.size() + 1);
132 llvm::append_range(Out, Args);
146 FS->setCurrentWorkingDirectory(WorkingDirectory);
152 llvm::BumpPtrAllocator Alloc;
153 auto DiagEngineWithDiagOpts =
156 CommandLine, *DiagEngineWithDiagOpts.DiagEngine, FS, Alloc);
161 for (
const auto &Cmd : Compilation->getJobs())
164 FrontendCommandLines.begin(), FrontendCommandLines.end());
166 return Worker.computeDependencies(WorkingDirectory, FrontendCommandLinesView,
167 Consumer, Controller, DiagConsumer,
173 return llvm::make_error<llvm::StringError>(
174 DiagPrinterWithOS.
DiagnosticsOS.str(), llvm::inconvertibleErrorCode());
182 const auto IsCC1Input = (CommandLine.size() >= 2 && CommandLine[1] ==
"-cc1");
183 return IsCC1Input ?
Worker.computeDependencies(WorkingDirectory, CommandLine,
184 Consumer, Controller,
185 DiagConsumer, OverlayFS)
187 Worker, WorkingDirectory, CommandLine, Consumer,
188 Controller, DiagConsumer, OverlayFS);
191std::optional<std::string>
195 MakeDependencyPrinterConsumer DepConsumer;
201 DepConsumer.printDependencies(Output);
208 class P1689ModuleDependencyPrinterConsumer
209 :
public MakeDependencyPrinterConsumer {
211 P1689ModuleDependencyPrinterConsumer(
P1689Rule &Rule,
213 : Filename(
Command.Filename), Rule(Rule) {
214 Rule.PrimaryOutput =
Command.Output;
217 void handleProvidedAndRequiredStdCXXModules(
218 std::optional<P1689ModuleInfo> Provided,
219 std::vector<P1689ModuleInfo> Requires)
override {
220 Rule.Provides = Provided;
222 Rule.Provides->SourcePath = Filename.str();
223 Rule.Requires = Requires;
226 StringRef getMakeFormatDependencyOutputPath() {
229 return Opts->OutputFile;
240 std::string lookupModuleOutput(
const ModuleDeps &,
247 P1689ModuleDependencyPrinterConsumer Consumer(Rule,
Command);
248 P1689ActionController Controller;
250 Controller, DiagConsumer))
253 MakeformatOutputPath = Consumer.getMakeFormatDependencyOutputPath();
254 if (!MakeformatOutputPath.empty())
255 Consumer.printDependencies(MakeformatOutput);
259std::optional<TranslationUnitDeps>
263 const llvm::DenseSet<ModuleID> &AlreadySeen,
265 std::optional<llvm::MemoryBufferRef> TUBuffer) {
272 std::vector<std::string> CommandLineWithTUBufferInput;
274 std::tie(OverlayFS, CommandLineWithTUBufferInput) =
277 CommandLine = CommandLineWithTUBufferInput;
281 DiagConsumer, OverlayFS))
289 const llvm::DenseSet<ModuleID> &AlreadySeen,
296 ModuleName, AlreadySeen, LookupModuleOutput);
310 llvm::BumpPtrAllocator Alloc;
311 const auto [Driver, Compilation] =
317 return StringRef(Cmd.getCreator().getName()) ==
"clang";
320 const auto &Jobs = Compilation->getJobs();
321 if (
const auto It = llvm::find_if(Jobs, IsClangCmd); It != Jobs.end())
329 if (CommandLine.size() >= 2 && CommandLine[1] ==
"-cc1") {
332 return Worker.initializeCompilerInstanceWithContext(CWD, CommandLine, DC);
339 &Worker.getVFS(), CommandLine, CWD,
"ScanningByName");
340 auto DiagEngineWithCmdAndOpts =
341 std::make_unique<DiagnosticsEngineWithDiagOpts>(ModifiedCommandLine,
345 ModifiedCommandLine, *DiagEngineWithCmdAndOpts->DiagEngine, OverlayFS);
349 return Worker.initializeCompilerInstanceWithContext(
350 CWD, *MaybeFirstCC1, std::move(DiagEngineWithCmdAndOpts), OverlayFS);
357 std::make_unique<TextDiagnosticsPrinterWithOutput>(CommandLine);
360 Worker, CWD, CommandLine, DiagPrinterWithOS->DiagPrinter);
363 return llvm::Error::success();
369 StringRef ModuleName,
const llvm::DenseSet<ModuleID> &AlreadySeen,
373 if (Worker.computeDependenciesByNameWithContext(ModuleName, Consumer,
381 if (Worker.finalizeCompilerInstanceWithContext())
382 return llvm::Error::success();
Defines the Diagnostic-related interfaces.
DependencyOutputOptions - Options for controlling the compiler dependency file generation.
Abstract interface, implemented by clients of the front-end, which formats and prints fully processed...
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
A simple dependency action controller that uses a callback.
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...
An individual dependency scanning worker that is able to run on its own thread.
TranslationUnitDeps takeTranslationUnitDeps()
Command - An executable path/name and argument vector to execute.
const llvm::opt::ArgStringList & getArguments() const
const char * getExecutable() const
llvm::function_ref< std::string(const ModuleDeps &, ModuleOutputKind)> LookupModuleOutputCallback
A callback to lookup module outputs for "-fmodule-file=", "-o" etc.
std::pair< IntrusiveRefCntPtr< llvm::vfs::OverlayFileSystem >, std::vector< std::string > > initVFSForTUBufferScanning(IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS, ArrayRef< std::string > CommandLine, StringRef WorkingDirectory, llvm::MemoryBufferRef TUBuffer)
ModuleOutputKind
An output from a module compilation, such as the path of the module file.
std::pair< IntrusiveRefCntPtr< llvm::vfs::OverlayFileSystem >, std::vector< std::string > > initVFSForByNameScanning(IntrusiveRefCntPtr< llvm::vfs::FileSystem > BaseFS, ArrayRef< std::string > CommandLine, StringRef WorkingDirectory, StringRef ModuleName)
llvm::StringRef getDriverMode(StringRef ProgName, ArrayRef< const char * > Args)
Returns the driver mode option's value, i.e.
llvm::Error expandResponseFiles(SmallVectorImpl< const char * > &Args, bool ClangCLMode, llvm::BumpPtrAllocator &Alloc, llvm::vfs::FileSystem *FS=nullptr)
Expand response files from a clang driver or cc1 invocation.
bool IsClangCL(StringRef DriverMode)
Checks whether the value produced by getDriverMode is for CL mode.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
The JSON file list parser is used to communicate input to InstallAPI.
@ Worker
'worker' clause, allowed on 'loop', Combined, and 'routine' directives.
@ Result
The result type of a method or function.
A command-line tool invocation that is part of building a TU.
llvm::raw_string_ostream DiagnosticsOS