Index: cfe/trunk/lib/Tooling/Tooling.cpp =================================================================== --- cfe/trunk/lib/Tooling/Tooling.cpp +++ cfe/trunk/lib/Tooling/Tooling.cpp @@ -338,17 +338,22 @@ 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 @@ 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"; }); Index: cfe/trunk/test/Tooling/clang-check-builtin-headers.cpp =================================================================== --- cfe/trunk/test/Tooling/clang-check-builtin-headers.cpp +++ cfe/trunk/test/Tooling/clang-check-builtin-headers.cpp @@ -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 // CHECK: C++ requires +// CHECK-NOHDR: fatal error: 'stddef.h' file not invalid;