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 "CIndexer.h"
15 #include "CIndexDiagnostic.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/Sema/CodeCompleteConsumer.h"
29 #include "clang/Sema/Sema.h"
30 #include "llvm/ADT/SmallString.h"
31 #include "llvm/ADT/StringExtras.h"
32 #include "llvm/Support/CrashRecoveryContext.h"
33 #include "llvm/Support/FileSystem.h"
34 #include "llvm/Support/FormatVariadic.h"
35 #include "llvm/Support/MemoryBuffer.h"
36 #include "llvm/Support/Program.h"
37 #include "llvm/Support/Timer.h"
38 #include "llvm/Support/raw_ostream.h"
39 #include <atomic>
40 #include <cstdio>
41 #include <cstdlib>
42 #include <string>
43
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
53 using namespace clang;
54 using namespace clang::cxindex;
55
56 enum CXCompletionChunkKind
clang_getCompletionChunkKind(CXCompletionString completion_string,unsigned chunk_number)57 clang_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
clang_getCompletionChunkText(CXCompletionString completion_string,unsigned chunk_number)111 CXString 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((*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
149 CXCompletionString
clang_getCompletionChunkCompletionString(CXCompletionString completion_string,unsigned chunk_number)150 clang_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
clang_getNumCompletionChunks(CXCompletionString completion_string)187 unsigned clang_getNumCompletionChunks(CXCompletionString completion_string) {
188 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
189 return CCStr? CCStr->size() : 0;
190 }
191
clang_getCompletionPriority(CXCompletionString completion_string)192 unsigned clang_getCompletionPriority(CXCompletionString completion_string) {
193 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
194 return CCStr? CCStr->getPriority() : unsigned(CCP_Unlikely);
195 }
196
197 enum CXAvailabilityKind
clang_getCompletionAvailability(CXCompletionString completion_string)198 clang_getCompletionAvailability(CXCompletionString completion_string) {
199 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
200 return CCStr? static_cast<CXAvailabilityKind>(CCStr->getAvailability())
201 : CXAvailability_Available;
202 }
203
clang_getCompletionNumAnnotations(CXCompletionString completion_string)204 unsigned clang_getCompletionNumAnnotations(CXCompletionString completion_string)
205 {
206 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
207 return CCStr ? CCStr->getAnnotationCount() : 0;
208 }
209
clang_getCompletionAnnotation(CXCompletionString completion_string,unsigned annotation_number)210 CXString clang_getCompletionAnnotation(CXCompletionString completion_string,
211 unsigned annotation_number) {
212 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
213 return CCStr ? cxstring::createRef(CCStr->getAnnotation(annotation_number))
214 : cxstring::createNull();
215 }
216
217 CXString
clang_getCompletionParent(CXCompletionString completion_string,CXCursorKind * kind)218 clang_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(CCStr->getParentContextName());
228 }
229
230 CXString
clang_getCompletionBriefComment(CXCompletionString completion_string)231 clang_getCompletionBriefComment(CXCompletionString completion_string) {
232 CodeCompletionString *CCStr = (CodeCompletionString *)completion_string;
233
234 if (!CCStr)
235 return cxstring::createNull();
236
237 return cxstring::createRef(CCStr->getBriefComment());
238 }
239
240 namespace {
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.
249 struct 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
clang_getCompletionNumFixIts(CXCodeCompleteResults * results,unsigned completion_index)312 unsigned 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
clang_getCompletionFixIt(CXCodeCompleteResults * results,unsigned completion_index,unsigned fixit_index,CXSourceRange * replacement_range)322 CXString 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 *allocated_results->SourceMgr, allocated_results->LangOpts,
345 FixIt.RemoveRange);
346 }
347
348 return cxstring::createRef(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.
355 static std::atomic<unsigned> CodeCompletionResultObjects;
356
AllocatedCXCodeCompleteResults(IntrusiveRefCntPtr<FileManager> FileMgr)357 AllocatedCXCodeCompleteResults::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("LIBCLANG_OBJTRACKING"))
369 fprintf(stderr, "+++ %u completion results\n",
370 ++CodeCompletionResultObjects);
371 }
372
~AllocatedCXCodeCompleteResults()373 AllocatedCXCodeCompleteResults::~AllocatedCXCodeCompleteResults() {
374 delete [] Results;
375
376 for (unsigned I = 0, N = TemporaryBuffers.size(); I != N; ++I)
377 delete TemporaryBuffers[I];
378
379 if (getenv("LIBCLANG_OBJTRACKING"))
380 fprintf(stderr, "--- %u completion results\n",
381 --CodeCompletionResultObjects);
382 }
383
getContextsForContextKind(enum CodeCompletionContext::Kind kind,Sema & S)384 static 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_NewName:
541 case CodeCompletionContext::CCC_MacroName:
542 case CodeCompletionContext::CCC_PreprocessorExpression:
543 case CodeCompletionContext::CCC_PreprocessorDirective:
544 case CodeCompletionContext::CCC_Attribute:
545 case CodeCompletionContext::CCC_TypeQualifiers: {
546 //Only Clang results should be accepted, so we'll set all of the other
547 //context bits to 0 (i.e. the empty set)
548 contexts = CXCompletionContext_Unexposed;
549 break;
550 }
551 case CodeCompletionContext::CCC_Recovery: {
552 //We don't know what the current context is, so we'll return unknown
553 //This is the equivalent of setting all of the other context bits
554 contexts = CXCompletionContext_Unknown;
555 break;
556 }
557 }
558 return contexts;
559 }
560
561 namespace {
562 class CaptureCompletionResults : public CodeCompleteConsumer {
563 AllocatedCXCodeCompleteResults &AllocatedResults;
564 CodeCompletionTUInfo CCTUInfo;
565 SmallVector<CXCompletionResult, 16> StoredResults;
566 CXTranslationUnit *TU;
567 public:
CaptureCompletionResults(const CodeCompleteOptions & Opts,AllocatedCXCodeCompleteResults & Results,CXTranslationUnit * TranslationUnit)568 CaptureCompletionResults(const CodeCompleteOptions &Opts,
569 AllocatedCXCodeCompleteResults &Results,
570 CXTranslationUnit *TranslationUnit)
571 : CodeCompleteConsumer(Opts), AllocatedResults(Results),
572 CCTUInfo(Results.CodeCompletionAllocator), TU(TranslationUnit) {}
~CaptureCompletionResults()573 ~CaptureCompletionResults() override { Finish(); }
574
ProcessCodeCompleteResults(Sema & S,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)575 void ProcessCodeCompleteResults(Sema &S,
576 CodeCompletionContext Context,
577 CodeCompletionResult *Results,
578 unsigned NumResults) override {
579 StoredResults.reserve(StoredResults.size() + NumResults);
580 if (includeFixIts())
581 AllocatedResults.FixItsVector.reserve(NumResults);
582 for (unsigned I = 0; I != NumResults; ++I) {
583 CodeCompletionString *StoredCompletion
584 = Results[I].CreateCodeCompletionString(S, Context, getAllocator(),
585 getCodeCompletionTUInfo(),
586 includeBriefComments());
587
588 CXCompletionResult R;
589 R.CursorKind = Results[I].CursorKind;
590 R.CompletionString = StoredCompletion;
591 StoredResults.push_back(R);
592 if (includeFixIts())
593 AllocatedResults.FixItsVector.emplace_back(std::move(Results[I].FixIts));
594 }
595
596 enum CodeCompletionContext::Kind contextKind = Context.getKind();
597
598 AllocatedResults.ContextKind = contextKind;
599 AllocatedResults.Contexts = getContextsForContextKind(contextKind, S);
600
601 AllocatedResults.Selector = "";
602 ArrayRef<IdentifierInfo *> SelIdents = Context.getSelIdents();
603 for (ArrayRef<IdentifierInfo *>::iterator I = SelIdents.begin(),
604 E = SelIdents.end();
605 I != E; ++I) {
606 if (IdentifierInfo *selIdent = *I)
607 AllocatedResults.Selector += selIdent->getName();
608 AllocatedResults.Selector += ":";
609 }
610
611 QualType baseType = Context.getBaseType();
612 NamedDecl *D = nullptr;
613
614 if (!baseType.isNull()) {
615 // Get the declaration for a class/struct/union/enum type
616 if (const TagType *Tag = baseType->getAs<TagType>())
617 D = Tag->getDecl();
618 // Get the @interface declaration for a (possibly-qualified) Objective-C
619 // object pointer type, e.g., NSString*
620 else if (const ObjCObjectPointerType *ObjPtr =
621 baseType->getAs<ObjCObjectPointerType>())
622 D = ObjPtr->getInterfaceDecl();
623 // Get the @interface declaration for an Objective-C object type
624 else if (const ObjCObjectType *Obj = baseType->getAs<ObjCObjectType>())
625 D = Obj->getInterface();
626 // Get the class for a C++ injected-class-name
627 else if (const InjectedClassNameType *Injected =
628 baseType->getAs<InjectedClassNameType>())
629 D = Injected->getDecl();
630 }
631
632 if (D != nullptr) {
633 CXCursor cursor = cxcursor::MakeCXCursor(D, *TU);
634
635 AllocatedResults.ContainerKind = clang_getCursorKind(cursor);
636
637 CXString CursorUSR = clang_getCursorUSR(cursor);
638 AllocatedResults.ContainerUSR = clang_getCString(CursorUSR);
639 clang_disposeString(CursorUSR);
640
641 const Type *type = baseType.getTypePtrOrNull();
642 if (type) {
643 AllocatedResults.ContainerIsIncomplete = type->isIncompleteType();
644 }
645 else {
646 AllocatedResults.ContainerIsIncomplete = 1;
647 }
648 }
649 else {
650 AllocatedResults.ContainerKind = CXCursor_InvalidCode;
651 AllocatedResults.ContainerUSR.clear();
652 AllocatedResults.ContainerIsIncomplete = 1;
653 }
654 }
655
ProcessOverloadCandidates(Sema & S,unsigned CurrentArg,OverloadCandidate * Candidates,unsigned NumCandidates,SourceLocation OpenParLoc,bool Braced)656 void ProcessOverloadCandidates(Sema &S, unsigned CurrentArg,
657 OverloadCandidate *Candidates,
658 unsigned NumCandidates,
659 SourceLocation OpenParLoc,
660 bool Braced) override {
661 StoredResults.reserve(StoredResults.size() + NumCandidates);
662 for (unsigned I = 0; I != NumCandidates; ++I) {
663 CodeCompletionString *StoredCompletion =
664 Candidates[I].CreateSignatureString(CurrentArg, S, getAllocator(),
665 getCodeCompletionTUInfo(),
666 includeBriefComments(), Braced);
667
668 CXCompletionResult R;
669 R.CursorKind = CXCursor_OverloadCandidate;
670 R.CompletionString = StoredCompletion;
671 StoredResults.push_back(R);
672 }
673 }
674
getAllocator()675 CodeCompletionAllocator &getAllocator() override {
676 return *AllocatedResults.CodeCompletionAllocator;
677 }
678
getCodeCompletionTUInfo()679 CodeCompletionTUInfo &getCodeCompletionTUInfo() override { return CCTUInfo;}
680
681 private:
Finish()682 void Finish() {
683 AllocatedResults.Results = new CXCompletionResult [StoredResults.size()];
684 AllocatedResults.NumResults = StoredResults.size();
685 std::memcpy(AllocatedResults.Results, StoredResults.data(),
686 StoredResults.size() * sizeof(CXCompletionResult));
687 StoredResults.clear();
688 }
689 };
690 }
691
692 static CXCodeCompleteResults *
clang_codeCompleteAt_Impl(CXTranslationUnit TU,const char * complete_filename,unsigned complete_line,unsigned complete_column,ArrayRef<CXUnsavedFile> unsaved_files,unsigned options)693 clang_codeCompleteAt_Impl(CXTranslationUnit TU, const char *complete_filename,
694 unsigned complete_line, unsigned complete_column,
695 ArrayRef<CXUnsavedFile> unsaved_files,
696 unsigned options) {
697 bool IncludeBriefComments = options & CXCodeComplete_IncludeBriefComments;
698 bool SkipPreamble = options & CXCodeComplete_SkipPreamble;
699 bool IncludeFixIts = options & CXCodeComplete_IncludeCompletionsWithFixIts;
700
701 #ifdef UDP_CODE_COMPLETION_LOGGER
702 #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
703 const llvm::TimeRecord &StartTime = llvm::TimeRecord::getCurrentTime();
704 #endif
705 #endif
706 bool EnableLogging = getenv("LIBCLANG_CODE_COMPLETION_LOGGING") != nullptr;
707
708 if (cxtu::isNotUsableTU(TU)) {
709 LOG_BAD_TU(TU);
710 return nullptr;
711 }
712
713 ASTUnit *AST = cxtu::getASTUnit(TU);
714 if (!AST)
715 return nullptr;
716
717 CIndexer *CXXIdx = TU->CIdx;
718 if (CXXIdx->isOptEnabled(CXGlobalOpt_ThreadBackgroundPriorityForEditing))
719 setThreadBackgroundPriority();
720
721 ASTUnit::ConcurrencyCheck Check(*AST);
722
723 // Perform the remapping of source files.
724 SmallVector<ASTUnit::RemappedFile, 4> RemappedFiles;
725
726 for (auto &UF : unsaved_files) {
727 std::unique_ptr<llvm::MemoryBuffer> MB =
728 llvm::MemoryBuffer::getMemBufferCopy(getContents(UF), UF.Filename);
729 RemappedFiles.push_back(std::make_pair(UF.Filename, MB.release()));
730 }
731
732 if (EnableLogging) {
733 // FIXME: Add logging.
734 }
735
736 // Parse the resulting source file to find code-completion results.
737 AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults(
738 &AST->getFileManager());
739 Results->Results = nullptr;
740 Results->NumResults = 0;
741
742 // Create a code-completion consumer to capture the results.
743 CodeCompleteOptions Opts;
744 Opts.IncludeBriefComments = IncludeBriefComments;
745 Opts.LoadExternal = !SkipPreamble;
746 Opts.IncludeFixIts = IncludeFixIts;
747 CaptureCompletionResults Capture(Opts, *Results, &TU);
748
749 // Perform completion.
750 std::vector<const char *> CArgs;
751 for (const auto &Arg : TU->Arguments)
752 CArgs.push_back(Arg.c_str());
753 std::string CompletionInvocation =
754 llvm::formatv("-code-completion-at={0}:{1}:{2}", complete_filename,
755 complete_line, complete_column)
756 .str();
757 LibclangInvocationReporter InvocationReporter(
758 *CXXIdx, LibclangInvocationReporter::OperationKind::CompletionOperation,
759 TU->ParsingOptions, CArgs, CompletionInvocation, unsaved_files);
760 AST->CodeComplete(complete_filename, complete_line, complete_column,
761 RemappedFiles, (options & CXCodeComplete_IncludeMacros),
762 (options & CXCodeComplete_IncludeCodePatterns),
763 IncludeBriefComments, Capture,
764 CXXIdx->getPCHContainerOperations(), *Results->Diag,
765 Results->LangOpts, *Results->SourceMgr, *Results->FileMgr,
766 Results->Diagnostics, Results->TemporaryBuffers);
767
768 Results->DiagnosticsWrappers.resize(Results->Diagnostics.size());
769
770 // Keep a reference to the allocator used for cached global completions, so
771 // that we can be sure that the memory used by our code completion strings
772 // doesn't get freed due to subsequent reparses (while the code completion
773 // results are still active).
774 Results->CachedCompletionAllocator = AST->getCachedCompletionAllocator();
775
776
777
778 #ifdef UDP_CODE_COMPLETION_LOGGER
779 #ifdef UDP_CODE_COMPLETION_LOGGER_PORT
780 const llvm::TimeRecord &EndTime = llvm::TimeRecord::getCurrentTime();
781 SmallString<256> LogResult;
782 llvm::raw_svector_ostream os(LogResult);
783
784 // Figure out the language and whether or not it uses PCH.
785 const char *lang = 0;
786 bool usesPCH = false;
787
788 for (std::vector<const char*>::iterator I = argv.begin(), E = argv.end();
789 I != E; ++I) {
790 if (*I == 0)
791 continue;
792 if (strcmp(*I, "-x") == 0) {
793 if (I + 1 != E) {
794 lang = *(++I);
795 continue;
796 }
797 }
798 else if (strcmp(*I, "-include") == 0) {
799 if (I+1 != E) {
800 const char *arg = *(++I);
801 SmallString<512> pchName;
802 {
803 llvm::raw_svector_ostream os(pchName);
804 os << arg << ".pth";
805 }
806 pchName.push_back('\0');
807 llvm::sys::fs::file_status stat_results;
808 if (!llvm::sys::fs::status(pchName, stat_results))
809 usesPCH = true;
810 continue;
811 }
812 }
813 }
814
815 os << "{ ";
816 os << "\"wall\": " << (EndTime.getWallTime() - StartTime.getWallTime());
817 os << ", \"numRes\": " << Results->NumResults;
818 os << ", \"diags\": " << Results->Diagnostics.size();
819 os << ", \"pch\": " << (usesPCH ? "true" : "false");
820 os << ", \"lang\": \"" << (lang ? lang : "<unknown>") << '"';
821 const char *name = getlogin();
822 os << ", \"user\": \"" << (name ? name : "unknown") << '"';
823 os << ", \"clangVer\": \"" << getClangFullVersion() << '"';
824 os << " }";
825
826 StringRef res = os.str();
827 if (res.size() > 0) {
828 do {
829 // Setup the UDP socket.
830 struct sockaddr_in servaddr;
831 bzero(&servaddr, sizeof(servaddr));
832 servaddr.sin_family = AF_INET;
833 servaddr.sin_port = htons(UDP_CODE_COMPLETION_LOGGER_PORT);
834 if (inet_pton(AF_INET, UDP_CODE_COMPLETION_LOGGER,
835 &servaddr.sin_addr) <= 0)
836 break;
837
838 int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
839 if (sockfd < 0)
840 break;
841
842 sendto(sockfd, res.data(), res.size(), 0,
843 (struct sockaddr *)&servaddr, sizeof(servaddr));
844 close(sockfd);
845 }
846 while (false);
847 }
848 #endif
849 #endif
850 return Results;
851 }
852
clang_codeCompleteAt(CXTranslationUnit TU,const char * complete_filename,unsigned complete_line,unsigned complete_column,struct CXUnsavedFile * unsaved_files,unsigned num_unsaved_files,unsigned options)853 CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU,
854 const char *complete_filename,
855 unsigned complete_line,
856 unsigned complete_column,
857 struct CXUnsavedFile *unsaved_files,
858 unsigned num_unsaved_files,
859 unsigned options) {
860 LOG_FUNC_SECTION {
861 *Log << TU << ' '
862 << complete_filename << ':' << complete_line << ':' << complete_column;
863 }
864
865 if (num_unsaved_files && !unsaved_files)
866 return nullptr;
867
868 CXCodeCompleteResults *result;
869 auto CodeCompleteAtImpl = [=, &result]() {
870 result = clang_codeCompleteAt_Impl(
871 TU, complete_filename, complete_line, complete_column,
872 llvm::ArrayRef(unsaved_files, num_unsaved_files), options);
873 };
874
875 llvm::CrashRecoveryContext CRC;
876
877 if (!RunSafely(CRC, CodeCompleteAtImpl)) {
878 fprintf(stderr, "libclang: crash detected in code completion\n");
879 cxtu::getASTUnit(TU)->setUnsafeToFree(true);
880 return nullptr;
881 } else if (getenv("LIBCLANG_RESOURCE_USAGE"))
882 PrintLibclangResourceUsage(TU);
883
884 return result;
885 }
886
clang_defaultCodeCompleteOptions(void)887 unsigned clang_defaultCodeCompleteOptions(void) {
888 return CXCodeComplete_IncludeMacros;
889 }
890
clang_disposeCodeCompleteResults(CXCodeCompleteResults * ResultsIn)891 void clang_disposeCodeCompleteResults(CXCodeCompleteResults *ResultsIn) {
892 if (!ResultsIn)
893 return;
894
895 AllocatedCXCodeCompleteResults *Results
896 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
897 delete Results;
898 }
899
900 unsigned
clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults * ResultsIn)901 clang_codeCompleteGetNumDiagnostics(CXCodeCompleteResults *ResultsIn) {
902 AllocatedCXCodeCompleteResults *Results
903 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
904 if (!Results)
905 return 0;
906
907 return Results->Diagnostics.size();
908 }
909
910 CXDiagnostic
clang_codeCompleteGetDiagnostic(CXCodeCompleteResults * ResultsIn,unsigned Index)911 clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *ResultsIn,
912 unsigned Index) {
913 AllocatedCXCodeCompleteResults *Results
914 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
915 if (!Results || Index >= Results->Diagnostics.size())
916 return nullptr;
917
918 CXStoredDiagnostic *Diag = Results->DiagnosticsWrappers[Index].get();
919 if (!Diag)
920 Diag = (Results->DiagnosticsWrappers[Index] =
921 std::make_unique<CXStoredDiagnostic>(
922 Results->Diagnostics[Index], Results->LangOpts))
923 .get();
924 return Diag;
925 }
926
927 unsigned long long
clang_codeCompleteGetContexts(CXCodeCompleteResults * ResultsIn)928 clang_codeCompleteGetContexts(CXCodeCompleteResults *ResultsIn) {
929 AllocatedCXCodeCompleteResults *Results
930 = static_cast<AllocatedCXCodeCompleteResults*>(ResultsIn);
931 if (!Results)
932 return 0;
933
934 return Results->Contexts;
935 }
936
clang_codeCompleteGetContainerKind(CXCodeCompleteResults * ResultsIn,unsigned * IsIncomplete)937 enum CXCursorKind clang_codeCompleteGetContainerKind(
938 CXCodeCompleteResults *ResultsIn,
939 unsigned *IsIncomplete) {
940 AllocatedCXCodeCompleteResults *Results =
941 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
942 if (!Results)
943 return CXCursor_InvalidCode;
944
945 if (IsIncomplete != nullptr) {
946 *IsIncomplete = Results->ContainerIsIncomplete;
947 }
948
949 return Results->ContainerKind;
950 }
951
clang_codeCompleteGetContainerUSR(CXCodeCompleteResults * ResultsIn)952 CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *ResultsIn) {
953 AllocatedCXCodeCompleteResults *Results =
954 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
955 if (!Results)
956 return cxstring::createEmpty();
957
958 return cxstring::createRef(Results->ContainerUSR.c_str());
959 }
960
961
clang_codeCompleteGetObjCSelector(CXCodeCompleteResults * ResultsIn)962 CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *ResultsIn) {
963 AllocatedCXCodeCompleteResults *Results =
964 static_cast<AllocatedCXCodeCompleteResults *>(ResultsIn);
965 if (!Results)
966 return cxstring::createEmpty();
967
968 return cxstring::createDup(Results->Selector);
969 }
970
971 /// Simple utility function that appends a \p New string to the given
972 /// \p Old string, using the \p Buffer for storage.
973 ///
974 /// \param Old The string to which we are appending. This parameter will be
975 /// updated to reflect the complete string.
976 ///
977 ///
978 /// \param New The string to append to \p Old.
979 ///
980 /// \param Buffer A buffer that stores the actual, concatenated string. It will
981 /// be used if the old string is already-non-empty.
AppendToString(StringRef & Old,StringRef New,SmallString<256> & Buffer)982 static void AppendToString(StringRef &Old, StringRef New,
983 SmallString<256> &Buffer) {
984 if (Old.empty()) {
985 Old = New;
986 return;
987 }
988
989 if (Buffer.empty())
990 Buffer.append(Old.begin(), Old.end());
991 Buffer.append(New.begin(), New.end());
992 Old = Buffer.str();
993 }
994
995 /// Get the typed-text blocks from the given code-completion string
996 /// and return them as a single string.
997 ///
998 /// \param String The code-completion string whose typed-text blocks will be
999 /// concatenated.
1000 ///
1001 /// \param Buffer A buffer used for storage of the completed name.
GetTypedName(CodeCompletionString * String,SmallString<256> & Buffer)1002 static StringRef GetTypedName(CodeCompletionString *String,
1003 SmallString<256> &Buffer) {
1004 StringRef Result;
1005 for (CodeCompletionString::iterator C = String->begin(), CEnd = String->end();
1006 C != CEnd; ++C) {
1007 if (C->Kind == CodeCompletionString::CK_TypedText)
1008 AppendToString(Result, C->Text, Buffer);
1009 }
1010
1011 return Result;
1012 }
1013
1014 namespace {
1015 struct OrderCompletionResults {
operator ()__anona55d30fc0411::OrderCompletionResults1016 bool operator()(const CXCompletionResult &XR,
1017 const CXCompletionResult &YR) const {
1018 CodeCompletionString *X
1019 = (CodeCompletionString *)XR.CompletionString;
1020 CodeCompletionString *Y
1021 = (CodeCompletionString *)YR.CompletionString;
1022
1023 SmallString<256> XBuffer;
1024 StringRef XText = GetTypedName(X, XBuffer);
1025 SmallString<256> YBuffer;
1026 StringRef YText = GetTypedName(Y, YBuffer);
1027
1028 if (XText.empty() || YText.empty())
1029 return !XText.empty();
1030
1031 int result = XText.compare_insensitive(YText);
1032 if (result < 0)
1033 return true;
1034 if (result > 0)
1035 return false;
1036
1037 result = XText.compare(YText);
1038 return result < 0;
1039 }
1040 };
1041 }
1042
clang_sortCodeCompletionResults(CXCompletionResult * Results,unsigned NumResults)1043 void clang_sortCodeCompletionResults(CXCompletionResult *Results,
1044 unsigned NumResults) {
1045 std::stable_sort(Results, Results + NumResults, OrderCompletionResults());
1046 }
1047