1//===- CIndexCodeCompletion.cpp - Code Completion API hooks ---------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the Clang-C Source Indexing library hooks for
10// code completion.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CIndexDiagnostic.h"
15#include "CIndexer.h"
16#include "CLog.h"
17#include "CXCursor.h"
18#include "CXSourceLocation.h"
19#include "CXString.h"
20#include "CXTranslationUnit.h"
21#include "clang/AST/Decl.h"
22#include "clang/AST/DeclObjC.h"
23#include "clang/AST/Type.h"
24#include "clang/Basic/FileManager.h"
25#include "clang/Basic/SourceManager.h"
26#include "clang/Frontend/ASTUnit.h"
27#include "clang/Frontend/CompilerInstance.h"
28#include "clang/Frontend/FrontendActions.h"
29#include "clang/Sema/CodeCompleteConsumer.h"
30#include "clang/Sema/Sema.h"
31#include "llvm/ADT/SmallString.h"
32#include "llvm/ADT/StringExtras.h"
33#include "llvm/Support/CrashRecoveryContext.h"
34#include "llvm/Support/FileSystem.h"
35#include "llvm/Support/FormatVariadic.h"
36#include "llvm/Support/MemoryBuffer.h"
37#include "llvm/Support/Program.h"
38#include "llvm/Support/Timer.h"
39#include "llvm/Support/raw_ostream.h"
40#include <atomic>
41#include <cstdio>
42#include <cstdlib>
43#include <string>
44
45#ifdef UDP_CODE_COMPLETION_LOGGER
46#include "clang/Basic/Version.h"
47#include <arpa/inet.h>
48#include <sys/socket.h>
49#include <sys/types.h>
50#include <unistd.h>
51#endif
52
53using namespace clang;
54using namespace clang::cxindex;
55
56enum CXCompletionChunkKind
57clang_getCompletionChunkKind(CXCompletionString completion_string,
58 unsigned chunk_number) {
59 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
60 if (!CCStr || chunk_number >= CCStr->size())
61 return CXCompletionChunk_Text;
62
63 switch ((*CCStr)[chunk_number].Kind) {
64 case CodeCompletionString::CK_TypedText:
65 return CXCompletionChunk_TypedText;
66 case CodeCompletionString::CK_Text:
67 return CXCompletionChunk_Text;
68 case CodeCompletionString::CK_Optional:
69 return CXCompletionChunk_Optional;
70 case CodeCompletionString::CK_Placeholder:
71 return CXCompletionChunk_Placeholder;
72 case CodeCompletionString::CK_Informative:
73 return CXCompletionChunk_Informative;
74 case CodeCompletionString::CK_ResultType:
75 return CXCompletionChunk_ResultType;
76 case CodeCompletionString::CK_CurrentParameter:
77 return CXCompletionChunk_CurrentParameter;
78 case CodeCompletionString::CK_LeftParen:
79 return CXCompletionChunk_LeftParen;
80 case CodeCompletionString::CK_RightParen:
81 return CXCompletionChunk_RightParen;
82 case CodeCompletionString::CK_LeftBracket:
83 return CXCompletionChunk_LeftBracket;
84 case CodeCompletionString::CK_RightBracket:
85 return CXCompletionChunk_RightBracket;
86 case CodeCompletionString::CK_LeftBrace:
87 return CXCompletionChunk_LeftBrace;
88 case CodeCompletionString::CK_RightBrace:
89 return CXCompletionChunk_RightBrace;
90 case CodeCompletionString::CK_LeftAngle:
91 return CXCompletionChunk_LeftAngle;
92 case CodeCompletionString::CK_RightAngle:
93 return CXCompletionChunk_RightAngle;
94 case CodeCompletionString::CK_Comma:
95 return CXCompletionChunk_Comma;
96 case CodeCompletionString::CK_Colon:
97 return CXCompletionChunk_Colon;
98 case CodeCompletionString::CK_SemiColon:
99 return CXCompletionChunk_SemiColon;
100 case CodeCompletionString::CK_Equal:
101 return CXCompletionChunk_Equal;
102 case CodeCompletionString::CK_HorizontalSpace:
103 return CXCompletionChunk_HorizontalSpace;
104 case CodeCompletionString::CK_VerticalSpace:
105 return CXCompletionChunk_VerticalSpace;
106 }
107
108 llvm_unreachable("Invalid CompletionKind!");
109}
110
111CXString clang_getCompletionChunkText(CXCompletionString completion_string,
112 unsigned chunk_number) {
113 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
114 if (!CCStr || chunk_number >= CCStr->size())
115 return cxstring::createNull();
116
117 switch ((*CCStr)[chunk_number].Kind) {
118 case CodeCompletionString::CK_TypedText:
119 case CodeCompletionString::CK_Text:
120 case CodeCompletionString::CK_Placeholder:
121 case CodeCompletionString::CK_CurrentParameter:
122 case CodeCompletionString::CK_Informative:
123 case CodeCompletionString::CK_LeftParen:
124 case CodeCompletionString::CK_RightParen:
125 case CodeCompletionString::CK_LeftBracket:
126 case CodeCompletionString::CK_RightBracket:
127 case CodeCompletionString::CK_LeftBrace:
128 case CodeCompletionString::CK_RightBrace:
129 case CodeCompletionString::CK_LeftAngle:
130 case CodeCompletionString::CK_RightAngle:
131 case CodeCompletionString::CK_Comma:
132 case CodeCompletionString::CK_ResultType:
133 case CodeCompletionString::CK_Colon:
134 case CodeCompletionString::CK_SemiColon:
135 case CodeCompletionString::CK_Equal:
136 case CodeCompletionString::CK_HorizontalSpace:
137 case CodeCompletionString::CK_VerticalSpace:
138 return cxstring::createRef(String: (*CCStr)[chunk_number].Text);
139
140 case CodeCompletionString::CK_Optional:
141 // Note: treated as an empty text block.
142 return cxstring::createEmpty();
143 }
144
145 llvm_unreachable("Invalid CodeCompletionString Kind!");
146}
147
148
149CXCompletionString
150clang_getCompletionChunkCompletionString(CXCompletionString completion_string,
151 unsigned chunk_number) {
152 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
153 if (!CCStr || chunk_number >= CCStr->size())
154 return nullptr;
155
156 switch ((*CCStr)[chunk_number].Kind) {
157 case CodeCompletionString::CK_TypedText:
158 case CodeCompletionString::CK_Text:
159 case CodeCompletionString::CK_Placeholder:
160 case CodeCompletionString::CK_CurrentParameter:
161 case CodeCompletionString::CK_Informative:
162 case CodeCompletionString::CK_LeftParen:
163 case CodeCompletionString::CK_RightParen:
164 case CodeCompletionString::CK_LeftBracket:
165 case CodeCompletionString::CK_RightBracket:
166 case CodeCompletionString::CK_LeftBrace:
167 case CodeCompletionString::CK_RightBrace:
168 case CodeCompletionString::CK_LeftAngle:
169 case CodeCompletionString::CK_RightAngle:
170 case CodeCompletionString::CK_Comma:
171 case CodeCompletionString::CK_ResultType:
172 case CodeCompletionString::CK_Colon:
173 case CodeCompletionString::CK_SemiColon:
174 case CodeCompletionString::CK_Equal:
175 case CodeCompletionString::CK_HorizontalSpace:
176 case CodeCompletionString::CK_VerticalSpace:
177 return nullptr;
178
179 case CodeCompletionString::CK_Optional:
180 // Note: treated as an empty text block.
181 return (*CCStr)[chunk_number].Optional;
182 }
183
184 llvm_unreachable("Invalid CompletionKind!");
185}
186
187unsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
188 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
189 return CCStr? CCStr->size() : 0;
190}
191
192unsigned clang_getCompletionPriority(CXCompletionString completion_string) {
193 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
194 return CCStr? CCStr->getPriority() : unsigned(CCP_Unlikely);
195}
196
197enum CXAvailabilityKind
198clang_getCompletionAvailability(CXCompletionString completion_string) {
199 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
200 return CCStr? static_cast<CXAvailabilityKind>(CCStr->getAvailability())
201 : CXAvailability_Available;
202}
203
204unsigned clang_getCompletionNumAnnotations(CXCompletionString completion_string)
205{
206 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
207 return CCStr ? CCStr->getAnnotationCount() : 0;
208}
209
210CXString clang_getCompletionAnnotation(CXCompletionString completion_string,
211 unsigned annotation_number) {
212 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
213 return CCStr ? cxstring::createRef(String: CCStr->getAnnotation(AnnotationNr: annotation_number))
214 : cxstring::createNull();
215}
216
217CXString
218clang_getCompletionParent(CXCompletionString completion_string,
219 CXCursorKind *kind) {
220 if (kind)
221 *kind = CXCursor_NotImplemented;
222
223 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
224 if (!CCStr)
225 return cxstring::createNull();
226
227 return cxstring::createRef(String: CCStr->getParentContextName());
228}
229
230CXString
231clang_getCompletionBriefComment(CXCompletionString completion_string) {
232 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
233
234 if (!CCStr)
235 return cxstring::createNull();
236
237 return cxstring::createRef(String: CCStr->getBriefComment());
238}
239
240namespace {
241
242/// The CXCodeCompleteResults structure we allocate internally;
243/// the client only sees the initial CXCodeCompleteResults structure.
244///
245/// Normally, clients of CXString shouldn't care whether or not a CXString is
246/// managed by a pool or by explicitly malloc'ed memory. But
247/// AllocatedCXCodeCompleteResults outlives the CXTranslationUnit, so we can
248/// not rely on the StringPool in the TU.
249struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
250 AllocatedCXCodeCompleteResults(IntrusiveRefCntPtr<FileManager> FileMgr);
251 ~AllocatedCXCodeCompleteResults();
252
253 /// Diagnostics produced while performing code completion.
254 SmallVector<StoredDiagnostic, 8> Diagnostics;
255
256 /// Allocated API-exposed wrappters for Diagnostics.
257 SmallVector<std::unique_ptr<CXStoredDiagnostic>, 8> DiagnosticsWrappers;
258
259 DiagnosticOptions DiagOpts;
260
261 /// Diag object
262 IntrusiveRefCntPtr<DiagnosticsEngine> Diag;
263
264 /// Language options used to adjust source locations.
265 LangOptions LangOpts;
266
267 /// File manager, used for diagnostics.
268 IntrusiveRefCntPtr<FileManager> FileMgr;
269
270 /// Source manager, used for diagnostics.
271 IntrusiveRefCntPtr<SourceManager> SourceMgr;
272
273 /// Temporary buffers that will be deleted once we have finished with
274 /// the code-completion results.
275 SmallVector<const llvm::MemoryBuffer *, 1> TemporaryBuffers;
276
277 /// Allocator used to store globally cached code-completion results.
278 std::shared_ptr<clang::GlobalCodeCompletionAllocator>
279 CachedCompletionAllocator;
280
281 /// Allocator used to store code completion results.
282 std::shared_ptr<clang::GlobalCodeCompletionAllocator> CodeCompletionAllocator;
283
284 /// Context under which completion occurred.
285 enum clang::CodeCompletionContext::Kind ContextKind;
286
287 /// A bitfield representing the acceptable completions for the
288 /// current context.
289 unsigned long long Contexts;
290
291 /// The kind of the container for the current context for completions.
292 enum CXCursorKind ContainerKind;
293
294 /// The USR of the container for the current context for completions.
295 std::string ContainerUSR;
296
297 /// a boolean value indicating whether there is complete information
298 /// about the container
299 unsigned ContainerIsIncomplete;
300
301 /// A string containing the Objective-C selector entered thus far for a
302 /// message send.
303 std::string Selector;
304
305 /// Vector of fix-its for each completion result that *must* be applied
306 /// before that result for the corresponding completion item.
307 std::vector<std::vector<FixItHint>> FixItsVector;
308};
309
310} // end anonymous namespace
311
312unsigned clang_getCompletionNumFixIts(CXCodeCompleteResults *results,
313 unsigned completion_index) {
314 AllocatedCXCodeCompleteResults *allocated_results = (AllocatedCXCodeCompleteResults *)results;
315
316 if (!allocated_results || allocated_results->FixItsVector.size() <= completion_index)
317 return 0;
318
319 return static_cast<unsigned>(allocated_results->FixItsVector[completion_index].size());
320}
321
322CXString clang_getCompletionFixIt(CXCodeCompleteResults *results,
323 unsigned completion_index,
324 unsigned fixit_index,
325 CXSourceRange *replacement_range) {
326 AllocatedCXCodeCompleteResults *allocated_results = (AllocatedCXCodeCompleteResults *)results;
327
328 if (!allocated_results || allocated_results->FixItsVector.size() <= completion_index) {
329 if (replacement_range)
330 *replacement_range = clang_getNullRange();
331 return cxstring::createNull();
332 }
333
334 ArrayRef<FixItHint> FixIts = allocated_results->FixItsVector[completion_index];
335 if (FixIts.size() <= fixit_index) {
336 if (replacement_range)
337 *replacement_range = clang_getNullRange();
338 return cxstring::createNull();
339 }
340
341 const FixItHint &FixIt = FixIts[fixit_index];
342 if (replacement_range) {
343 *replacement_range = cxloc::translateSourceRange(
344 SM: *allocated_results->SourceMgr, LangOpts: allocated_results->LangOpts,
345 R: FixIt.RemoveRange);
346 }
347
348 return cxstring::createRef(String: FixIt.CodeToInsert.c_str());
349}
350
351/// Tracks the number of code-completion result objects that are
352/// currently active.
353///
354/// Used for debugging purposes only.
355static std::atomic<unsigned> CodeCompletionResultObjects;
356
357AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
358 IntrusiveRefCntPtr<FileManager> FileMgr)
359 : CXCodeCompleteResults(),
360 Diag(llvm::makeIntrusiveRefCnt<DiagnosticsEngine>(A: DiagnosticIDs::create(),
361 A&: DiagOpts)),
362 FileMgr(std::move(FileMgr)),
363 SourceMgr(
364 llvm::makeIntrusiveRefCnt<SourceManager>(A&: *Diag, A&: *this->FileMgr)),
365 CodeCompletionAllocator(
366 std::make_shared<clang::GlobalCodeCompletionAllocator>()),
367 Contexts(CXCompletionContext_Unknown),
368 ContainerKind(CXCursor_InvalidCode), ContainerIsIncomplete(1) {
369 if (getenv(name: "LIBCLANG_OBJTRACKING"))
370 fprintf(stderr, format: "+++ %u completion results\n",
371 ++CodeCompletionResultObjects);
372}
373
374AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
375 delete [] Results;
376
377 for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
378 delete TemporaryBuffers[I];
379
380 if (getenv(name: "LIBCLANG_OBJTRACKING"))
381 fprintf(stderr, format: "--- %u completion results\n",
382 --CodeCompletionResultObjects);
383}
384
385static unsigned long long getContextsForContextKind(
386 enum CodeCompletionContext::Kind kind,
387 Sema &S) {
388 unsigned long long contexts = 0;
389 switch (kind) {
390 case CodeCompletionContext::CCC_OtherWithMacros: {
391 //We can allow macros here, but we don't know what else is permissible
392 //So we'll say the only thing permissible are macros
393 contexts = CXCompletionContext_MacroName;
394 break;
395 }
396 case CodeCompletionContext::CCC_TopLevel:
397 case CodeCompletionContext::CCC_ObjCIvarList:
398 case CodeCompletionContext::CCC_ClassStructUnion:
399 case CodeCompletionContext::CCC_Type: {
400 contexts = CXCompletionContext_AnyType |
401 CXCompletionContext_ObjCInterface;
402 if (S.getLangOpts().CPlusPlus) {
403 contexts |= CXCompletionContext_EnumTag |
404 CXCompletionContext_UnionTag |
405 CXCompletionContext_StructTag |
406 CXCompletionContext_ClassTag |
407 CXCompletionContext_NestedNameSpecifier;
408 }
409 break;
410 }
411 case CodeCompletionContext::CCC_Statement: {
412 contexts = CXCompletionContext_AnyType |
413 CXCompletionContext_ObjCInterface |
414 CXCompletionContext_AnyValue;
415 if (S.getLangOpts().CPlusPlus) {
416 contexts |= CXCompletionContext_EnumTag |
417 CXCompletionContext_UnionTag |
418 CXCompletionContext_StructTag |
419 CXCompletionContext_ClassTag |
420 CXCompletionContext_NestedNameSpecifier;
421 }
422 break;
423 }
424 case CodeCompletionContext::CCC_Expression: {
425 contexts = CXCompletionContext_AnyValue;
426 if (S.getLangOpts().CPlusPlus) {
427 contexts |= CXCompletionContext_AnyType |
428 CXCompletionContext_ObjCInterface |
429 CXCompletionContext_EnumTag |
430 CXCompletionContext_UnionTag |
431 CXCompletionContext_StructTag |
432 CXCompletionContext_ClassTag |
433 CXCompletionContext_NestedNameSpecifier;
434 }
435 break;
436 }
437 case CodeCompletionContext::CCC_ObjCMessageReceiver: {
438 contexts = CXCompletionContext_ObjCObjectValue |
439 CXCompletionContext_ObjCSelectorValue |
440 CXCompletionContext_ObjCInterface;
441 if (S.getLangOpts().CPlusPlus) {
442 contexts |= CXCompletionContext_CXXClassTypeValue |
443 CXCompletionContext_AnyType |
444 CXCompletionContext_EnumTag |
445 CXCompletionContext_UnionTag |
446 CXCompletionContext_StructTag |
447 CXCompletionContext_ClassTag |
448 CXCompletionContext_NestedNameSpecifier;
449 }
450 break;
451 }
452 case CodeCompletionContext::CCC_DotMemberAccess: {
453 contexts = CXCompletionContext_DotMemberAccess;
454 break;
455 }
456 case CodeCompletionContext::CCC_ArrowMemberAccess: {
457 contexts = CXCompletionContext_ArrowMemberAccess;
458 break;
459 }
460 case CodeCompletionContext::CCC_ObjCPropertyAccess: {
461 contexts = CXCompletionContext_ObjCPropertyAccess;
462 break;
463 }
464 case CodeCompletionContext::CCC_EnumTag: {
465 contexts = CXCompletionContext_EnumTag |
466 CXCompletionContext_NestedNameSpecifier;
467 break;
468 }
469 case CodeCompletionContext::CCC_UnionTag: {
470 contexts = CXCompletionContext_UnionTag |
471 CXCompletionContext_NestedNameSpecifier;
472 break;
473 }
474 case CodeCompletionContext::CCC_ClassOrStructTag: {
475 contexts = CXCompletionContext_StructTag |
476 CXCompletionContext_ClassTag |
477 CXCompletionContext_NestedNameSpecifier;
478 break;
479 }
480 case CodeCompletionContext::CCC_ObjCProtocolName: {
481 contexts = CXCompletionContext_ObjCProtocol;
482 break;
483 }
484 case CodeCompletionContext::CCC_Namespace: {
485 contexts = CXCompletionContext_Namespace;
486 break;
487 }
488 case CodeCompletionContext::CCC_SymbolOrNewName:
489 case CodeCompletionContext::CCC_Symbol: {
490 contexts = CXCompletionContext_NestedNameSpecifier;
491 break;
492 }
493 case CodeCompletionContext::CCC_MacroNameUse: {
494 contexts = CXCompletionContext_MacroName;
495 break;
496 }
497 case CodeCompletionContext::CCC_NaturalLanguage: {
498 contexts = CXCompletionContext_NaturalLanguage;
499 break;
500 }
501 case CodeCompletionContext::CCC_IncludedFile: {
502 contexts = CXCompletionContext_IncludedFile;
503 break;
504 }
505 case CodeCompletionContext::CCC_SelectorName: {
506 contexts = CXCompletionContext_ObjCSelectorName;
507 break;
508 }
509 case CodeCompletionContext::CCC_ParenthesizedExpression: {
510 contexts = CXCompletionContext_AnyType |
511 CXCompletionContext_ObjCInterface |
512 CXCompletionContext_AnyValue;
513 if (S.getLangOpts().CPlusPlus) {
514 contexts |= CXCompletionContext_EnumTag |
515 CXCompletionContext_UnionTag |
516 CXCompletionContext_StructTag |
517 CXCompletionContext_ClassTag |
518 CXCompletionContext_NestedNameSpecifier;
519 }
520 break;
521 }
522 case CodeCompletionContext::CCC_ObjCInstanceMessage: {
523 contexts = CXCompletionContext_ObjCInstanceMessage;
524 break;
525 }
526 case CodeCompletionContext::CCC_ObjCClassMessage: {
527 contexts = CXCompletionContext_ObjCClassMessage;
528 break;
529 }
530 case CodeCompletionContext::CCC_ObjCInterfaceName: {
531 contexts = CXCompletionContext_ObjCInterface;
532 break;
533 }
534 case CodeCompletionContext::CCC_ObjCCategoryName: {
535 contexts = CXCompletionContext_ObjCCategory;
536 break;
537 }
538 case CodeCompletionContext::CCC_Other:
539 case CodeCompletionContext::CCC_ObjCInterface:
540 case CodeCompletionContext::CCC_ObjCImplementation:
541 case CodeCompletionContext::CCC_ObjCClassForwardDecl:
542 case CodeCompletionContext::CCC_NewName:
543 case CodeCompletionContext::CCC_MacroName:
544 case CodeCompletionContext::CCC_PreprocessorExpression:
545 case CodeCompletionContext::CCC_PreprocessorDirective:
546 case CodeCompletionContext::CCC_Attribute:
547 case CodeCompletionContext::CCC_TopLevelOrExpression:
548 case CodeCompletionContext::CCC_TypeQualifiers: {
549 //Only Clang results should be accepted, so we'll set all of the other
550 //context bits to 0 (i.e. the empty set)
551 contexts = CXCompletionContext_Unexposed;
552 break;
553 }
554 case CodeCompletionContext::CCC_Recovery: {
555 //We don't know what the current context is, so we'll return unknown
556 //This is the equivalent of setting all of the other context bits
557 contexts = CXCompletionContext_Unknown;
558 break;
559 }
560 }
561 return contexts;
562}
563
564namespace {
565 class CaptureCompletionResults : public CodeCompleteConsumer {
566 AllocatedCXCodeCompleteResults &AllocatedResults;
567 CodeCompletionTUInfo CCTUInfo;
568 SmallVector<CXCompletionResult, 16> StoredResults;
569 CXTranslationUnit *TU;
570 public:
571 CaptureCompletionResults(const CodeCompleteOptions &Opts,
572 AllocatedCXCodeCompleteResults &Results,
573 CXTranslationUnit *TranslationUnit)
574 : CodeCompleteConsumer(Opts), AllocatedResults(Results),
575 CCTUInfo(Results.CodeCompletionAllocator), TU(TranslationUnit) {}
576 ~CaptureCompletionResults() override { Finish(); }
577
578 void ProcessCodeCompleteResults(Sema &S,
579 CodeCompletionContext Context,
580 CodeCompletionResult *Results,
581 unsigned NumResults) override {
582 StoredResults.reserve(N: StoredResults.size() + NumResults);
583 if (includeFixIts())
584 AllocatedResults.FixItsVector.reserve(n: NumResults);
585 for (unsigned I = 0; I != NumResults; ++I) {
586 CodeCompletionString *StoredCompletion
587 = Results[I].CreateCodeCompletionString(S, CCContext: Context, Allocator&: getAllocator(),
588 CCTUInfo&: getCodeCompletionTUInfo(),
589 IncludeBriefComments: includeBriefComments());
590
591 CXCompletionResult R;
592 R.CursorKind = Results[I].CursorKind;
593 R.CompletionString = StoredCompletion;
594 StoredResults.push_back(Elt: R);
595 if (includeFixIts())
596 AllocatedResults.FixItsVector.emplace_back(args: std::move(Results[I].FixIts));
597 }
598
599 enum CodeCompletionContext::Kind contextKind = Context.getKind();
600
601 AllocatedResults.ContextKind = contextKind;
602 AllocatedResults.Contexts = getContextsForContextKind(kind: contextKind, S);
603
604 AllocatedResults.Selector = "";
605 ArrayRef<const IdentifierInfo *> SelIdents = Context.getSelIdents();
606 for (ArrayRef<const IdentifierInfo *>::iterator I = SelIdents.begin(),
607 E = SelIdents.end();
608 I != E; ++I) {
609 if (const IdentifierInfo *selIdent = *I)
610 AllocatedResults.Selector += selIdent->getName();
611 AllocatedResults.Selector += ":";
612 }
613
614 QualType baseType = Context.getBaseType();
615 NamedDecl *D = nullptr;
616
617 if (!baseType.isNull()) {
618 // Get the declaration for a class/struct/union/enum type
619 if (const TagType *Tag = baseType->getAs<TagType>())
620 D = Tag->getDecl();
621 // Get the @interface declaration for a (possibly-qualified) Objective-C
622 // object pointer type, e.g., NSString*
623 else if (const ObjCObjectPointerType *ObjPtr =
624 baseType->getAs<ObjCObjectPointerType>())
625 D = ObjPtr->getInterfaceDecl();
626 // Get the @interface declaration for an Objective-C object type
627 else if (const ObjCObjectType *Obj = baseType->getAs<ObjCObjectType>())
628 D = Obj->getInterface();
629 // Get the class for a C++ injected-class-name
630 else if (const InjectedClassNameType *Injected =
631 baseType->getAs<InjectedClassNameType>())
632 D = Injected->getDecl();
633 }
634
635 if (D != nullptr) {
636 CXCursor cursor = cxcursor::MakeCXCursor(D, TU: *TU);
637
638 AllocatedResults.ContainerKind = clang_getCursorKind(cursor);
639
640 CXString CursorUSR = clang_getCursorUSR(cursor);
641 AllocatedResults.ContainerUSR = clang_getCString(string: CursorUSR);
642 clang_disposeString(string: CursorUSR);
643
644 const Type *type = baseType.getTypePtrOrNull();
645 if (type) {
646 AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
647 }
648 else {
649 AllocatedResults.ContainerIsIncomplete = 1;
650 }
651 }
652 else {
653 AllocatedResults.ContainerKind = CXCursor_InvalidCode;
654 AllocatedResults.ContainerUSR.clear();
655 AllocatedResults.ContainerIsIncomplete = 1;
656 }
657 }
658
659 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
660 OverloadCandidate *Candidates,
661 unsigned NumCandidates,
662 SourceLocation OpenParLoc,
663 bool Braced) override {
664 StoredResults.reserve(N: StoredResults.size() + NumCandidates);
665 for (unsigned I = 0; I != NumCandidates; ++I) {
666 CodeCompletionString *StoredCompletion =
667 Candidates[I].CreateSignatureString(CurrentArg, S, Allocator&: getAllocator(),
668 CCTUInfo&: getCodeCompletionTUInfo(),
669 IncludeBriefComments: includeBriefComments(), Braced);
670
671 CXCompletionResult R;
672 R.CursorKind = CXCursor_OverloadCandidate;
673 R.CompletionString = StoredCompletion;
674 StoredResults.push_back(Elt: R);
675 }
676 }
677
678 CodeCompletionAllocator &getAllocator() override {
679 return *AllocatedResults.CodeCompletionAllocator;
680 }
681
682 CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;}
683
684 private:
685 void Finish() {
686 AllocatedResults.Results = new CXCompletionResult [StoredResults.size()];
687 AllocatedResults.NumResults = StoredResults.size();
688 std::memcpy(dest: AllocatedResults.Results, src: StoredResults.data(),
689 n: StoredResults.size() * sizeof(CXCompletionResult));
690 StoredResults.clear();
691 }
692 };
693}
694
695static CXCodeCompleteResults *
696clang_codeCompleteAt_Impl(CXTranslationUnit TU, const char *complete_filename,
697 unsigned complete_line, unsigned complete_column,
698 ArrayRef<CXUnsavedFile> unsaved_files,
699 unsigned options) {
700 bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;
701 bool SkipPreamble = options & CXCodeComplete_SkipPreamble;
702 bool IncludeFixIts = options & CXCodeComplete_IncludeCompletionsWithFixIts;
703
704#ifdef UDP_CODE_COMPLETION_LOGGER
705#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
706 const llvm::TimeRecord &StartTime = llvm::TimeRecord::getCurrentTime();
707#endif
708#endif
709 bool EnableLogging = getenv(name: "LIBCLANG_CODE_COMPLETION_LOGGING") != nullptr;
710
711 if (cxtu::isNotUsableTU(TU)) {
712 LOG_BAD_TU(TU);
713 return nullptr;
714 }
715
716 ASTUnit *AST = cxtu::getASTUnit(TU);
717 if (!AST)
718 return nullptr;
719
720 CIndexer *CXXIdx = TU->CIdx;
721 if (CXXIdx->isOptEnabled(opt: CXGlobalOpt_ThreadBackgroundPriorityForEditing))
722 setThreadBackgroundPriority();
723
724 ASTUnit::ConcurrencyCheck Check(*AST);
725
726 // Perform the remapping of source files.
727 SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
728
729 for (auto &UF : unsaved_files) {
730 std::unique_ptr<llvm::MemoryBuffer> MB =
731 llvm::MemoryBuffer::getMemBufferCopy(InputData: getContents(UF), BufferName: UF.Filename);
732 RemappedFiles.push_back(Elt: std::make_pair(x: UF.Filename, y: MB.release()));
733 }
734
735 if (EnableLogging) {
736 // FIXME: Add logging.
737 }
738
739 // Parse the resulting source file to find code-completion results.
740 AllocatedCXCodeCompleteResults *Results =
741 new AllocatedCXCodeCompleteResults(AST->getFileManagerPtr());
742 Results->Results = nullptr;
743 Results->NumResults = 0;
744
745 // Create a code-completion consumer to capture the results.
746 CodeCompleteOptions Opts;
747 Opts.IncludeBriefComments = IncludeBriefComments;
748 Opts.LoadExternal = !SkipPreamble;
749 Opts.IncludeFixIts = IncludeFixIts;
750 CaptureCompletionResults Capture(Opts, *Results, &TU);
751
752 // Perform completion.
753 std::vector<const char *> CArgs;
754 for (const auto &Arg : TU->Arguments)
755 CArgs.push_back(x: Arg.c_str());
756 std::string CompletionInvocation =
757 llvm::formatv(Fmt: "-code-completion-at={0}:{1}:{2}", Vals&: complete_filename,
758 Vals&: complete_line, Vals&: complete_column)
759 .str();
760 LibclangInvocationReporter InvocationReporter(
761 *CXXIdx, LibclangInvocationReporter::OperationKind::CompletionOperation,
762 TU->ParsingOptions, CArgs, CompletionInvocation, unsaved_files);
763 AST->CodeComplete(File: complete_filename, Line: complete_line, Column: complete_column,
764 RemappedFiles, IncludeMacros: (options & CXCodeComplete_IncludeMacros),
765 IncludeCodePatterns: (options & CXCodeComplete_IncludeCodePatterns),
766 IncludeBriefComments, Consumer&: Capture,
767 PCHContainerOps: CXXIdx->getPCHContainerOperations(), Diag: Results->Diag,
768 LangOpts&: Results->LangOpts, SourceMgr: Results->SourceMgr, FileMgr: Results->FileMgr,
769 StoredDiagnostics&: Results->Diagnostics, OwnedBuffers&: Results->TemporaryBuffers,
770 /*SyntaxOnlyAction=*/Act: nullptr);
771
772 Results->DiagnosticsWrappers.resize(N: Results->Diagnostics.size());
773
774 // Keep a reference to the allocator used for cached global completions, so
775 // that we can be sure that the memory used by our code completion strings
776 // doesn't get freed due to subsequent reparses (while the code completion
777 // results are still active).
778 Results->CachedCompletionAllocator = AST->getCachedCompletionAllocator();
779
780
781
782#ifdef UDP_CODE_COMPLETION_LOGGER
783#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
784 const llvm::TimeRecord &EndTime = llvm::TimeRecord::getCurrentTime();
785 SmallString<256> LogResult;
786 llvm::raw_svector_ostream os(LogResult);
787
788 // Figure out the language and whether or not it uses PCH.
789 const char *lang = 0;
790 bool usesPCH = false;
791
792 for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
793 I != E; ++I) {
794 if (*I == 0)
795 continue;
796 if (strcmp(*I, "-x") == 0) {
797 if (I + 1 != E) {
798 lang = *(++I);
799 continue;
800 }
801 }
802 else if (strcmp(*I, "-include") == 0) {
803 if (I+1 != E) {
804 const char *arg = *(++I);
805 SmallString<512> pchName;
806 {
807 llvm::raw_svector_ostream os(pchName);
808 os << arg << ".pth";
809 }
810 pchName.push_back('\0');
811 llvm::sys::fs::file_status stat_results;
812 if (!llvm::sys::fs::status(pchName, stat_results))
813 usesPCH = true;
814 continue;
815 }
816 }
817 }
818
819 os << "{ ";
820 os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
821 os << ", \"numRes\": " << Results->NumResults;
822 os << ", \"diags\": " << Results->Diagnostics.size();
823 os << ", \"pch\": " << (usesPCH ? "true" : "false");
824 os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
825 const char *name = getlogin();
826 os << ", \"user\": \"" << (name ? name : "unknown") << '"';
827 os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
828 os << " }";
829
830 StringRef res = os.str();
831 if (res.size() > 0) {
832 do {
833 // Setup the UDP socket.
834 struct sockaddr_in servaddr;
835 bzero(&servaddr, sizeof(servaddr));
836 servaddr.sin_family = AF_INET;
837 servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
838 if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
839 &servaddr.sin_addr) <= 0)
840 break;
841
842 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
843 if (sockfd < 0)
844 break;
845
846 sendto(sockfd, res.data(), res.size(), 0,
847 (struct sockaddr *)&servaddr, sizeof(servaddr));
848 close(sockfd);
849 }
850 while (false);
851 }
852#endif
853#endif
854 return Results;
855}
856
857CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
858 const char *complete_filename,
859 unsigned complete_line,
860 unsigned complete_column,
861 struct CXUnsavedFile *unsaved_files,
862 unsigned num_unsaved_files,
863 unsigned options) {
864 LOG_FUNC_SECTION {
865 *Log << TU << ' '
866 << complete_filename << ':' << complete_line << ':' << complete_column;
867 }
868
869 if (num_unsaved_files && !unsaved_files)
870 return nullptr;
871
872 CXCodeCompleteResults *result;
873 auto CodeCompleteAtImpl = [=, &result]() {
874 result = clang_codeCompleteAt_Impl(
875 TU, complete_filename, complete_line, complete_column,
876 unsaved_files: llvm::ArrayRef(unsaved_files, num_unsaved_files), options);
877 };
878
879 llvm::CrashRecoveryContext CRC;
880
881 if (!RunSafely(CRC, Fn: CodeCompleteAtImpl)) {
882 fprintf(stderr, format: "libclang: crash detected in code completion\n");
883 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
884 return nullptr;
885 } else if (getenv(name: "LIBCLANG_RESOURCE_USAGE"))
886 PrintLibclangResourceUsage(TU);
887
888 return result;
889}
890
891unsigned clang_defaultCodeCompleteOptions(void) {
892 return CXCodeComplete_IncludeMacros;
893}
894
895void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {
896 if (!ResultsIn)
897 return;
898
899 AllocatedCXCodeCompleteResults *Results
900 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
901 delete Results;
902}
903
904unsigned
905clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) {
906 AllocatedCXCodeCompleteResults *Results
907 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
908 if (!Results)
909 return 0;
910
911 return Results->Diagnostics.size();
912}
913
914CXDiagnostic
915clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
916 unsigned Index) {
917 AllocatedCXCodeCompleteResults *Results
918 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
919 if (!Results || Index >= Results->Diagnostics.size())
920 return nullptr;
921
922 CXStoredDiagnostic *Diag = Results->DiagnosticsWrappers[Index].get();
923 if (!Diag)
924 Diag = (Results->DiagnosticsWrappers[Index] =
925 std::make_unique<CXStoredDiagnostic>(
926 args&: Results->Diagnostics[Index], args&: Results->LangOpts))
927 .get();
928 return Diag;
929}
930
931unsigned long long
932clang_codeCompleteGetContexts(CXCodeCompleteResults *ResultsIn) {
933 AllocatedCXCodeCompleteResults *Results
934 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
935 if (!Results)
936 return 0;
937
938 return Results->Contexts;
939}
940
941enum CXCursorKind clang_codeCompleteGetContainerKind(
942 CXCodeCompleteResults *ResultsIn,
943 unsigned *IsIncomplete) {
944 AllocatedCXCodeCompleteResults *Results =
945 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
946 if (!Results)
947 return CXCursor_InvalidCode;
948
949 if (IsIncomplete != nullptr) {
950 *IsIncomplete = Results->ContainerIsIncomplete;
951 }
952
953 return Results->ContainerKind;
954}
955
956CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
957 AllocatedCXCodeCompleteResults *Results =
958 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
959 if (!Results)
960 return cxstring::createEmpty();
961
962 return cxstring::createRef(String: Results->ContainerUSR.c_str());
963}
964
965
966CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
967 AllocatedCXCodeCompleteResults *Results =
968 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
969 if (!Results)
970 return cxstring::createEmpty();
971
972 return cxstring::createDup(String: Results->Selector);
973}
974
975/// Simple utility function that appends a \p New string to the given
976/// \p Old string, using the \p Buffer for storage.
977///
978/// \param Old The string to which we are appending. This parameter will be
979/// updated to reflect the complete string.
980///
981///
982/// \param New The string to append to \p Old.
983///
984/// \param Buffer A buffer that stores the actual, concatenated string. It will
985/// be used if the old string is already-non-empty.
986static void AppendToString(StringRef &Old, StringRef New,
987 SmallString<256> &Buffer) {
988 if (Old.empty()) {
989 Old = New;
990 return;
991 }
992
993 if (Buffer.empty())
994 Buffer.append(in_start: Old.begin(), in_end: Old.end());
995 Buffer.append(in_start: New.begin(), in_end: New.end());
996 Old = Buffer.str();
997}
998
999/// Get the typed-text blocks from the given code-completion string
1000/// and return them as a single string.
1001///
1002/// \param String The code-completion string whose typed-text blocks will be
1003/// concatenated.
1004///
1005/// \param Buffer A buffer used for storage of the completed name.
1006static StringRef GetTypedName(CodeCompletionString *String,
1007 SmallString<256> &Buffer) {
1008 StringRef Result;
1009 for (CodeCompletionString::iterator C = String->begin(), CEnd = String->end();
1010 C != CEnd; ++C) {
1011 if (C->Kind == CodeCompletionString::CK_TypedText)
1012 AppendToString(Old&: Result, New: C->Text, Buffer);
1013 }
1014
1015 return Result;
1016}
1017
1018namespace {
1019 struct OrderCompletionResults {
1020 bool operator()(const CXCompletionResult &XR,
1021 const CXCompletionResult &YR) const {
1022 CodeCompletionString *X
1023 = (CodeCompletionString *)XR.CompletionString;
1024 CodeCompletionString *Y
1025 = (CodeCompletionString *)YR.CompletionString;
1026
1027 SmallString<256> XBuffer;
1028 StringRef XText = GetTypedName(String: X, Buffer&: XBuffer);
1029 SmallString<256> YBuffer;
1030 StringRef YText = GetTypedName(String: Y, Buffer&: YBuffer);
1031
1032 if (XText.empty() || YText.empty())
1033 return !XText.empty();
1034
1035 int result = XText.compare_insensitive(RHS: YText);
1036 if (result < 0)
1037 return true;
1038 if (result > 0)
1039 return false;
1040
1041 result = XText.compare(RHS: YText);
1042 return result < 0;
1043 }
1044 };
1045}
1046
1047void clang_sortCodeCompletionResults(CXCompletionResult *Results,
1048 unsigned NumResults) {
1049 std::stable_sort(first: Results, last: Results + NumResults, comp: OrderCompletionResults());
1050}
1051