[Tooling] Inject -resource-dir instead of overwriting argv[0].

This allows using a different standard library (the one from argv[0] in
the compilation database) with the correct builtins.

Differential Revision: http://reviews.llvm.org/D19356

llvm-svn: 266973
This commit is contained in:
Benjamin Kramer 2016-04-21 10:18:18 +00:00
parent 6a8b91df64
commit b5737c1491
2 changed files with 25 additions and 8 deletions

View File

@ -338,17 +338,22 @@ void ClangTool::clearArgumentsAdjusters() {
ArgsAdjuster = nullptr;
}
static void injectResourceDir(CommandLineArguments &Args, const char *Argv0,
void *MainAddr) {
// Allow users to override the resource dir.
for (StringRef Arg : Args)
if (Arg.startswith("-resource-dir"))
return;
// If there's no override in place add our resource dir.
Args.push_back("-resource-dir=" +
CompilerInvocation::GetResourcesPath(Argv0, MainAddr));
}
int ClangTool::run(ToolAction *Action) {
// Exists solely for the purpose of lookup of the resource path.
// This just needs to be some symbol in the binary.
static int StaticSymbol;
// The driver detects the builtin header path based on the path of the
// executable.
// FIXME: On linux, GetMainExecutable is independent of the value of the
// first argument, thus allowing ClangTool and runToolOnCode to just
// pass in made-up names here. Make sure this works on other platforms.
std::string MainExecutable =
llvm::sys::fs::getMainExecutable("clang_tool", &StaticSymbol);
llvm::SmallString<128> InitialDirectory;
if (std::error_code EC = llvm::sys::fs::current_path(InitialDirectory))
@ -413,7 +418,17 @@ int ClangTool::run(ToolAction *Action) {
if (ArgsAdjuster)
CommandLine = ArgsAdjuster(CommandLine, CompileCommand.Filename);
assert(!CommandLine.empty());
CommandLine[0] = MainExecutable;
// Add the resource dir based on the binary of this tool. argv[0] in the
// compilation database may refer to a different compiler and we want to
// pick up the very same standard library that compiler is using. The
// builtin headers in the resource dir need to match the exact clang
// version the tool is using.
// FIXME: On linux, GetMainExecutable is independent of the value of the
// first argument, thus allowing ClangTool and runToolOnCode to just
// pass in made-up names here. Make sure this works on other platforms.
injectResourceDir(CommandLine, "clang_tool", &StaticSymbol);
// FIXME: We need a callback mechanism for the tool writer to output a
// customized message for each file.
DEBUG({ llvm::dbgs() << "Processing: " << File << ".\n"; });

View File

@ -4,9 +4,11 @@
// RUN: echo '[{"directory":".","command":"/random/tool -c %t/test.cpp","file":"%t/test.cpp"}]' | sed -e 's/\\/\//g' > %t/compile_commands.json
// RUN: cp "%s" "%t/test.cpp"
// RUN: not clang-check -p "%t" "%t/test.cpp" 2>&1|FileCheck %s
// RUN: not clang-check -p "%t" "%t/test.cpp" -extra-arg=-resource-dir=foo 2>&1|FileCheck %s -check-prefix=CHECK-NOHDR
// FIXME: Make the above easier.
#include <stddef.h>
// CHECK: C++ requires
// CHECK-NOHDR: fatal error: 'stddef.h' file not
invalid;