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