1*6e516c87SDimitry Andric //===- GuessTargetAndModeCompilationDatabase.cpp --------------------------===// 2*6e516c87SDimitry Andric // 3*6e516c87SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*6e516c87SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*6e516c87SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*6e516c87SDimitry Andric // 7*6e516c87SDimitry Andric //===----------------------------------------------------------------------===// 8*6e516c87SDimitry Andric 9*6e516c87SDimitry Andric #include "clang/Tooling/CompilationDatabase.h" 10*6e516c87SDimitry Andric #include "clang/Tooling/Tooling.h" 11*6e516c87SDimitry Andric #include "llvm/Support/Path.h" 12*6e516c87SDimitry Andric #include "llvm/Support/Program.h" 13*6e516c87SDimitry Andric #include <memory> 14*6e516c87SDimitry Andric 15*6e516c87SDimitry Andric namespace clang { 16*6e516c87SDimitry Andric namespace tooling { 17*6e516c87SDimitry Andric 18*6e516c87SDimitry Andric namespace { 19*6e516c87SDimitry Andric class LocationAdderDatabase : public CompilationDatabase { 20*6e516c87SDimitry Andric public: LocationAdderDatabase(std::unique_ptr<CompilationDatabase> Base)21*6e516c87SDimitry Andric LocationAdderDatabase(std::unique_ptr<CompilationDatabase> Base) 22*6e516c87SDimitry Andric : Base(std::move(Base)) { 23*6e516c87SDimitry Andric assert(this->Base != nullptr); 24*6e516c87SDimitry Andric } 25*6e516c87SDimitry Andric getAllFiles() const26*6e516c87SDimitry Andric std::vector<std::string> getAllFiles() const override { 27*6e516c87SDimitry Andric return Base->getAllFiles(); 28*6e516c87SDimitry Andric } 29*6e516c87SDimitry Andric getAllCompileCommands() const30*6e516c87SDimitry Andric std::vector<CompileCommand> getAllCompileCommands() const override { 31*6e516c87SDimitry Andric return addLocation(Base->getAllCompileCommands()); 32*6e516c87SDimitry Andric } 33*6e516c87SDimitry Andric 34*6e516c87SDimitry Andric std::vector<CompileCommand> getCompileCommands(StringRef FilePath) const35*6e516c87SDimitry Andric getCompileCommands(StringRef FilePath) const override { 36*6e516c87SDimitry Andric return addLocation(Base->getCompileCommands(FilePath)); 37*6e516c87SDimitry Andric } 38*6e516c87SDimitry Andric 39*6e516c87SDimitry Andric private: 40*6e516c87SDimitry Andric std::vector<CompileCommand> addLocation(std::vector<CompileCommand> Cmds) const41*6e516c87SDimitry Andric addLocation(std::vector<CompileCommand> Cmds) const { 42*6e516c87SDimitry Andric for (auto &Cmd : Cmds) { 43*6e516c87SDimitry Andric if (Cmd.CommandLine.empty()) 44*6e516c87SDimitry Andric continue; 45*6e516c87SDimitry Andric std::string &Driver = Cmd.CommandLine.front(); 46*6e516c87SDimitry Andric // If the driver name already is absolute, we don't need to do anything. 47*6e516c87SDimitry Andric if (llvm::sys::path::is_absolute(Driver)) 48*6e516c87SDimitry Andric continue; 49*6e516c87SDimitry Andric // If the name is a relative path, like bin/clang, we assume it's 50*6e516c87SDimitry Andric // possible to resolve it and don't do anything about it either. 51*6e516c87SDimitry Andric if (llvm::any_of(Driver, 52*6e516c87SDimitry Andric [](char C) { return llvm::sys::path::is_separator(C); })) 53*6e516c87SDimitry Andric continue; 54*6e516c87SDimitry Andric auto Absolute = llvm::sys::findProgramByName(Driver); 55*6e516c87SDimitry Andric // If we found it in path, update the entry in Cmd.CommandLine 56*6e516c87SDimitry Andric if (Absolute && llvm::sys::path::is_absolute(*Absolute)) 57*6e516c87SDimitry Andric Driver = std::move(*Absolute); 58*6e516c87SDimitry Andric } 59*6e516c87SDimitry Andric return Cmds; 60*6e516c87SDimitry Andric } 61*6e516c87SDimitry Andric std::unique_ptr<CompilationDatabase> Base; 62*6e516c87SDimitry Andric }; 63*6e516c87SDimitry Andric } // namespace 64*6e516c87SDimitry Andric 65*6e516c87SDimitry Andric std::unique_ptr<CompilationDatabase> inferToolLocation(std::unique_ptr<CompilationDatabase> Base)66*6e516c87SDimitry AndricinferToolLocation(std::unique_ptr<CompilationDatabase> Base) { 67*6e516c87SDimitry Andric return std::make_unique<LocationAdderDatabase>(std::move(Base)); 68*6e516c87SDimitry Andric } 69*6e516c87SDimitry Andric 70*6e516c87SDimitry Andric } // namespace tooling 71*6e516c87SDimitry Andric } // namespace clang 72