diff --git a/clang/test/Index/record-completion-invocation.c b/clang/test/Index/record-completion-invocation.c --- a/clang/test/Index/record-completion-invocation.c +++ b/clang/test/Index/record-completion-invocation.c @@ -8,4 +8,4 @@ // RUN: env LIBCLANG_DISABLE_CRASH_RECOVERY=1 CINDEXTEST_INVOCATION_EMISSION_PATH=%t not --crash c-index-test -code-completion-at=%s:10:1 "-remap-file=%s,%S/Inputs/record-parsing-invocation-remap.c" %s // RUN: cat %t/libclang-* | FileCheck %s -// CHECK: {"toolchain":"{{.*}}","libclang.operation":"complete","libclang.opts":1,"args":["clang","-fno-spell-checking","{{.*}}record-completion-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"],"invocation-args":["-code-completion-at={{.*}}record-completion-invocation.c:10:1"],"unsaved_file_hashes":[{"name":"{{.*}}record-completion-invocation.c","md5":"aee23773de90e665992b48209351d70e"}]} +// CHECK: {"toolchain":"{{.*}}","libclang.operation":"complete","libclang.opts":1,"args":["{{.*}}clang","-fno-spell-checking","{{.*}}record-completion-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"],"invocation-args":["-code-completion-at={{.*}}record-completion-invocation.c:10:1"],"unsaved_file_hashes":[{"name":"{{.*}}record-completion-invocation.c","md5":"aee23773de90e665992b48209351d70e"}]} diff --git a/clang/test/Index/record-parsing-invocation.c b/clang/test/Index/record-parsing-invocation.c --- a/clang/test/Index/record-parsing-invocation.c +++ b/clang/test/Index/record-parsing-invocation.c @@ -24,5 +24,5 @@ # pragma clang __debug parser_crash #endif -// CHECK: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"]} -// CHECK-UNSAVED: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"],"unsaved_file_hashes":[{"name":"{{.*}}record-parsing-invocation.c","md5":"aee23773de90e665992b48209351d70e"}]} +// CHECK: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["{{.*}}clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"]} +// CHECK-UNSAVED: {"toolchain":"{{.*}}","libclang.operation":"parse","libclang.opts":1,"args":["{{.*}}clang","-fno-spell-checking","{{.*}}record-parsing-invocation.c","-Xclang","-detailed-preprocessing-record","-fallow-editor-placeholders"],"unsaved_file_hashes":[{"name":"{{.*}}record-parsing-invocation.c","md5":"aee23773de90e665992b48209351d70e"}]} diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp --- a/clang/tools/libclang/CIndex.cpp +++ b/clang/tools/libclang/CIndex.cpp @@ -3543,12 +3543,15 @@ const char *const *command_line_args, int num_command_line_args, struct CXUnsavedFile *unsaved_files, unsigned num_unsaved_files, unsigned options, CXTranslationUnit *out_TU) { + if (!CIdx) + return CXError_InvalidArguments; SmallVector Args; - Args.push_back("clang"); + Args.push_back(static_cast(CIdx)->getClangBinaryPath().c_str()); Args.append(command_line_args, command_line_args + num_command_line_args); - return clang_parseTranslationUnit2FullArgv( + CXErrorCode Ret = clang_parseTranslationUnit2FullArgv( CIdx, source_filename, Args.data(), Args.size(), unsaved_files, num_unsaved_files, options, out_TU); + return Ret; } enum CXErrorCode clang_parseTranslationUnit2FullArgv( diff --git a/clang/tools/libclang/CIndexer.h b/clang/tools/libclang/CIndexer.h --- a/clang/tools/libclang/CIndexer.h +++ b/clang/tools/libclang/CIndexer.h @@ -41,6 +41,7 @@ std::shared_ptr PCHContainerOps; std::string ToolchainPath; + std::string ClangBinaryPath; std::string InvocationEmissionPath; @@ -56,7 +57,7 @@ /// declarations. bool getOnlyLocalDecls() const { return OnlyLocalDecls; } void setOnlyLocalDecls(bool Local = true) { OnlyLocalDecls = Local; } - + bool getDisplayDiagnostics() const { return DisplayDiagnostics; } void setDisplayDiagnostics(bool Display = true) { DisplayDiagnostics = Display; @@ -78,6 +79,9 @@ StringRef getClangToolchainPath(); + /// Returns /bin/clang. + const std::string &getClangBinaryPath(); + void setInvocationEmissionPath(StringRef Str) { InvocationEmissionPath = Str; } diff --git a/clang/tools/libclang/CIndexer.cpp b/clang/tools/libclang/CIndexer.cpp --- a/clang/tools/libclang/CIndexer.cpp +++ b/clang/tools/libclang/CIndexer.cpp @@ -88,6 +88,15 @@ return ToolchainPath; } +const std::string &CIndexer::getClangBinaryPath() { + if (!ClangBinaryPath.empty()) + return ClangBinaryPath; + llvm::SmallString<128> Path; + llvm::sys::path::append(Path, getClangToolchainPath(), "bin", "clang"); + ClangBinaryPath = Path.str(); + return ClangBinaryPath; +} + LibclangInvocationReporter::LibclangInvocationReporter( CIndexer &Idx, OperationKind Op, unsigned ParseOptions, llvm::ArrayRef Args,