From: Alex Lorenz Date: Thu, 7 Dec 2017 20:37:50 +0000 (+0000) Subject: [libclang] Record code-completion invocations to a temporary file when X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8c8d967b8ab952e6072fb9aeea995fb87dd3a806;p=clang [libclang] Record code-completion invocations to a temporary file when requested by client This is a follow up to r319702 which records parsing invocations. These files are not emitted by default, and the client has to specify the invocation emission path first. rdar://35322543 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@320085 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/Index/record-completion-invocation.c b/test/Index/record-completion-invocation.c new file mode 100644 index 0000000000..c249565a4b --- /dev/null +++ b/test/Index/record-completion-invocation.c @@ -0,0 +1,11 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: env CINDEXTEST_INVOCATION_EMISSION_PATH=%t not 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 + +// RUN: rm -rf %t +// RUN: mkdir %t +// 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"}]} diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c index 6cb67e1030..91afbe219a 100644 --- a/tools/c-index-test/c-index-test.c +++ b/tools/c-index-test/c-index-test.c @@ -2316,7 +2316,8 @@ int perform_code_completion(int argc, const char **argv, int timing_only) { CXTranslationUnit TU; unsigned I, Repeats = 1; unsigned completionOptions = clang_defaultCodeCompleteOptions(); - + const char *InvocationPath; + if (getenv("CINDEXTEST_CODE_COMPLETE_PATTERNS")) completionOptions |= CXCodeComplete_IncludeCodePatterns; if (getenv("CINDEXTEST_COMPLETION_BRIEF_COMMENTS")) @@ -2335,7 +2336,10 @@ int perform_code_completion(int argc, const char **argv, int timing_only) { return -1; CIdx = clang_createIndex(0, 0); - + InvocationPath = getenv("CINDEXTEST_INVOCATION_EMISSION_PATH"); + if (InvocationPath) + clang_CXIndex_setInvocationEmissionPathOption(CIdx, InvocationPath); + if (getenv("CINDEXTEST_EDITING")) Repeats = 5; diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp index 49a1726ac5..656df9b09b 100644 --- a/tools/libclang/CIndex.cpp +++ b/tools/libclang/CIndex.cpp @@ -81,6 +81,8 @@ CXTranslationUnit cxtu::MakeCXTranslationUnit(CIndexer *CIdx, D->Diagnostics = nullptr; D->OverridenCursorsPool = createOverridenCXCursorsPool(); D->CommentToXML = nullptr; + D->ParsingOptions = 0; + D->Arguments = {}; return D; } @@ -3440,7 +3442,8 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename, LibclangInvocationReporter InvocationReporter( *CXXIdx, LibclangInvocationReporter::OperationKind::ParseOperation, - options, llvm::makeArrayRef(*Args), unsaved_files); + options, llvm::makeArrayRef(*Args), /*InvocationArgs=*/None, + unsaved_files); std::unique_ptr Unit(ASTUnit::LoadFromCommandLine( Args->data(), Args->data() + Args->size(), CXXIdx->getPCHContainerOperations(), Diags, @@ -3467,7 +3470,14 @@ clang_parseTranslationUnit_Impl(CXIndex CIdx, const char *source_filename, return CXError_ASTReadError; *out_TU = MakeCXTranslationUnit(CXXIdx, std::move(Unit)); - return *out_TU ? CXError_Success : CXError_Failure; + if (CXTranslationUnitImpl *TU = *out_TU) { + TU->ParsingOptions = options; + TU->Arguments.reserve(Args->size()); + for (const char *Arg : *Args) + TU->Arguments.push_back(Arg); + return CXError_Success; + } + return CXError_Failure; } CXTranslationUnit diff --git a/tools/libclang/CIndexCodeCompletion.cpp b/tools/libclang/CIndexCodeCompletion.cpp index 2f32dc24e5..d4af0870c0 100644 --- a/tools/libclang/CIndexCodeCompletion.cpp +++ b/tools/libclang/CIndexCodeCompletion.cpp @@ -32,6 +32,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/CrashRecoveryContext.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/FormatVariadic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Program.h" #include "llvm/Support/Timer.h" @@ -691,6 +692,16 @@ clang_codeCompleteAt_Impl(CXTranslationUnit TU, const char *complete_filename, CaptureCompletionResults Capture(Opts, *Results, &TU); // Perform completion. + std::vector CArgs; + for (const auto &Arg : TU->Arguments) + CArgs.push_back(Arg.c_str()); + std::string CompletionInvocation = + llvm::formatv("-code-completion-at={0}:{1}:{2}", complete_filename, + complete_line, complete_column) + .str(); + LibclangInvocationReporter InvocationReporter( + *CXXIdx, LibclangInvocationReporter::OperationKind::CompletionOperation, + TU->ParsingOptions, CArgs, CompletionInvocation, unsaved_files); AST->CodeComplete(complete_filename, complete_line, complete_column, RemappedFiles, (options & CXCodeComplete_IncludeMacros), (options & CXCodeComplete_IncludeCodePatterns), diff --git a/tools/libclang/CIndexer.cpp b/tools/libclang/CIndexer.cpp index b705016251..62ea881720 100644 --- a/tools/libclang/CIndexer.cpp +++ b/tools/libclang/CIndexer.cpp @@ -93,6 +93,7 @@ StringRef CIndexer::getClangToolchainPath() { LibclangInvocationReporter::LibclangInvocationReporter( CIndexer &Idx, OperationKind Op, unsigned ParseOptions, llvm::ArrayRef Args, + llvm::ArrayRef InvocationArgs, llvm::ArrayRef UnsavedFiles) { StringRef Path = Idx.getInvocationEmissionPath(); if (Path.empty()) @@ -127,6 +128,14 @@ LibclangInvocationReporter::LibclangInvocationReporter( OS << ','; OS << '"' << I.value() << '"'; } + if (!InvocationArgs.empty()) { + OS << R"(],"invocation-args":[)"; + for (const auto &I : llvm::enumerate(InvocationArgs)) { + if (I.index()) + OS << ','; + OS << '"' << I.value() << '"'; + } + } if (!UnsavedFiles.empty()) { OS << R"(],"unsaved_file_hashes":[)"; for (const auto &UF : llvm::enumerate(UnsavedFiles)) { diff --git a/tools/libclang/CIndexer.h b/tools/libclang/CIndexer.h index dafbb08cfa..6c46eed4fb 100644 --- a/tools/libclang/CIndexer.h +++ b/tools/libclang/CIndexer.h @@ -95,6 +95,7 @@ public: LibclangInvocationReporter(CIndexer &Idx, OperationKind Op, unsigned ParseOptions, llvm::ArrayRef Args, + llvm::ArrayRef InvocationArgs, llvm::ArrayRef UnsavedFiles); ~LibclangInvocationReporter(); diff --git a/tools/libclang/CXTranslationUnit.h b/tools/libclang/CXTranslationUnit.h index ce8469b501..590142f30f 100644 --- a/tools/libclang/CXTranslationUnit.h +++ b/tools/libclang/CXTranslationUnit.h @@ -33,6 +33,8 @@ struct CXTranslationUnitImpl { void *Diagnostics; void *OverridenCursorsPool; clang::index::CommentToXMLConverter *CommentToXML; + unsigned ParsingOptions; + std::vector Arguments; }; struct CXTargetInfoImpl {