phosek created this revision. phosek added reviewers: ilya-biryukov, sammccall, bkramer, echristo. Herald added subscribers: cfe-commits, kadircet. Herald added a project: clang.
Args[0] isn't necessarily a correct path, it may not even be the path to the compiler, for example when using tools like ccache, distcc or goma the first argument in command recorded inside the compilation database would be this tool, not the compiler. This path is then used as installation dir inside the driver and is then used to derive other toolchain specific paths, such as path to libc++ headers (which would be ../include/c++/v1 relative to the compiler binary). When the first argument is another tool, or even if it's Clang but the compilation database contains a relative path, the installation dir is going to be incorrect and the header resolution will fail which breaks tools like clangd. So rather than relying blindly on the first argument, we'll use the executable path (when available) instead. Repository: rC Clang https://reviews.llvm.org/D63092 Files: clang/lib/Frontend/CreateInvocationFromCommandLine.cpp clang/unittests/libclang/LibclangTest.cpp Index: clang/unittests/libclang/LibclangTest.cpp =================================================================== --- clang/unittests/libclang/LibclangTest.cpp +++ clang/unittests/libclang/LibclangTest.cpp @@ -621,7 +621,10 @@ std::string Clang = "bin/clang"; WriteFile(Clang, ""); + std::string InstalledDir = TestDir + "/bin"; + const char *Argv[] = {Clang.c_str(), "-target", "arm-linux-gnueabi", + "-ccc-install-dir", InstalledDir.c_str(), "-stdlib=libstdc++", "--gcc-toolchain="}; EXPECT_EQ(CXError_Success, Index: clang/lib/Frontend/CreateInvocationFromCommandLine.cpp =================================================================== --- clang/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ clang/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -43,8 +43,12 @@ // FIXME: Find a cleaner way to force the driver into restricted modes. Args.push_back("-fsyntax-only"); + void *P = reinterpret_cast<void*>(createInvocationFromCommandLine); + std::string ClangExecutable = + llvm::sys::fs::getMainExecutable(Args[0], P); + // FIXME: We shouldn't have to pass in the path info. - driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(), + driver::Driver TheDriver(ClangExecutable, llvm::sys::getDefaultTargetTriple(), *Diags, VFS); // Don't check that inputs exist, they may have been remapped.
Index: clang/unittests/libclang/LibclangTest.cpp =================================================================== --- clang/unittests/libclang/LibclangTest.cpp +++ clang/unittests/libclang/LibclangTest.cpp @@ -621,7 +621,10 @@ std::string Clang = "bin/clang"; WriteFile(Clang, ""); + std::string InstalledDir = TestDir + "/bin"; + const char *Argv[] = {Clang.c_str(), "-target", "arm-linux-gnueabi", + "-ccc-install-dir", InstalledDir.c_str(), "-stdlib=libstdc++", "--gcc-toolchain="}; EXPECT_EQ(CXError_Success, Index: clang/lib/Frontend/CreateInvocationFromCommandLine.cpp =================================================================== --- clang/lib/Frontend/CreateInvocationFromCommandLine.cpp +++ clang/lib/Frontend/CreateInvocationFromCommandLine.cpp @@ -43,8 +43,12 @@ // FIXME: Find a cleaner way to force the driver into restricted modes. Args.push_back("-fsyntax-only"); + void *P = reinterpret_cast<void*>(createInvocationFromCommandLine); + std::string ClangExecutable = + llvm::sys::fs::getMainExecutable(Args[0], P); + // FIXME: We shouldn't have to pass in the path info. - driver::Driver TheDriver(Args[0], llvm::sys::getDefaultTargetTriple(), + driver::Driver TheDriver(ClangExecutable, llvm::sys::getDefaultTargetTriple(), *Diags, VFS); // Don't check that inputs exist, they may have been remapped.
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits