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