xref: /freebsd/contrib/llvm-project/clang/lib/Tooling/DependencyScanning/DependencyScanningTool.cpp (revision a7dea1671b87c07d2d266f836bfa8b58efc7c134)
1*a7dea167SDimitry Andric //===- DependencyScanningTool.cpp - clang-scan-deps service ------------===//
2*a7dea167SDimitry Andric //
3*a7dea167SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*a7dea167SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*a7dea167SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*a7dea167SDimitry Andric //
7*a7dea167SDimitry Andric //===----------------------------------------------------------------------===//
8*a7dea167SDimitry Andric 
9*a7dea167SDimitry Andric #include "clang/Tooling/DependencyScanning/DependencyScanningTool.h"
10*a7dea167SDimitry Andric #include "clang/Frontend/Utils.h"
11*a7dea167SDimitry Andric 
12*a7dea167SDimitry Andric namespace clang{
13*a7dea167SDimitry Andric namespace tooling{
14*a7dea167SDimitry Andric namespace dependencies{
15*a7dea167SDimitry Andric 
16*a7dea167SDimitry Andric DependencyScanningTool::DependencyScanningTool(DependencyScanningService &Service,
17*a7dea167SDimitry Andric const tooling::CompilationDatabase &Compilations) : Worker(Service), Compilations(Compilations) {}
18*a7dea167SDimitry Andric 
19*a7dea167SDimitry Andric llvm::Expected<std::string> DependencyScanningTool::getDependencyFile(const std::string &Input,
20*a7dea167SDimitry Andric                                               StringRef CWD) {
21*a7dea167SDimitry Andric   /// Prints out all of the gathered dependencies into a string.
22*a7dea167SDimitry Andric   class DependencyPrinterConsumer : public DependencyConsumer {
23*a7dea167SDimitry Andric   public:
24*a7dea167SDimitry Andric     void handleFileDependency(const DependencyOutputOptions &Opts,
25*a7dea167SDimitry Andric                               StringRef File) override {
26*a7dea167SDimitry Andric       if (!this->Opts)
27*a7dea167SDimitry Andric         this->Opts = std::make_unique<DependencyOutputOptions>(Opts);
28*a7dea167SDimitry Andric       Dependencies.push_back(File);
29*a7dea167SDimitry Andric     }
30*a7dea167SDimitry Andric 
31*a7dea167SDimitry Andric     void printDependencies(std::string &S) {
32*a7dea167SDimitry Andric       if (!Opts)
33*a7dea167SDimitry Andric         return;
34*a7dea167SDimitry Andric 
35*a7dea167SDimitry Andric       class DependencyPrinter : public DependencyFileGenerator {
36*a7dea167SDimitry Andric       public:
37*a7dea167SDimitry Andric         DependencyPrinter(DependencyOutputOptions &Opts,
38*a7dea167SDimitry Andric                           ArrayRef<std::string> Dependencies)
39*a7dea167SDimitry Andric             : DependencyFileGenerator(Opts) {
40*a7dea167SDimitry Andric           for (const auto &Dep : Dependencies)
41*a7dea167SDimitry Andric             addDependency(Dep);
42*a7dea167SDimitry Andric         }
43*a7dea167SDimitry Andric 
44*a7dea167SDimitry Andric         void printDependencies(std::string &S) {
45*a7dea167SDimitry Andric           llvm::raw_string_ostream OS(S);
46*a7dea167SDimitry Andric           outputDependencyFile(OS);
47*a7dea167SDimitry Andric         }
48*a7dea167SDimitry Andric       };
49*a7dea167SDimitry Andric 
50*a7dea167SDimitry Andric       DependencyPrinter Generator(*Opts, Dependencies);
51*a7dea167SDimitry Andric       Generator.printDependencies(S);
52*a7dea167SDimitry Andric     }
53*a7dea167SDimitry Andric 
54*a7dea167SDimitry Andric   private:
55*a7dea167SDimitry Andric     std::unique_ptr<DependencyOutputOptions> Opts;
56*a7dea167SDimitry Andric     std::vector<std::string> Dependencies;
57*a7dea167SDimitry Andric   };
58*a7dea167SDimitry Andric 
59*a7dea167SDimitry Andric   DependencyPrinterConsumer Consumer;
60*a7dea167SDimitry Andric   auto Result =
61*a7dea167SDimitry Andric       Worker.computeDependencies(Input, CWD, Compilations, Consumer);
62*a7dea167SDimitry Andric   if (Result)
63*a7dea167SDimitry Andric     return std::move(Result);
64*a7dea167SDimitry Andric   std::string Output;
65*a7dea167SDimitry Andric   Consumer.printDependencies(Output);
66*a7dea167SDimitry Andric   return Output;
67*a7dea167SDimitry Andric }
68*a7dea167SDimitry Andric 
69*a7dea167SDimitry Andric } // end namespace dependencies
70*a7dea167SDimitry Andric } // end namespace tooling
71*a7dea167SDimitry Andric } // end namespace clang
72