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 IntrusiveRefCntPtr<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(), DiagOpts(new DiagnosticOptions),
360 Diag(new DiagnosticsEngine(
361 IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts)),
362 FileMgr(std::move(FileMgr)),
363 SourceMgr(new SourceManager(*Diag, *this->FileMgr)),
364 CodeCompletionAllocator(
365 std::make_shared<clang::GlobalCodeCompletionAllocator>()),
366 Contexts(CXCompletionContext_Unknown),
367 ContainerKind(CXCursor_InvalidCode), ContainerIsIncomplete(1) {
368 if (getenv(name: "LIBCLANG_OBJTRACKING"))
369 fprintf(stderr, format: "+++ %u completion results\n",
370 ++CodeCompletionResultObjects);
371}
372
373AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
374 delete [] Results;
375
376 for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
377 delete TemporaryBuffers[I];
378
379 if (getenv(name: "LIBCLANG_OBJTRACKING"))
380 fprintf(stderr, format: "--- %u completion results\n",
381 --CodeCompletionResultObjects);
382}
383
384static unsigned long long getContextsForContextKind(
385 enum CodeCompletionContext::Kind kind,
386 Sema &S) {
387 unsigned long long contexts = 0;
388 switch (kind) {
389 case CodeCompletionContext::CCC_OtherWithMacros: {
390 //We can allow macros here, but we don't know what else is permissible
391 //So we'll say the only thing permissible are macros
392 contexts = CXCompletionContext_MacroName;
393 break;
394 }
395 case CodeCompletionContext::CCC_TopLevel:
396 case CodeCompletionContext::CCC_ObjCIvarList:
397 case CodeCompletionContext::CCC_ClassStructUnion:
398 case CodeCompletionContext::CCC_Type: {
399 contexts = CXCompletionContext_AnyType |
400 CXCompletionContext_ObjCInterface;
401 if (S.getLangOpts().CPlusPlus) {
402 contexts |= CXCompletionContext_EnumTag |
403 CXCompletionContext_UnionTag |
404 CXCompletionContext_StructTag |
405 CXCompletionContext_ClassTag |
406 CXCompletionContext_NestedNameSpecifier;
407 }
408 break;
409 }
410 case CodeCompletionContext::CCC_Statement: {
411 contexts = CXCompletionContext_AnyType |
412 CXCompletionContext_ObjCInterface |
413 CXCompletionContext_AnyValue;
414 if (S.getLangOpts().CPlusPlus) {
415 contexts |= CXCompletionContext_EnumTag |
416 CXCompletionContext_UnionTag |
417 CXCompletionContext_StructTag |
418 CXCompletionContext_ClassTag |
419 CXCompletionContext_NestedNameSpecifier;
420 }
421 break;
422 }
423 case CodeCompletionContext::CCC_Expression: {
424 contexts = CXCompletionContext_AnyValue;
425 if (S.getLangOpts().CPlusPlus) {
426 contexts |= CXCompletionContext_AnyType |
427 CXCompletionContext_ObjCInterface |
428 CXCompletionContext_EnumTag |
429 CXCompletionContext_UnionTag |
430 CXCompletionContext_StructTag |
431 CXCompletionContext_ClassTag |
432 CXCompletionContext_NestedNameSpecifier;
433 }
434 break;
435 }
436 case CodeCompletionContext::CCC_ObjCMessageReceiver: {
437 contexts = CXCompletionContext_ObjCObjectValue |
438 CXCompletionContext_ObjCSelectorValue |
439 CXCompletionContext_ObjCInterface;
440 if (S.getLangOpts().CPlusPlus) {
441 contexts |= CXCompletionContext_CXXClassTypeValue |
442 CXCompletionContext_AnyType |
443 CXCompletionContext_EnumTag |
444 CXCompletionContext_UnionTag |
445 CXCompletionContext_StructTag |
446 CXCompletionContext_ClassTag |
447 CXCompletionContext_NestedNameSpecifier;
448 }
449 break;
450 }
451 case CodeCompletionContext::CCC_DotMemberAccess: {
452 contexts = CXCompletionContext_DotMemberAccess;
453 break;
454 }
455 case CodeCompletionContext::CCC_ArrowMemberAccess: {
456 contexts = CXCompletionContext_ArrowMemberAccess;
457 break;
458 }
459 case CodeCompletionContext::CCC_ObjCPropertyAccess: {
460 contexts = CXCompletionContext_ObjCPropertyAccess;
461 break;
462 }
463 case CodeCompletionContext::CCC_EnumTag: {
464 contexts = CXCompletionContext_EnumTag |
465 CXCompletionContext_NestedNameSpecifier;
466 break;
467 }
468 case CodeCompletionContext::CCC_UnionTag: {
469 contexts = CXCompletionContext_UnionTag |
470 CXCompletionContext_NestedNameSpecifier;
471 break;
472 }
473 case CodeCompletionContext::CCC_ClassOrStructTag: {
474 contexts = CXCompletionContext_StructTag |
475 CXCompletionContext_ClassTag |
476 CXCompletionContext_NestedNameSpecifier;
477 break;
478 }
479 case CodeCompletionContext::CCC_ObjCProtocolName: {
480 contexts = CXCompletionContext_ObjCProtocol;
481 break;
482 }
483 case CodeCompletionContext::CCC_Namespace: {
484 contexts = CXCompletionContext_Namespace;
485 break;
486 }
487 case CodeCompletionContext::CCC_SymbolOrNewName:
488 case CodeCompletionContext::CCC_Symbol: {
489 contexts = CXCompletionContext_NestedNameSpecifier;
490 break;
491 }
492 case CodeCompletionContext::CCC_MacroNameUse: {
493 contexts = CXCompletionContext_MacroName;
494 break;
495 }
496 case CodeCompletionContext::CCC_NaturalLanguage: {
497 contexts = CXCompletionContext_NaturalLanguage;
498 break;
499 }
500 case CodeCompletionContext::CCC_IncludedFile: {
501 contexts = CXCompletionContext_IncludedFile;
502 break;
503 }
504 case CodeCompletionContext::CCC_SelectorName: {
505 contexts = CXCompletionContext_ObjCSelectorName;
506 break;
507 }
508 case CodeCompletionContext::CCC_ParenthesizedExpression: {
509 contexts = CXCompletionContext_AnyType |
510 CXCompletionContext_ObjCInterface |
511 CXCompletionContext_AnyValue;
512 if (S.getLangOpts().CPlusPlus) {
513 contexts |= CXCompletionContext_EnumTag |
514 CXCompletionContext_UnionTag |
515 CXCompletionContext_StructTag |
516 CXCompletionContext_ClassTag |
517 CXCompletionContext_NestedNameSpecifier;
518 }
519 break;
520 }
521 case CodeCompletionContext::CCC_ObjCInstanceMessage: {
522 contexts = CXCompletionContext_ObjCInstanceMessage;
523 break;
524 }
525 case CodeCompletionContext::CCC_ObjCClassMessage: {
526 contexts = CXCompletionContext_ObjCClassMessage;
527 break;
528 }
529 case CodeCompletionContext::CCC_ObjCInterfaceName: {
530 contexts = CXCompletionContext_ObjCInterface;
531 break;
532 }
533 case CodeCompletionContext::CCC_ObjCCategoryName: {
534 contexts = CXCompletionContext_ObjCCategory;
535 break;
536 }
537 case CodeCompletionContext::CCC_Other:
538 case CodeCompletionContext::CCC_ObjCInterface:
539 case CodeCompletionContext::CCC_ObjCImplementation:
540 case CodeCompletionContext::CCC_ObjCClassForwardDecl:
541 case CodeCompletionContext::CCC_NewName:
542 case CodeCompletionContext::CCC_MacroName:
543 case CodeCompletionContext::CCC_PreprocessorExpression:
544 case CodeCompletionContext::CCC_PreprocessorDirective:
545 case CodeCompletionContext::CCC_Attribute:
546 case CodeCompletionContext::CCC_TopLevelOrExpression:
547 case CodeCompletionContext::CCC_TypeQualifiers: {
548 //Only Clang results should be accepted, so we'll set all of the other
549 //context bits to 0 (i.e. the empty set)
550 contexts = CXCompletionContext_Unexposed;
551 break;
552 }
553 case CodeCompletionContext::CCC_Recovery: {
554 //We don't know what the current context is, so we'll return unknown
555 //This is the equivalent of setting all of the other context bits
556 contexts = CXCompletionContext_Unknown;
557 break;
558 }
559 }
560 return contexts;
561}
562
563namespace {
564 class CaptureCompletionResults : public CodeCompleteConsumer {
565 AllocatedCXCodeCompleteResults &AllocatedResults;
566 CodeCompletionTUInfo CCTUInfo;
567 SmallVector<CXCompletionResult, 16> StoredResults;
568 CXTranslationUnit *TU;
569 public:
570 CaptureCompletionResults(const CodeCompleteOptions &Opts,
571 AllocatedCXCodeCompleteResults &Results,
572 CXTranslationUnit *TranslationUnit)
573 : CodeCompleteConsumer(Opts), AllocatedResults(Results),
574 CCTUInfo(Results.CodeCompletionAllocator), TU(TranslationUnit) {}
575 ~CaptureCompletionResults() override { Finish(); }
576
577 void ProcessCodeCompleteResults(Sema &S,
578 CodeCompletionContext Context,
579 CodeCompletionResult *Results,
580 unsigned NumResults) override {
581 StoredResults.reserve(N: StoredResults.size() + NumResults);
582 if (includeFixIts())
583 AllocatedResults.FixItsVector.reserve(n: NumResults);
584 for (unsigned I = 0; I != NumResults; ++I) {
585 CodeCompletionString *StoredCompletion
586 = Results[I].CreateCodeCompletionString(S, CCContext: Context, Allocator&: getAllocator(),
587 CCTUInfo&: getCodeCompletionTUInfo(),
588 IncludeBriefComments: includeBriefComments());
589
590 CXCompletionResult R;
591 R.CursorKind = Results[I].CursorKind;
592 R.CompletionString = StoredCompletion;
593 StoredResults.push_back(Elt: R);
594 if (includeFixIts())
595 AllocatedResults.FixItsVector.emplace_back(args: std::move(Results[I].FixIts));
596 }
597
598 enum CodeCompletionContext::Kind contextKind = Context.getKind();
599
600 AllocatedResults.ContextKind = contextKind;
601 AllocatedResults.Contexts = getContextsForContextKind(kind: contextKind, S);
602
603 AllocatedResults.Selector = "";
604 ArrayRef<const IdentifierInfo *> SelIdents = Context.getSelIdents();
605 for (ArrayRef<const IdentifierInfo *>::iterator I = SelIdents.begin(),
606 E = SelIdents.end();
607 I != E; ++I) {
608 if (const IdentifierInfo *selIdent = *I)
609 AllocatedResults.Selector += selIdent->getName();
610 AllocatedResults.Selector += ":";
611 }
612
613 QualType baseType = Context.getBaseType();
614 NamedDecl *D = nullptr;
615
616 if (!baseType.isNull()) {
617 // Get the declaration for a class/struct/union/enum type
618 if (const TagType *Tag = baseType->getAs<TagType>())
619 D = Tag->getDecl();
620 // Get the @interface declaration for a (possibly-qualified) Objective-C
621 // object pointer type, e.g., NSString*
622 else if (const ObjCObjectPointerType *ObjPtr =
623 baseType->getAs<ObjCObjectPointerType>())
624 D = ObjPtr->getInterfaceDecl();
625 // Get the @interface declaration for an Objective-C object type
626 else if (const ObjCObjectType *Obj = baseType->getAs<ObjCObjectType>())
627 D = Obj->getInterface();
628 // Get the class for a C++ injected-class-name
629 else if (const InjectedClassNameType *Injected =
630 baseType->getAs<InjectedClassNameType>())
631 D = Injected->getDecl();
632 }
633
634 if (D != nullptr) {
635 CXCursor cursor = cxcursor::MakeCXCursor(D, *TU);
636
637 AllocatedResults.ContainerKind = clang_getCursorKind(cursor);
638
639 CXString CursorUSR = clang_getCursorUSR(cursor);
640 AllocatedResults.ContainerUSR = clang_getCString(string: CursorUSR);
641 clang_disposeString(string: CursorUSR);
642
643 const Type *type = baseType.getTypePtrOrNull();
644 if (type) {
645 AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
646 }
647 else {
648 AllocatedResults.ContainerIsIncomplete = 1;
649 }
650 }
651 else {
652 AllocatedResults.ContainerKind = CXCursor_InvalidCode;
653 AllocatedResults.ContainerUSR.clear();
654 AllocatedResults.ContainerIsIncomplete = 1;
655 }
656 }
657
658 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
659 OverloadCandidate *Candidates,
660 unsigned NumCandidates,
661 SourceLocation OpenParLoc,
662 bool Braced) override {
663 StoredResults.reserve(N: StoredResults.size() + NumCandidates);
664 for (unsigned I = 0; I != NumCandidates; ++I) {
665 CodeCompletionString *StoredCompletion =
666 Candidates[I].CreateSignatureString(CurrentArg, S, Allocator&: getAllocator(),
667 CCTUInfo&: getCodeCompletionTUInfo(),
668 IncludeBriefComments: includeBriefComments(), Braced);
669
670 CXCompletionResult R;
671 R.CursorKind = CXCursor_OverloadCandidate;
672 R.CompletionString = StoredCompletion;
673 StoredResults.push_back(Elt: R);
674 }
675 }
676
677 CodeCompletionAllocator &getAllocator() override {
678 return *AllocatedResults.CodeCompletionAllocator;
679 }
680
681 CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;}
682
683 private:
684 void Finish() {
685 AllocatedResults.Results = new CXCompletionResult [StoredResults.size()];
686 AllocatedResults.NumResults = StoredResults.size();
687 std::memcpy(dest: AllocatedResults.Results, src: StoredResults.data(),
688 n: StoredResults.size() * sizeof(CXCompletionResult));
689 StoredResults.clear();
690 }
691 };
692}
693
694static CXCodeCompleteResults *
695clang_codeCompleteAt_Impl(CXTranslationUnit TU, const char *complete_filename,
696 unsigned complete_line, unsigned complete_column,
697 ArrayRef<CXUnsavedFile> unsaved_files,
698 unsigned options) {
699 bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;
700 bool SkipPreamble = options & CXCodeComplete_SkipPreamble;
701 bool IncludeFixIts = options & CXCodeComplete_IncludeCompletionsWithFixIts;
702
703#ifdef UDP_CODE_COMPLETION_LOGGER
704#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
705 const llvm::TimeRecord &StartTime = llvm::TimeRecord::getCurrentTime();
706#endif
707#endif
708 bool EnableLogging = getenv(name: "LIBCLANG_CODE_COMPLETION_LOGGING") != nullptr;
709
710 if (cxtu::isNotUsableTU(TU)) {
711 LOG_BAD_TU(TU);
712 return nullptr;
713 }
714
715 ASTUnit *AST = cxtu::getASTUnit(TU);
716 if (!AST)
717 return nullptr;
718
719 CIndexer *CXXIdx = TU->CIdx;
720 if (CXXIdx->isOptEnabled(opt: CXGlobalOpt_ThreadBackgroundPriorityForEditing))
721 setThreadBackgroundPriority();
722
723 ASTUnit::ConcurrencyCheck Check(*AST);
724
725 // Perform the remapping of source files.
726 SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
727
728 for (auto &UF : unsaved_files) {
729 std::unique_ptr<llvm::MemoryBuffer> MB =
730 llvm::MemoryBuffer::getMemBufferCopy(InputData: getContents(UF), BufferName: UF.Filename);
731 RemappedFiles.push_back(Elt: std::make_pair(x: UF.Filename, y: MB.release()));
732 }
733
734 if (EnableLogging) {
735 // FIXME: Add logging.
736 }
737
738 // Parse the resulting source file to find code-completion results.
739 AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults(
740 &AST->getFileManager());
741 Results->Results = nullptr;
742 Results->NumResults = 0;
743
744 // Create a code-completion consumer to capture the results.
745 CodeCompleteOptions Opts;
746 Opts.IncludeBriefComments = IncludeBriefComments;
747 Opts.LoadExternal = !SkipPreamble;
748 Opts.IncludeFixIts = IncludeFixIts;
749 CaptureCompletionResults Capture(Opts, *Results, &TU);
750
751 // Perform completion.
752 std::vector<const char *> CArgs;
753 for (const auto &Arg : TU->Arguments)
754 CArgs.push_back(x: Arg.c_str());
755 std::string CompletionInvocation =
756 llvm::formatv(Fmt: "-code-completion-at={0}:{1}:{2}", Vals&: complete_filename,
757 Vals&: complete_line, Vals&: complete_column)
758 .str();
759 LibclangInvocationReporter InvocationReporter(
760 *CXXIdx, LibclangInvocationReporter::OperationKind::CompletionOperation,
761 TU->ParsingOptions, CArgs, CompletionInvocation, unsaved_files);
762 AST->CodeComplete(File: complete_filename, Line: complete_line, Column: complete_column,
763 RemappedFiles, IncludeMacros: (options & CXCodeComplete_IncludeMacros),
764 IncludeCodePatterns: (options & CXCodeComplete_IncludeCodePatterns),
765 IncludeBriefComments, Consumer&: Capture,
766 PCHContainerOps: CXXIdx->getPCHContainerOperations(), Diag&: *Results->Diag,
767 LangOpts&: Results->LangOpts, SourceMgr&: *Results->SourceMgr, FileMgr&: *Results->FileMgr,
768 StoredDiagnostics&: Results->Diagnostics, OwnedBuffers&: Results->TemporaryBuffers,
769 /*SyntaxOnlyAction=*/Act: nullptr);
770
771 Results->DiagnosticsWrappers.resize(N: Results->Diagnostics.size());
772
773 // Keep a reference to the allocator used for cached global completions, so
774 // that we can be sure that the memory used by our code completion strings
775 // doesn't get freed due to subsequent reparses (while the code completion
776 // results are still active).
777 Results->CachedCompletionAllocator = AST->getCachedCompletionAllocator();
778
779
780
781#ifdef UDP_CODE_COMPLETION_LOGGER
782#ifdef UDP_CODE_COMPLETION_LOGGER_PORT
783 const llvm::TimeRecord &EndTime = llvm::TimeRecord::getCurrentTime();
784 SmallString<256> LogResult;
785 llvm::raw_svector_ostream os(LogResult);
786
787 // Figure out the language and whether or not it uses PCH.
788 const char *lang = 0;
789 bool usesPCH = false;
790
791 for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
792 I != E; ++I) {
793 if (*I == 0)
794 continue;
795 if (strcmp(*I, "-x") == 0) {
796 if (I + 1 != E) {
797 lang = *(++I);
798 continue;
799 }
800 }
801 else if (strcmp(*I, "-include") == 0) {
802 if (I+1 != E) {
803 const char *arg = *(++I);
804 SmallString<512> pchName;
805 {
806 llvm::raw_svector_ostream os(pchName);
807 os << arg << ".pth";
808 }
809 pchName.push_back('\0');
810 llvm::sys::fs::file_status stat_results;
811 if (!llvm::sys::fs::status(pchName, stat_results))
812 usesPCH = true;
813 continue;
814 }
815 }
816 }
817
818 os << "{ ";
819 os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
820 os << ", \"numRes\": " << Results->NumResults;
821 os << ", \"diags\": " << Results->Diagnostics.size();
822 os << ", \"pch\": " << (usesPCH ? "true" : "false");
823 os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
824 const char *name = getlogin();
825 os << ", \"user\": \"" << (name ? name : "unknown") << '"';
826 os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
827 os << " }";
828
829 StringRef res = os.str();
830 if (res.size() > 0) {
831 do {
832 // Setup the UDP socket.
833 struct sockaddr_in servaddr;
834 bzero(&servaddr, sizeof(servaddr));
835 servaddr.sin_family = AF_INET;
836 servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
837 if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
838 &servaddr.sin_addr) <= 0)
839 break;
840
841 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
842 if (sockfd < 0)
843 break;
844
845 sendto(sockfd, res.data(), res.size(), 0,
846 (struct sockaddr *)&servaddr, sizeof(servaddr));
847 close(sockfd);
848 }
849 while (false);
850 }
851#endif
852#endif
853 return Results;
854}
855
856CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
857 const char *complete_filename,
858 unsigned complete_line,
859 unsigned complete_column,
860 struct CXUnsavedFile *unsaved_files,
861 unsigned num_unsaved_files,
862 unsigned options) {
863 LOG_FUNC_SECTION {
864 *Log << TU << ' '
865 << complete_filename << ':' << complete_line << ':' << complete_column;
866 }
867
868 if (num_unsaved_files && !unsaved_files)
869 return nullptr;
870
871 CXCodeCompleteResults *result;
872 auto CodeCompleteAtImpl = [=, &result]() {
873 result = clang_codeCompleteAt_Impl(
874 TU, complete_filename, complete_line, complete_column,
875 unsaved_files: llvm::ArrayRef(unsaved_files, num_unsaved_files), options);
876 };
877
878 llvm::CrashRecoveryContext CRC;
879
880 if (!RunSafely(CRC, Fn: CodeCompleteAtImpl)) {
881 fprintf(stderr, format: "libclang: crash detected in code completion\n");
882 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
883 return nullptr;
884 } else if (getenv(name: "LIBCLANG_RESOURCE_USAGE"))
885 PrintLibclangResourceUsage(TU);
886
887 return result;
888}
889
890unsigned clang_defaultCodeCompleteOptions(void) {
891 return CXCodeComplete_IncludeMacros;
892}
893
894void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {
895 if (!ResultsIn)
896 return;
897
898 AllocatedCXCodeCompleteResults *Results
899 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
900 delete Results;
901}
902
903unsigned
904clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) {
905 AllocatedCXCodeCompleteResults *Results
906 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
907 if (!Results)
908 return 0;
909
910 return Results->Diagnostics.size();
911}
912
913CXDiagnostic
914clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
915 unsigned Index) {
916 AllocatedCXCodeCompleteResults *Results
917 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
918 if (!Results || Index >= Results->Diagnostics.size())
919 return nullptr;
920
921 CXStoredDiagnostic *Diag = Results->DiagnosticsWrappers[Index].get();
922 if (!Diag)
923 Diag = (Results->DiagnosticsWrappers[Index] =
924 std::make_unique<CXStoredDiagnostic>(
925 args&: Results->Diagnostics[Index], args&: Results->LangOpts))
926 .get();
927 return Diag;
928}
929
930unsigned long long
931clang_codeCompleteGetContexts(CXCodeCompleteResults *ResultsIn) {
932 AllocatedCXCodeCompleteResults *Results
933 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
934 if (!Results)
935 return 0;
936
937 return Results->Contexts;
938}
939
940enum CXCursorKind clang_codeCompleteGetContainerKind(
941 CXCodeCompleteResults *ResultsIn,
942 unsigned *IsIncomplete) {
943 AllocatedCXCodeCompleteResults *Results =
944 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
945 if (!Results)
946 return CXCursor_InvalidCode;
947
948 if (IsIncomplete != nullptr) {
949 *IsIncomplete = Results->ContainerIsIncomplete;
950 }
951
952 return Results->ContainerKind;
953}
954
955CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
956 AllocatedCXCodeCompleteResults *Results =
957 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
958 if (!Results)
959 return cxstring::createEmpty();
960
961 return cxstring::createRef(String: Results->ContainerUSR.c_str());
962}
963
964
965CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
966 AllocatedCXCodeCompleteResults *Results =
967 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
968 if (!Results)
969 return cxstring::createEmpty();
970
971 return cxstring::createDup(String: Results->Selector);
972}
973
974/// Simple utility function that appends a \p New string to the given
975/// \p Old string, using the \p Buffer for storage.
976///
977/// \param Old The string to which we are appending. This parameter will be
978/// updated to reflect the complete string.
979///
980///
981/// \param New The string to append to \p Old.
982///
983/// \param Buffer A buffer that stores the actual, concatenated string. It will
984/// be used if the old string is already-non-empty.
985static void AppendToString(StringRef &Old, StringRef New,
986 SmallString<256> &Buffer) {
987 if (Old.empty()) {
988 Old = New;
989 return;
990 }
991
992 if (Buffer.empty())
993 Buffer.append(in_start: Old.begin(), in_end: Old.end());
994 Buffer.append(in_start: New.begin(), in_end: New.end());
995 Old = Buffer.str();
996}
997
998/// Get the typed-text blocks from the given code-completion string
999/// and return them as a single string.
1000///
1001/// \param String The code-completion string whose typed-text blocks will be
1002/// concatenated.
1003///
1004/// \param Buffer A buffer used for storage of the completed name.
1005static StringRef GetTypedName(CodeCompletionString *String,
1006 SmallString<256> &Buffer) {
1007 StringRef Result;
1008 for (CodeCompletionString::iterator C = String->begin(), CEnd = String->end();
1009 C != CEnd; ++C) {
1010 if (C->Kind == CodeCompletionString::CK_TypedText)
1011 AppendToString(Old&: Result, New: C->Text, Buffer);
1012 }
1013
1014 return Result;
1015}
1016
1017namespace {
1018 struct OrderCompletionResults {
1019 bool operator()(const CXCompletionResult &XR,
1020 const CXCompletionResult &YR) const {
1021 CodeCompletionString *X
1022 = (CodeCompletionString *)XR.CompletionString;
1023 CodeCompletionString *Y
1024 = (CodeCompletionString *)YR.CompletionString;
1025
1026 SmallString<256> XBuffer;
1027 StringRef XText = GetTypedName(String: X, Buffer&: XBuffer);
1028 SmallString<256> YBuffer;
1029 StringRef YText = GetTypedName(String: Y, Buffer&: YBuffer);
1030
1031 if (XText.empty() || YText.empty())
1032 return !XText.empty();
1033
1034 int result = XText.compare_insensitive(RHS: YText);
1035 if (result < 0)
1036 return true;
1037 if (result > 0)
1038 return false;
1039
1040 result = XText.compare(RHS: YText);
1041 return result < 0;
1042 }
1043 };
1044}
1045
1046void clang_sortCodeCompletionResults(CXCompletionResult *Results,
1047 unsigned NumResults) {
1048 std::stable_sort(first: Results, last: Results + NumResults, comp: OrderCompletionResults());
1049}
1050

source code of clang/tools/libclang/CIndexCodeCompletion.cpp