xref: /llvm-project/clang/lib/Tooling/LocateToolCompilationDatabase.cpp (revision a26ec542371652e1d774696e90016fd5b0b1c191)
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