xref: /freebsd/contrib/llvm-project/clang/lib/Tooling/LocateToolCompilationDatabase.cpp (revision 6e516c87b6d779911edde7481d8aef165b837a03)
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 Andric inferToolLocation(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