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