Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions clang/include/clang/Tooling/CompilationDatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,12 @@ std::unique_ptr<CompilationDatabase>
std::unique_ptr<CompilationDatabase>
inferTargetAndDriverMode(std::unique_ptr<CompilationDatabase> Base);

/// Returns a wrapped CompilationDatabase that will transform argv[0] to an
/// absolute path, if it currently is a plain tool name, looking it up in
/// PATH.
std::unique_ptr<CompilationDatabase>
inferToolLocation(std::unique_ptr<CompilationDatabase> Base);

/// Returns a wrapped CompilationDatabase that will expand all rsp(response)
/// files on commandline returned by underlying database.
std::unique_ptr<CompilationDatabase>
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Tooling/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ add_clang_library(clangTooling
GuessTargetAndModeCompilationDatabase.cpp
InterpolatingCompilationDatabase.cpp
JSONCompilationDatabase.cpp
LocateToolCompilationDatabase.cpp
Refactoring.cpp
RefactoringCallbacks.cpp
StandaloneExecution.cpp
Expand Down
71 changes: 71 additions & 0 deletions clang/lib/Tooling/LocateToolCompilationDatabase.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
//===- GuessTargetAndModeCompilationDatabase.cpp --------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/Tooling/CompilationDatabase.h"
#include "clang/Tooling/Tooling.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Program.h"
#include <memory>

namespace clang {
namespace tooling {

namespace {
class LocationAdderDatabase : public CompilationDatabase {
public:
LocationAdderDatabase(std::unique_ptr<CompilationDatabase> Base)
: Base(std::move(Base)) {
assert(this->Base != nullptr);
}

std::vector<std::string> getAllFiles() const override {
return Base->getAllFiles();
}

std::vector<CompileCommand> getAllCompileCommands() const override {
return addLocation(Base->getAllCompileCommands());
}

std::vector<CompileCommand>
getCompileCommands(StringRef FilePath) const override {
return addLocation(Base->getCompileCommands(FilePath));
}

private:
std::vector<CompileCommand>
addLocation(std::vector<CompileCommand> Cmds) const {
for (auto &Cmd : Cmds) {
if (Cmd.CommandLine.empty())
continue;
std::string &Driver = Cmd.CommandLine.front();
// If the driver name already is absolute, we don't need to do anything.
if (llvm::sys::path::is_absolute(Driver))
continue;
// If the name is a relative path, like bin/clang, we assume it's
// possible to resolve it and don't do anything about it either.
if (llvm::any_of(Driver,
[](char C) { return llvm::sys::path::is_separator(C); }))
continue;
auto Absolute = llvm::sys::findProgramByName(Driver);
// If we found it in path, update the entry in Cmd.CommandLine
if (Absolute && llvm::sys::path::is_absolute(*Absolute))
Driver = std::move(*Absolute);
}
return Cmds;
}
std::unique_ptr<CompilationDatabase> Base;
};
} // namespace

std::unique_ptr<CompilationDatabase>
inferToolLocation(std::unique_ptr<CompilationDatabase> Base) {
return std::make_unique<LocationAdderDatabase>(std::move(Base));
}

} // namespace tooling
} // namespace clang
2 changes: 1 addition & 1 deletion clang/test/ClangScanDeps/modules-extern-submodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ module third {}
// CHECK: "-fmodule-map-file=[[PREFIX]]/first/first/module.modulemap",
// CHECK: "-fmodule-file=first=[[PREFIX]]/cache/{{.*}}/first-{{.*}}.pcm",
// CHECK: ],
// CHECK-NEXT: "executable": "clang",
// CHECK-NEXT: "executable": "{{.*}}clang",
// CHECK-NEXT: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/tu.m"
// CHECK-NEXT: ],
Expand Down
4 changes: 2 additions & 2 deletions clang/test/ClangScanDeps/modules-full-output-tu-order.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
// CHECK: "-D"
// CHECK-NEXT: "ONE"
// CHECK: ],
// CHECK-NEXT: "executable": "clang",
// CHECK-NEXT: "executable": "{{.*}}clang",
// CHECK-NEXT: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/tu.c"
// CHECK-NEXT: ],
Expand All @@ -52,7 +52,7 @@
// CHECK: "-D"
// CHECK-NEXT: "TWO"
// CHECK: ],
// CHECK-NEXT: "executable": "clang",
// CHECK-NEXT: "executable": "{{.*}}clang",
// CHECK-NEXT: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/tu.c"
// CHECK-NEXT: ],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ module Dependency { header "dependency.h" }
// CHECK: ],
// CHECK-NEXT: "command-line": [
// CHECK: ],
// CHECK-NEXT: "executable": "clang",
// CHECK-NEXT: "executable": "{{.*}}clang",
// CHECK-NEXT: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/tu.c"
// CHECK-NEXT: ],
Expand Down
2 changes: 1 addition & 1 deletion clang/test/ClangScanDeps/modules-header-sharing.m
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@
// CHECK: "-fmodule-map-file=[[PREFIX]]/frameworks/A.framework/Modules/module.modulemap",
// CHECK: "-fmodule-name=A",
// CHECK: ],
// CHECK-NEXT: "executable": "clang",
// CHECK-NEXT: "executable": "{{.*}}clang",
// CHECK-NEXT: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/tu.m",
// CHECK-NEXT: "[[PREFIX]]/shared/H.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ framework module FWPrivate { header "private.h" }
// CHECK: "-fmodule-map-file=[[PREFIX]]/frameworks/FW.framework/Modules/module.private.modulemap",
// CHECK: "-fmodule-name=FWPrivate",
// CHECK: ],
// CHECK-NEXT: "executable": "clang",
// CHECK-NEXT: "executable": "{{.*}}clang",
// CHECK-NEXT: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/tu.m"
// CHECK-NEXT: ],
Expand Down
2 changes: 1 addition & 1 deletion clang/test/ClangScanDeps/modules-implementation-private.m
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
// CHECK-NEXT: ],
// CHECK-NEXT: "command-line": [
// CHECK: ],
// CHECK-NEXT: "executable": "clang",
// CHECK-NEXT: "executable": "{{.*}}clang",
// CHECK-NEXT: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/tu.m",
// CHECK-NEXT: "[[PREFIX]]/frameworks/FW.framework/PrivateHeaders/Missed.h",
Expand Down
2 changes: 1 addition & 1 deletion clang/test/ClangScanDeps/modules-priv-fw-from-pub.m
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@
// CHECK-NEXT: ],
// CHECK-NEXT: "command-line": [
// CHECK: ],
// CHECK-NEXT: "executable": "clang",
// CHECK-NEXT: "executable": "{{.*}}clang",
// CHECK-NEXT: "file-deps": [
// CHECK-NEXT: "[[PREFIX]]/tu.m"
// CHECK-NEXT: ],
Expand Down
32 changes: 32 additions & 0 deletions clang/test/ClangScanDeps/resolve-executable-path.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// UNSUPPORTED: system-windows

// Check that we expand the executable name to an absolute path, when invoked
// with a plain executable name, which is implied to be found in PATH.
// REQUIRES: x86-registered-target

// RUN: rm -rf %t
// RUN: mkdir -p %t/bin
// RUN: ln -s %clang %t/bin/x86_64-w64-mingw32-clang
// RUN: split-file %s %t
// RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json

// Check that we can deduce this both when using a compilation database, and when using
// a literal command line.

// RUN: env "PATH=%t/bin:%PATH%" clang-scan-deps -format experimental-full -compilation-database %t/cdb.json | FileCheck %s -DBASE=%/t

// RUN: env "PATH=%t/bin:%PATH%" clang-scan-deps -format experimental-full -- x86_64-w64-mingw32-clang %t/source.c -o %t/source.o | FileCheck %s -DBASE=%/t

// CHECK: "executable": "[[BASE]]/bin/x86_64-w64-mingw32-clang"

//--- cdb.json.in
[
{
"directory": "DIR"
"command": "x86_64-w64-mingw32-clang -c DIR/source.c -o DIR/source.o"
"file": "DIR/source.c"
},
]

//--- source.c
void func(void) {}
2 changes: 2 additions & 0 deletions clang/tools/clang-scan-deps/ClangScanDeps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,8 @@ int clang_scan_deps_main(int argc, char **argv, const llvm::ToolContext &) {

Compilations = inferTargetAndDriverMode(std::move(Compilations));

Compilations = inferToolLocation(std::move(Compilations));

// The command options are rewritten to run Clang in preprocessor only mode.
auto AdjustingCompilations =
std::make_unique<tooling::ArgumentsAdjustingCompilations>(
Expand Down