1 //===- CodeCompleteConsumer.cpp - Code Completion Interface ---------------===//
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 CodeCompleteConsumer class.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "clang/Sema/CodeCompleteConsumer.h"
14 #include "clang-c/Index.h"
15 #include "clang/AST/Decl.h"
16 #include "clang/AST/DeclBase.h"
17 #include "clang/AST/DeclObjC.h"
18 #include "clang/AST/DeclTemplate.h"
19 #include "clang/AST/DeclarationName.h"
20 #include "clang/AST/Type.h"
21 #include "clang/Basic/IdentifierTable.h"
22 #include "clang/Lex/Preprocessor.h"
23 #include "clang/Sema/Sema.h"
24 #include "llvm/ADT/SmallString.h"
25 #include "llvm/ADT/SmallVector.h"
26 #include "llvm/ADT/StringExtras.h"
27 #include "llvm/ADT/StringRef.h"
28 #include "llvm/ADT/Twine.h"
29 #include "llvm/Support/Casting.h"
30 #include "llvm/Support/Compiler.h"
31 #include "llvm/Support/ErrorHandling.h"
32 #include "llvm/Support/FormatVariadic.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include <algorithm>
35 #include <cassert>
36 #include <cstdint>
37 #include <string>
38
39 using namespace clang;
40
41 //===----------------------------------------------------------------------===//
42 // Code completion context implementation
43 //===----------------------------------------------------------------------===//
44
wantConstructorResults() const45 bool CodeCompletionContext::wantConstructorResults() const {
46 switch (CCKind) {
47 case CCC_Recovery:
48 case CCC_Statement:
49 case CCC_Expression:
50 case CCC_ObjCMessageReceiver:
51 case CCC_ParenthesizedExpression:
52 case CCC_Symbol:
53 case CCC_SymbolOrNewName:
54 return true;
55
56 case CCC_TopLevel:
57 case CCC_ObjCInterface:
58 case CCC_ObjCImplementation:
59 case CCC_ObjCIvarList:
60 case CCC_ClassStructUnion:
61 case CCC_DotMemberAccess:
62 case CCC_ArrowMemberAccess:
63 case CCC_ObjCPropertyAccess:
64 case CCC_EnumTag:
65 case CCC_UnionTag:
66 case CCC_ClassOrStructTag:
67 case CCC_ObjCProtocolName:
68 case CCC_Namespace:
69 case CCC_Type:
70 case CCC_NewName:
71 case CCC_MacroName:
72 case CCC_MacroNameUse:
73 case CCC_PreprocessorExpression:
74 case CCC_PreprocessorDirective:
75 case CCC_NaturalLanguage:
76 case CCC_SelectorName:
77 case CCC_TypeQualifiers:
78 case CCC_Other:
79 case CCC_OtherWithMacros:
80 case CCC_ObjCInstanceMessage:
81 case CCC_ObjCClassMessage:
82 case CCC_ObjCInterfaceName:
83 case CCC_ObjCCategoryName:
84 case CCC_IncludedFile:
85 return false;
86 }
87
88 llvm_unreachable("Invalid CodeCompletionContext::Kind!");
89 }
90
getCompletionKindString(CodeCompletionContext::Kind Kind)91 StringRef clang::getCompletionKindString(CodeCompletionContext::Kind Kind) {
92 using CCKind = CodeCompletionContext::Kind;
93 switch (Kind) {
94 case CCKind::CCC_Other:
95 return "Other";
96 case CCKind::CCC_OtherWithMacros:
97 return "OtherWithMacros";
98 case CCKind::CCC_TopLevel:
99 return "TopLevel";
100 case CCKind::CCC_ObjCInterface:
101 return "ObjCInterface";
102 case CCKind::CCC_ObjCImplementation:
103 return "ObjCImplementation";
104 case CCKind::CCC_ObjCIvarList:
105 return "ObjCIvarList";
106 case CCKind::CCC_ClassStructUnion:
107 return "ClassStructUnion";
108 case CCKind::CCC_Statement:
109 return "Statement";
110 case CCKind::CCC_Expression:
111 return "Expression";
112 case CCKind::CCC_ObjCMessageReceiver:
113 return "ObjCMessageReceiver";
114 case CCKind::CCC_DotMemberAccess:
115 return "DotMemberAccess";
116 case CCKind::CCC_ArrowMemberAccess:
117 return "ArrowMemberAccess";
118 case CCKind::CCC_ObjCPropertyAccess:
119 return "ObjCPropertyAccess";
120 case CCKind::CCC_EnumTag:
121 return "EnumTag";
122 case CCKind::CCC_UnionTag:
123 return "UnionTag";
124 case CCKind::CCC_ClassOrStructTag:
125 return "ClassOrStructTag";
126 case CCKind::CCC_ObjCProtocolName:
127 return "ObjCProtocolName";
128 case CCKind::CCC_Namespace:
129 return "Namespace";
130 case CCKind::CCC_Type:
131 return "Type";
132 case CCKind::CCC_NewName:
133 return "NewName";
134 case CCKind::CCC_Symbol:
135 return "Symbol";
136 case CCKind::CCC_SymbolOrNewName:
137 return "SymbolOrNewName";
138 case CCKind::CCC_MacroName:
139 return "MacroName";
140 case CCKind::CCC_MacroNameUse:
141 return "MacroNameUse";
142 case CCKind::CCC_PreprocessorExpression:
143 return "PreprocessorExpression";
144 case CCKind::CCC_PreprocessorDirective:
145 return "PreprocessorDirective";
146 case CCKind::CCC_NaturalLanguage:
147 return "NaturalLanguage";
148 case CCKind::CCC_SelectorName:
149 return "SelectorName";
150 case CCKind::CCC_TypeQualifiers:
151 return "TypeQualifiers";
152 case CCKind::CCC_ParenthesizedExpression:
153 return "ParenthesizedExpression";
154 case CCKind::CCC_ObjCInstanceMessage:
155 return "ObjCInstanceMessage";
156 case CCKind::CCC_ObjCClassMessage:
157 return "ObjCClassMessage";
158 case CCKind::CCC_ObjCInterfaceName:
159 return "ObjCInterfaceName";
160 case CCKind::CCC_ObjCCategoryName:
161 return "ObjCCategoryName";
162 case CCKind::CCC_IncludedFile:
163 return "IncludedFile";
164 case CCKind::CCC_Recovery:
165 return "Recovery";
166 }
167 llvm_unreachable("Invalid CodeCompletionContext::Kind!");
168 }
169
170 //===----------------------------------------------------------------------===//
171 // Code completion string implementation
172 //===----------------------------------------------------------------------===//
173
Chunk(ChunkKind Kind,const char * Text)174 CodeCompletionString::Chunk::Chunk(ChunkKind Kind, const char *Text)
175 : Kind(Kind), Text("") {
176 switch (Kind) {
177 case CK_TypedText:
178 case CK_Text:
179 case CK_Placeholder:
180 case CK_Informative:
181 case CK_ResultType:
182 case CK_CurrentParameter:
183 this->Text = Text;
184 break;
185
186 case CK_Optional:
187 llvm_unreachable("Optional strings cannot be created from text");
188
189 case CK_LeftParen:
190 this->Text = "(";
191 break;
192
193 case CK_RightParen:
194 this->Text = ")";
195 break;
196
197 case CK_LeftBracket:
198 this->Text = "[";
199 break;
200
201 case CK_RightBracket:
202 this->Text = "]";
203 break;
204
205 case CK_LeftBrace:
206 this->Text = "{";
207 break;
208
209 case CK_RightBrace:
210 this->Text = "}";
211 break;
212
213 case CK_LeftAngle:
214 this->Text = "<";
215 break;
216
217 case CK_RightAngle:
218 this->Text = ">";
219 break;
220
221 case CK_Comma:
222 this->Text = ", ";
223 break;
224
225 case CK_Colon:
226 this->Text = ":";
227 break;
228
229 case CK_SemiColon:
230 this->Text = ";";
231 break;
232
233 case CK_Equal:
234 this->Text = " = ";
235 break;
236
237 case CK_HorizontalSpace:
238 this->Text = " ";
239 break;
240
241 case CK_VerticalSpace:
242 this->Text = "\n";
243 break;
244 }
245 }
246
247 CodeCompletionString::Chunk
CreateText(const char * Text)248 CodeCompletionString::Chunk::CreateText(const char *Text) {
249 return Chunk(CK_Text, Text);
250 }
251
252 CodeCompletionString::Chunk
CreateOptional(CodeCompletionString * Optional)253 CodeCompletionString::Chunk::CreateOptional(CodeCompletionString *Optional) {
254 Chunk Result;
255 Result.Kind = CK_Optional;
256 Result.Optional = Optional;
257 return Result;
258 }
259
260 CodeCompletionString::Chunk
CreatePlaceholder(const char * Placeholder)261 CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) {
262 return Chunk(CK_Placeholder, Placeholder);
263 }
264
265 CodeCompletionString::Chunk
CreateInformative(const char * Informative)266 CodeCompletionString::Chunk::CreateInformative(const char *Informative) {
267 return Chunk(CK_Informative, Informative);
268 }
269
270 CodeCompletionString::Chunk
CreateResultType(const char * ResultType)271 CodeCompletionString::Chunk::CreateResultType(const char *ResultType) {
272 return Chunk(CK_ResultType, ResultType);
273 }
274
CreateCurrentParameter(const char * CurrentParameter)275 CodeCompletionString::Chunk CodeCompletionString::Chunk::CreateCurrentParameter(
276 const char *CurrentParameter) {
277 return Chunk(CK_CurrentParameter, CurrentParameter);
278 }
279
CodeCompletionString(const Chunk * Chunks,unsigned NumChunks,unsigned Priority,CXAvailabilityKind Availability,const char ** Annotations,unsigned NumAnnotations,StringRef ParentName,const char * BriefComment)280 CodeCompletionString::CodeCompletionString(
281 const Chunk *Chunks, unsigned NumChunks, unsigned Priority,
282 CXAvailabilityKind Availability, const char **Annotations,
283 unsigned NumAnnotations, StringRef ParentName, const char *BriefComment)
284 : NumChunks(NumChunks), NumAnnotations(NumAnnotations), Priority(Priority),
285 Availability(Availability), ParentName(ParentName),
286 BriefComment(BriefComment) {
287 assert(NumChunks <= 0xffff);
288 assert(NumAnnotations <= 0xffff);
289
290 Chunk *StoredChunks = reinterpret_cast<Chunk *>(this + 1);
291 for (unsigned I = 0; I != NumChunks; ++I)
292 StoredChunks[I] = Chunks[I];
293
294 const char **StoredAnnotations =
295 reinterpret_cast<const char **>(StoredChunks + NumChunks);
296 for (unsigned I = 0; I != NumAnnotations; ++I)
297 StoredAnnotations[I] = Annotations[I];
298 }
299
getAnnotationCount() const300 unsigned CodeCompletionString::getAnnotationCount() const {
301 return NumAnnotations;
302 }
303
getAnnotation(unsigned AnnotationNr) const304 const char *CodeCompletionString::getAnnotation(unsigned AnnotationNr) const {
305 if (AnnotationNr < NumAnnotations)
306 return reinterpret_cast<const char *const *>(end())[AnnotationNr];
307 else
308 return nullptr;
309 }
310
getAsString() const311 std::string CodeCompletionString::getAsString() const {
312 std::string Result;
313 llvm::raw_string_ostream OS(Result);
314
315 for (const Chunk &C : *this) {
316 switch (C.Kind) {
317 case CK_Optional:
318 OS << "{#" << C.Optional->getAsString() << "#}";
319 break;
320 case CK_Placeholder:
321 OS << "<#" << C.Text << "#>";
322 break;
323 case CK_Informative:
324 case CK_ResultType:
325 OS << "[#" << C.Text << "#]";
326 break;
327 case CK_CurrentParameter:
328 OS << "<#" << C.Text << "#>";
329 break;
330 default:
331 OS << C.Text;
332 break;
333 }
334 }
335 return OS.str();
336 }
337
getTypedText() const338 const char *CodeCompletionString::getTypedText() const {
339 for (const Chunk &C : *this)
340 if (C.Kind == CK_TypedText)
341 return C.Text;
342
343 return nullptr;
344 }
345
CopyString(const Twine & String)346 const char *CodeCompletionAllocator::CopyString(const Twine &String) {
347 SmallString<128> Data;
348 StringRef Ref = String.toStringRef(Data);
349 // FIXME: It would be more efficient to teach Twine to tell us its size and
350 // then add a routine there to fill in an allocated char* with the contents
351 // of the string.
352 char *Mem = (char *)Allocate(Ref.size() + 1, 1);
353 std::copy(Ref.begin(), Ref.end(), Mem);
354 Mem[Ref.size()] = 0;
355 return Mem;
356 }
357
getParentName(const DeclContext * DC)358 StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) {
359 if (!isa<NamedDecl>(DC))
360 return {};
361
362 // Check whether we've already cached the parent name.
363 StringRef &CachedParentName = ParentNames[DC];
364 if (!CachedParentName.empty())
365 return CachedParentName;
366
367 // If we already processed this DeclContext and assigned empty to it, the
368 // data pointer will be non-null.
369 if (CachedParentName.data() != nullptr)
370 return {};
371
372 // Find the interesting names.
373 SmallVector<const DeclContext *, 2> Contexts;
374 while (DC && !DC->isFunctionOrMethod()) {
375 if (const auto *ND = dyn_cast<NamedDecl>(DC)) {
376 if (ND->getIdentifier())
377 Contexts.push_back(DC);
378 }
379
380 DC = DC->getParent();
381 }
382
383 {
384 SmallString<128> S;
385 llvm::raw_svector_ostream OS(S);
386 bool First = true;
387 for (unsigned I = Contexts.size(); I != 0; --I) {
388 if (First)
389 First = false;
390 else {
391 OS << "::";
392 }
393
394 const DeclContext *CurDC = Contexts[I - 1];
395 if (const auto *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
396 CurDC = CatImpl->getCategoryDecl();
397
398 if (const auto *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
399 const ObjCInterfaceDecl *Interface = Cat->getClassInterface();
400 if (!Interface) {
401 // Assign an empty StringRef but with non-null data to distinguish
402 // between empty because we didn't process the DeclContext yet.
403 CachedParentName = StringRef((const char *)(uintptr_t)~0U, 0);
404 return {};
405 }
406
407 OS << Interface->getName() << '(' << Cat->getName() << ')';
408 } else {
409 OS << cast<NamedDecl>(CurDC)->getName();
410 }
411 }
412
413 CachedParentName = AllocatorRef->CopyString(OS.str());
414 }
415
416 return CachedParentName;
417 }
418
TakeString()419 CodeCompletionString *CodeCompletionBuilder::TakeString() {
420 void *Mem = getAllocator().Allocate(
421 sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size() +
422 sizeof(const char *) * Annotations.size(),
423 alignof(CodeCompletionString));
424 CodeCompletionString *Result = new (Mem) CodeCompletionString(
425 Chunks.data(), Chunks.size(), Priority, Availability, Annotations.data(),
426 Annotations.size(), ParentName, BriefComment);
427 Chunks.clear();
428 return Result;
429 }
430
AddTypedTextChunk(const char * Text)431 void CodeCompletionBuilder::AddTypedTextChunk(const char *Text) {
432 Chunks.push_back(Chunk(CodeCompletionString::CK_TypedText, Text));
433 }
434
AddTextChunk(const char * Text)435 void CodeCompletionBuilder::AddTextChunk(const char *Text) {
436 Chunks.push_back(Chunk::CreateText(Text));
437 }
438
AddOptionalChunk(CodeCompletionString * Optional)439 void CodeCompletionBuilder::AddOptionalChunk(CodeCompletionString *Optional) {
440 Chunks.push_back(Chunk::CreateOptional(Optional));
441 }
442
AddPlaceholderChunk(const char * Placeholder)443 void CodeCompletionBuilder::AddPlaceholderChunk(const char *Placeholder) {
444 Chunks.push_back(Chunk::CreatePlaceholder(Placeholder));
445 }
446
AddInformativeChunk(const char * Text)447 void CodeCompletionBuilder::AddInformativeChunk(const char *Text) {
448 Chunks.push_back(Chunk::CreateInformative(Text));
449 }
450
AddResultTypeChunk(const char * ResultType)451 void CodeCompletionBuilder::AddResultTypeChunk(const char *ResultType) {
452 Chunks.push_back(Chunk::CreateResultType(ResultType));
453 }
454
AddCurrentParameterChunk(const char * CurrentParameter)455 void CodeCompletionBuilder::AddCurrentParameterChunk(
456 const char *CurrentParameter) {
457 Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter));
458 }
459
AddChunk(CodeCompletionString::ChunkKind CK,const char * Text)460 void CodeCompletionBuilder::AddChunk(CodeCompletionString::ChunkKind CK,
461 const char *Text) {
462 Chunks.push_back(Chunk(CK, Text));
463 }
464
addParentContext(const DeclContext * DC)465 void CodeCompletionBuilder::addParentContext(const DeclContext *DC) {
466 if (DC->isTranslationUnit())
467 return;
468
469 if (DC->isFunctionOrMethod())
470 return;
471
472 if (!isa<NamedDecl>(DC))
473 return;
474
475 ParentName = getCodeCompletionTUInfo().getParentName(DC);
476 }
477
addBriefComment(StringRef Comment)478 void CodeCompletionBuilder::addBriefComment(StringRef Comment) {
479 BriefComment = Allocator.CopyString(Comment);
480 }
481
482 //===----------------------------------------------------------------------===//
483 // Code completion overload candidate implementation
484 //===----------------------------------------------------------------------===//
getFunction() const485 FunctionDecl *CodeCompleteConsumer::OverloadCandidate::getFunction() const {
486 if (getKind() == CK_Function)
487 return Function;
488 else if (getKind() == CK_FunctionTemplate)
489 return FunctionTemplate->getTemplatedDecl();
490 else
491 return nullptr;
492 }
493
494 const FunctionType *
getFunctionType() const495 CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
496 switch (Kind) {
497 case CK_Function:
498 return Function->getType()->getAs<FunctionType>();
499
500 case CK_FunctionTemplate:
501 return FunctionTemplate->getTemplatedDecl()
502 ->getType()
503 ->getAs<FunctionType>();
504
505 case CK_FunctionType:
506 return Type;
507 }
508
509 llvm_unreachable("Invalid CandidateKind!");
510 }
511
512 //===----------------------------------------------------------------------===//
513 // Code completion consumer implementation
514 //===----------------------------------------------------------------------===//
515
516 CodeCompleteConsumer::~CodeCompleteConsumer() = default;
517
isResultFilteredOut(StringRef Filter,CodeCompletionResult Result)518 bool PrintingCodeCompleteConsumer::isResultFilteredOut(
519 StringRef Filter, CodeCompletionResult Result) {
520 switch (Result.Kind) {
521 case CodeCompletionResult::RK_Declaration:
522 return !(Result.Declaration->getIdentifier() &&
523 Result.Declaration->getIdentifier()->getName().startswith(Filter));
524 case CodeCompletionResult::RK_Keyword:
525 return !StringRef(Result.Keyword).startswith(Filter);
526 case CodeCompletionResult::RK_Macro:
527 return !Result.Macro->getName().startswith(Filter);
528 case CodeCompletionResult::RK_Pattern:
529 return !(Result.Pattern->getTypedText() &&
530 StringRef(Result.Pattern->getTypedText()).startswith(Filter));
531 }
532 llvm_unreachable("Unknown code completion result Kind.");
533 }
534
ProcessCodeCompleteResults(Sema & SemaRef,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)535 void PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(
536 Sema &SemaRef, CodeCompletionContext Context, CodeCompletionResult *Results,
537 unsigned NumResults) {
538 std::stable_sort(Results, Results + NumResults);
539
540 if (!Context.getPreferredType().isNull())
541 OS << "PREFERRED-TYPE: " << Context.getPreferredType().getAsString()
542 << "\n";
543
544 StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter();
545 // Print the completions.
546 for (unsigned I = 0; I != NumResults; ++I) {
547 if (!Filter.empty() && isResultFilteredOut(Filter, Results[I]))
548 continue;
549 OS << "COMPLETION: ";
550 switch (Results[I].Kind) {
551 case CodeCompletionResult::RK_Declaration:
552 OS << *Results[I].Declaration;
553 {
554 std::vector<std::string> Tags;
555 if (Results[I].Hidden)
556 Tags.push_back("Hidden");
557 if (Results[I].InBaseClass)
558 Tags.push_back("InBase");
559 if (Results[I].Availability ==
560 CXAvailabilityKind::CXAvailability_NotAccessible)
561 Tags.push_back("Inaccessible");
562 if (!Tags.empty())
563 OS << " (" << llvm::join(Tags, ",") << ")";
564 }
565 if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(
566 SemaRef, Context, getAllocator(), CCTUInfo,
567 includeBriefComments())) {
568 OS << " : " << CCS->getAsString();
569 if (const char *BriefComment = CCS->getBriefComment())
570 OS << " : " << BriefComment;
571 }
572 break;
573
574 case CodeCompletionResult::RK_Keyword:
575 OS << Results[I].Keyword;
576 break;
577
578 case CodeCompletionResult::RK_Macro:
579 OS << Results[I].Macro->getName();
580 if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(
581 SemaRef, Context, getAllocator(), CCTUInfo,
582 includeBriefComments())) {
583 OS << " : " << CCS->getAsString();
584 }
585 break;
586
587 case CodeCompletionResult::RK_Pattern:
588 OS << "Pattern : " << Results[I].Pattern->getAsString();
589 break;
590 }
591 for (const FixItHint &FixIt : Results[I].FixIts) {
592 const SourceLocation BLoc = FixIt.RemoveRange.getBegin();
593 const SourceLocation ELoc = FixIt.RemoveRange.getEnd();
594
595 SourceManager &SM = SemaRef.SourceMgr;
596 std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc);
597 std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(ELoc);
598 // Adjust for token ranges.
599 if (FixIt.RemoveRange.isTokenRange())
600 EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, SemaRef.LangOpts);
601
602 OS << " (requires fix-it:"
603 << " {" << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
604 << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
605 << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
606 << SM.getColumnNumber(EInfo.first, EInfo.second) << "}"
607 << " to \"" << FixIt.CodeToInsert << "\")";
608 }
609 OS << '\n';
610 }
611 }
612
613 // This function is used solely to preserve the former presentation of overloads
614 // by "clang -cc1 -code-completion-at", since CodeCompletionString::getAsString
615 // needs to be improved for printing the newer and more detailed overload
616 // chunks.
getOverloadAsString(const CodeCompletionString & CCS)617 static std::string getOverloadAsString(const CodeCompletionString &CCS) {
618 std::string Result;
619 llvm::raw_string_ostream OS(Result);
620
621 for (auto &C : CCS) {
622 switch (C.Kind) {
623 case CodeCompletionString::CK_Informative:
624 case CodeCompletionString::CK_ResultType:
625 OS << "[#" << C.Text << "#]";
626 break;
627
628 case CodeCompletionString::CK_CurrentParameter:
629 OS << "<#" << C.Text << "#>";
630 break;
631
632 // FIXME: We can also print optional parameters of an overload.
633 case CodeCompletionString::CK_Optional:
634 break;
635
636 default:
637 OS << C.Text;
638 break;
639 }
640 }
641 return OS.str();
642 }
643
ProcessOverloadCandidates(Sema & SemaRef,unsigned CurrentArg,OverloadCandidate * Candidates,unsigned NumCandidates,SourceLocation OpenParLoc)644 void PrintingCodeCompleteConsumer::ProcessOverloadCandidates(
645 Sema &SemaRef, unsigned CurrentArg, OverloadCandidate *Candidates,
646 unsigned NumCandidates, SourceLocation OpenParLoc) {
647 OS << "OPENING_PAREN_LOC: ";
648 OpenParLoc.print(OS, SemaRef.getSourceManager());
649 OS << "\n";
650
651 for (unsigned I = 0; I != NumCandidates; ++I) {
652 if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString(
653 CurrentArg, SemaRef, getAllocator(), CCTUInfo,
654 includeBriefComments())) {
655 OS << "OVERLOAD: " << getOverloadAsString(*CCS) << "\n";
656 }
657 }
658 }
659
660 /// Retrieve the effective availability of the given declaration.
getDeclAvailability(const Decl * D)661 static AvailabilityResult getDeclAvailability(const Decl *D) {
662 AvailabilityResult AR = D->getAvailability();
663 if (isa<EnumConstantDecl>(D))
664 AR = std::max(AR, cast<Decl>(D->getDeclContext())->getAvailability());
665 return AR;
666 }
667
computeCursorKindAndAvailability(bool Accessible)668 void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) {
669 switch (Kind) {
670 case RK_Pattern:
671 if (!Declaration) {
672 // Do nothing: Patterns can come with cursor kinds!
673 break;
674 }
675 LLVM_FALLTHROUGH;
676
677 case RK_Declaration: {
678 // Set the availability based on attributes.
679 switch (getDeclAvailability(Declaration)) {
680 case AR_Available:
681 case AR_NotYetIntroduced:
682 Availability = CXAvailability_Available;
683 break;
684
685 case AR_Deprecated:
686 Availability = CXAvailability_Deprecated;
687 break;
688
689 case AR_Unavailable:
690 Availability = CXAvailability_NotAvailable;
691 break;
692 }
693
694 if (const auto *Function = dyn_cast<FunctionDecl>(Declaration))
695 if (Function->isDeleted())
696 Availability = CXAvailability_NotAvailable;
697
698 CursorKind = getCursorKindForDecl(Declaration);
699 if (CursorKind == CXCursor_UnexposedDecl) {
700 // FIXME: Forward declarations of Objective-C classes and protocols
701 // are not directly exposed, but we want code completion to treat them
702 // like a definition.
703 if (isa<ObjCInterfaceDecl>(Declaration))
704 CursorKind = CXCursor_ObjCInterfaceDecl;
705 else if (isa<ObjCProtocolDecl>(Declaration))
706 CursorKind = CXCursor_ObjCProtocolDecl;
707 else
708 CursorKind = CXCursor_NotImplemented;
709 }
710 break;
711 }
712
713 case RK_Macro:
714 case RK_Keyword:
715 llvm_unreachable("Macro and keyword kinds are handled by the constructors");
716 }
717
718 if (!Accessible)
719 Availability = CXAvailability_NotAccessible;
720 }
721
722 /// Retrieve the name that should be used to order a result.
723 ///
724 /// If the name needs to be constructed as a string, that string will be
725 /// saved into Saved and the returned StringRef will refer to it.
getOrderedName(std::string & Saved) const726 StringRef CodeCompletionResult::getOrderedName(std::string &Saved) const {
727 switch (Kind) {
728 case RK_Keyword:
729 return Keyword;
730 case RK_Pattern:
731 return Pattern->getTypedText();
732 case RK_Macro:
733 return Macro->getName();
734 case RK_Declaration:
735 // Handle declarations below.
736 break;
737 }
738
739 DeclarationName Name = Declaration->getDeclName();
740
741 // If the name is a simple identifier (by far the common case), or a
742 // zero-argument selector, just return a reference to that identifier.
743 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
744 return Id->getName();
745 if (Name.isObjCZeroArgSelector())
746 if (IdentifierInfo *Id = Name.getObjCSelector().getIdentifierInfoForSlot(0))
747 return Id->getName();
748
749 Saved = Name.getAsString();
750 return Saved;
751 }
752
operator <(const CodeCompletionResult & X,const CodeCompletionResult & Y)753 bool clang::operator<(const CodeCompletionResult &X,
754 const CodeCompletionResult &Y) {
755 std::string XSaved, YSaved;
756 StringRef XStr = X.getOrderedName(XSaved);
757 StringRef YStr = Y.getOrderedName(YSaved);
758 int cmp = XStr.compare_lower(YStr);
759 if (cmp)
760 return cmp < 0;
761
762 // If case-insensitive comparison fails, try case-sensitive comparison.
763 return XStr.compare(YStr) < 0;
764 }
765