xref: /src/contrib/llvm-project/clang/lib/Sema/CodeCompleteConsumer.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
148675466SDimitry Andric //===- CodeCompleteConsumer.cpp - Code Completion Interface ---------------===//
24c8b2481SRoman Divacky //
322989816SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
422989816SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
522989816SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
64c8b2481SRoman Divacky //
74c8b2481SRoman Divacky //===----------------------------------------------------------------------===//
84c8b2481SRoman Divacky //
94c8b2481SRoman Divacky //  This file implements the CodeCompleteConsumer class.
104c8b2481SRoman Divacky //
114c8b2481SRoman Divacky //===----------------------------------------------------------------------===//
1248675466SDimitry Andric 
134c8b2481SRoman Divacky #include "clang/Sema/CodeCompleteConsumer.h"
14809500fcSDimitry Andric #include "clang-c/Index.h"
1548675466SDimitry Andric #include "clang/AST/Decl.h"
1648675466SDimitry Andric #include "clang/AST/DeclBase.h"
173d1dcd9bSDimitry Andric #include "clang/AST/DeclObjC.h"
183d1dcd9bSDimitry Andric #include "clang/AST/DeclTemplate.h"
1948675466SDimitry Andric #include "clang/AST/DeclarationName.h"
2048675466SDimitry Andric #include "clang/AST/Type.h"
2148675466SDimitry Andric #include "clang/Basic/IdentifierTable.h"
22bab175ecSDimitry Andric #include "clang/Lex/Preprocessor.h"
23676fbe81SDimitry Andric #include "clang/Sema/Sema.h"
24809500fcSDimitry Andric #include "llvm/ADT/SmallString.h"
2548675466SDimitry Andric #include "llvm/ADT/SmallVector.h"
26cfca06d7SDimitry Andric #include "llvm/ADT/StringExtras.h"
2748675466SDimitry Andric #include "llvm/ADT/StringRef.h"
28bca07a45SDimitry Andric #include "llvm/ADT/Twine.h"
2948675466SDimitry Andric #include "llvm/Support/Casting.h"
3048675466SDimitry Andric #include "llvm/Support/Compiler.h"
3148675466SDimitry Andric #include "llvm/Support/ErrorHandling.h"
32676fbe81SDimitry Andric #include "llvm/Support/FormatVariadic.h"
334c8b2481SRoman Divacky #include "llvm/Support/raw_ostream.h"
344c8b2481SRoman Divacky #include <algorithm>
3548675466SDimitry Andric #include <cassert>
3648675466SDimitry Andric #include <cstdint>
3748675466SDimitry Andric #include <string>
38b3d5a323SRoman Divacky 
394c8b2481SRoman Divacky using namespace clang;
404c8b2481SRoman Divacky 
414c8b2481SRoman Divacky //===----------------------------------------------------------------------===//
42bca07a45SDimitry Andric // Code completion context implementation
43bca07a45SDimitry Andric //===----------------------------------------------------------------------===//
44bca07a45SDimitry Andric 
wantConstructorResults() const45bca07a45SDimitry Andric bool CodeCompletionContext::wantConstructorResults() const {
4648675466SDimitry Andric   switch (CCKind) {
47bca07a45SDimitry Andric   case CCC_Recovery:
48bca07a45SDimitry Andric   case CCC_Statement:
49bca07a45SDimitry Andric   case CCC_Expression:
50bca07a45SDimitry Andric   case CCC_ObjCMessageReceiver:
51bca07a45SDimitry Andric   case CCC_ParenthesizedExpression:
52676fbe81SDimitry Andric   case CCC_Symbol:
53676fbe81SDimitry Andric   case CCC_SymbolOrNewName:
54b1c73532SDimitry Andric   case CCC_TopLevelOrExpression:
55bca07a45SDimitry Andric     return true;
56bca07a45SDimitry Andric 
57bca07a45SDimitry Andric   case CCC_TopLevel:
58bca07a45SDimitry Andric   case CCC_ObjCInterface:
59bca07a45SDimitry Andric   case CCC_ObjCImplementation:
60bca07a45SDimitry Andric   case CCC_ObjCIvarList:
61bca07a45SDimitry Andric   case CCC_ClassStructUnion:
62180abc3dSDimitry Andric   case CCC_DotMemberAccess:
63180abc3dSDimitry Andric   case CCC_ArrowMemberAccess:
64180abc3dSDimitry Andric   case CCC_ObjCPropertyAccess:
65bca07a45SDimitry Andric   case CCC_EnumTag:
66bca07a45SDimitry Andric   case CCC_UnionTag:
67bca07a45SDimitry Andric   case CCC_ClassOrStructTag:
68bca07a45SDimitry Andric   case CCC_ObjCProtocolName:
69bca07a45SDimitry Andric   case CCC_Namespace:
70bca07a45SDimitry Andric   case CCC_Type:
71676fbe81SDimitry Andric   case CCC_NewName:
72bca07a45SDimitry Andric   case CCC_MacroName:
73bca07a45SDimitry Andric   case CCC_MacroNameUse:
74bca07a45SDimitry Andric   case CCC_PreprocessorExpression:
75bca07a45SDimitry Andric   case CCC_PreprocessorDirective:
76bca07a45SDimitry Andric   case CCC_NaturalLanguage:
77bca07a45SDimitry Andric   case CCC_SelectorName:
78bca07a45SDimitry Andric   case CCC_TypeQualifiers:
79bca07a45SDimitry Andric   case CCC_Other:
80bca07a45SDimitry Andric   case CCC_OtherWithMacros:
81180abc3dSDimitry Andric   case CCC_ObjCInstanceMessage:
82180abc3dSDimitry Andric   case CCC_ObjCClassMessage:
8336981b17SDimitry Andric   case CCC_ObjCInterfaceName:
84180abc3dSDimitry Andric   case CCC_ObjCCategoryName:
85676fbe81SDimitry Andric   case CCC_IncludedFile:
86c0981da4SDimitry Andric   case CCC_Attribute:
877fa27ce4SDimitry Andric   case CCC_ObjCClassForwardDecl:
88bca07a45SDimitry Andric     return false;
89bca07a45SDimitry Andric   }
90bca07a45SDimitry Andric 
91dbe13110SDimitry Andric   llvm_unreachable("Invalid CodeCompletionContext::Kind!");
92bca07a45SDimitry Andric }
93bca07a45SDimitry Andric 
getCompletionKindString(CodeCompletionContext::Kind Kind)9448675466SDimitry Andric StringRef clang::getCompletionKindString(CodeCompletionContext::Kind Kind) {
9548675466SDimitry Andric   using CCKind = CodeCompletionContext::Kind;
9648675466SDimitry Andric   switch (Kind) {
9748675466SDimitry Andric   case CCKind::CCC_Other:
9848675466SDimitry Andric     return "Other";
9948675466SDimitry Andric   case CCKind::CCC_OtherWithMacros:
10048675466SDimitry Andric     return "OtherWithMacros";
10148675466SDimitry Andric   case CCKind::CCC_TopLevel:
10248675466SDimitry Andric     return "TopLevel";
10348675466SDimitry Andric   case CCKind::CCC_ObjCInterface:
10448675466SDimitry Andric     return "ObjCInterface";
10548675466SDimitry Andric   case CCKind::CCC_ObjCImplementation:
10648675466SDimitry Andric     return "ObjCImplementation";
10748675466SDimitry Andric   case CCKind::CCC_ObjCIvarList:
10848675466SDimitry Andric     return "ObjCIvarList";
10948675466SDimitry Andric   case CCKind::CCC_ClassStructUnion:
11048675466SDimitry Andric     return "ClassStructUnion";
11148675466SDimitry Andric   case CCKind::CCC_Statement:
11248675466SDimitry Andric     return "Statement";
11348675466SDimitry Andric   case CCKind::CCC_Expression:
11448675466SDimitry Andric     return "Expression";
11548675466SDimitry Andric   case CCKind::CCC_ObjCMessageReceiver:
11648675466SDimitry Andric     return "ObjCMessageReceiver";
11748675466SDimitry Andric   case CCKind::CCC_DotMemberAccess:
11848675466SDimitry Andric     return "DotMemberAccess";
11948675466SDimitry Andric   case CCKind::CCC_ArrowMemberAccess:
12048675466SDimitry Andric     return "ArrowMemberAccess";
12148675466SDimitry Andric   case CCKind::CCC_ObjCPropertyAccess:
12248675466SDimitry Andric     return "ObjCPropertyAccess";
12348675466SDimitry Andric   case CCKind::CCC_EnumTag:
12448675466SDimitry Andric     return "EnumTag";
12548675466SDimitry Andric   case CCKind::CCC_UnionTag:
12648675466SDimitry Andric     return "UnionTag";
12748675466SDimitry Andric   case CCKind::CCC_ClassOrStructTag:
12848675466SDimitry Andric     return "ClassOrStructTag";
12948675466SDimitry Andric   case CCKind::CCC_ObjCProtocolName:
13048675466SDimitry Andric     return "ObjCProtocolName";
13148675466SDimitry Andric   case CCKind::CCC_Namespace:
13248675466SDimitry Andric     return "Namespace";
13348675466SDimitry Andric   case CCKind::CCC_Type:
13448675466SDimitry Andric     return "Type";
135676fbe81SDimitry Andric   case CCKind::CCC_NewName:
136676fbe81SDimitry Andric     return "NewName";
137676fbe81SDimitry Andric   case CCKind::CCC_Symbol:
138676fbe81SDimitry Andric     return "Symbol";
139676fbe81SDimitry Andric   case CCKind::CCC_SymbolOrNewName:
140676fbe81SDimitry Andric     return "SymbolOrNewName";
14148675466SDimitry Andric   case CCKind::CCC_MacroName:
14248675466SDimitry Andric     return "MacroName";
14348675466SDimitry Andric   case CCKind::CCC_MacroNameUse:
14448675466SDimitry Andric     return "MacroNameUse";
14548675466SDimitry Andric   case CCKind::CCC_PreprocessorExpression:
14648675466SDimitry Andric     return "PreprocessorExpression";
14748675466SDimitry Andric   case CCKind::CCC_PreprocessorDirective:
14848675466SDimitry Andric     return "PreprocessorDirective";
14948675466SDimitry Andric   case CCKind::CCC_NaturalLanguage:
15048675466SDimitry Andric     return "NaturalLanguage";
15148675466SDimitry Andric   case CCKind::CCC_SelectorName:
15248675466SDimitry Andric     return "SelectorName";
15348675466SDimitry Andric   case CCKind::CCC_TypeQualifiers:
15448675466SDimitry Andric     return "TypeQualifiers";
15548675466SDimitry Andric   case CCKind::CCC_ParenthesizedExpression:
15648675466SDimitry Andric     return "ParenthesizedExpression";
15748675466SDimitry Andric   case CCKind::CCC_ObjCInstanceMessage:
15848675466SDimitry Andric     return "ObjCInstanceMessage";
15948675466SDimitry Andric   case CCKind::CCC_ObjCClassMessage:
16048675466SDimitry Andric     return "ObjCClassMessage";
16148675466SDimitry Andric   case CCKind::CCC_ObjCInterfaceName:
16248675466SDimitry Andric     return "ObjCInterfaceName";
16348675466SDimitry Andric   case CCKind::CCC_ObjCCategoryName:
16448675466SDimitry Andric     return "ObjCCategoryName";
165676fbe81SDimitry Andric   case CCKind::CCC_IncludedFile:
166676fbe81SDimitry Andric     return "IncludedFile";
167c0981da4SDimitry Andric   case CCKind::CCC_Attribute:
168c0981da4SDimitry Andric     return "Attribute";
16948675466SDimitry Andric   case CCKind::CCC_Recovery:
17048675466SDimitry Andric     return "Recovery";
1717fa27ce4SDimitry Andric   case CCKind::CCC_ObjCClassForwardDecl:
1727fa27ce4SDimitry Andric     return "ObjCClassForwardDecl";
173b1c73532SDimitry Andric   case CCKind::CCC_TopLevelOrExpression:
174b1c73532SDimitry Andric     return "ReplTopLevel";
17548675466SDimitry Andric   }
17648675466SDimitry Andric   llvm_unreachable("Invalid CodeCompletionContext::Kind!");
17748675466SDimitry Andric }
17848675466SDimitry Andric 
179bca07a45SDimitry Andric //===----------------------------------------------------------------------===//
1804c8b2481SRoman Divacky // Code completion string implementation
1814c8b2481SRoman Divacky //===----------------------------------------------------------------------===//
18248675466SDimitry Andric 
Chunk(ChunkKind Kind,const char * Text)183bca07a45SDimitry Andric CodeCompletionString::Chunk::Chunk(ChunkKind Kind, const char *Text)
18448675466SDimitry Andric     : Kind(Kind), Text("") {
185b3d5a323SRoman Divacky   switch (Kind) {
186b3d5a323SRoman Divacky   case CK_TypedText:
187b3d5a323SRoman Divacky   case CK_Text:
188b3d5a323SRoman Divacky   case CK_Placeholder:
189b3d5a323SRoman Divacky   case CK_Informative:
190abe15e55SRoman Divacky   case CK_ResultType:
191bca07a45SDimitry Andric   case CK_CurrentParameter:
192bca07a45SDimitry Andric     this->Text = Text;
193b3d5a323SRoman Divacky     break;
194b3d5a323SRoman Divacky 
195b3d5a323SRoman Divacky   case CK_Optional:
19634d02d0bSRoman Divacky     llvm_unreachable("Optional strings cannot be created from text");
197b3d5a323SRoman Divacky 
198b3d5a323SRoman Divacky   case CK_LeftParen:
199b3d5a323SRoman Divacky     this->Text = "(";
200b3d5a323SRoman Divacky     break;
201b3d5a323SRoman Divacky 
202b3d5a323SRoman Divacky   case CK_RightParen:
203b3d5a323SRoman Divacky     this->Text = ")";
204b3d5a323SRoman Divacky     break;
205b3d5a323SRoman Divacky 
206b3d5a323SRoman Divacky   case CK_LeftBracket:
207b3d5a323SRoman Divacky     this->Text = "[";
208b3d5a323SRoman Divacky     break;
209b3d5a323SRoman Divacky 
210b3d5a323SRoman Divacky   case CK_RightBracket:
211b3d5a323SRoman Divacky     this->Text = "]";
212b3d5a323SRoman Divacky     break;
213b3d5a323SRoman Divacky 
214b3d5a323SRoman Divacky   case CK_LeftBrace:
215b3d5a323SRoman Divacky     this->Text = "{";
216b3d5a323SRoman Divacky     break;
217b3d5a323SRoman Divacky 
218b3d5a323SRoman Divacky   case CK_RightBrace:
219b3d5a323SRoman Divacky     this->Text = "}";
220b3d5a323SRoman Divacky     break;
221b3d5a323SRoman Divacky 
222b3d5a323SRoman Divacky   case CK_LeftAngle:
223b3d5a323SRoman Divacky     this->Text = "<";
224b3d5a323SRoman Divacky     break;
225b3d5a323SRoman Divacky 
226b3d5a323SRoman Divacky   case CK_RightAngle:
227b3d5a323SRoman Divacky     this->Text = ">";
228b3d5a323SRoman Divacky     break;
229b3d5a323SRoman Divacky 
230b3d5a323SRoman Divacky   case CK_Comma:
231b3d5a323SRoman Divacky     this->Text = ", ";
232b3d5a323SRoman Divacky     break;
233ee791ddeSRoman Divacky 
234ee791ddeSRoman Divacky   case CK_Colon:
235ee791ddeSRoman Divacky     this->Text = ":";
236ee791ddeSRoman Divacky     break;
237ee791ddeSRoman Divacky 
238ee791ddeSRoman Divacky   case CK_SemiColon:
239ee791ddeSRoman Divacky     this->Text = ";";
240ee791ddeSRoman Divacky     break;
241ee791ddeSRoman Divacky 
242ee791ddeSRoman Divacky   case CK_Equal:
243ee791ddeSRoman Divacky     this->Text = " = ";
244ee791ddeSRoman Divacky     break;
245ee791ddeSRoman Divacky 
246ee791ddeSRoman Divacky   case CK_HorizontalSpace:
247ee791ddeSRoman Divacky     this->Text = " ";
248ee791ddeSRoman Divacky     break;
249ee791ddeSRoman Divacky 
250ee791ddeSRoman Divacky   case CK_VerticalSpace:
251ee791ddeSRoman Divacky     this->Text = "\n";
252ee791ddeSRoman Divacky     break;
253b3d5a323SRoman Divacky   }
2544c8b2481SRoman Divacky }
2554c8b2481SRoman Divacky 
2564c8b2481SRoman Divacky CodeCompletionString::Chunk
CreateText(const char * Text)257bca07a45SDimitry Andric CodeCompletionString::Chunk::CreateText(const char *Text) {
2584c8b2481SRoman Divacky   return Chunk(CK_Text, Text);
2594c8b2481SRoman Divacky }
2604c8b2481SRoman Divacky 
2614c8b2481SRoman Divacky CodeCompletionString::Chunk
CreateOptional(CodeCompletionString * Optional)262bca07a45SDimitry Andric CodeCompletionString::Chunk::CreateOptional(CodeCompletionString *Optional) {
2634c8b2481SRoman Divacky   Chunk Result;
2644c8b2481SRoman Divacky   Result.Kind = CK_Optional;
265bca07a45SDimitry Andric   Result.Optional = Optional;
2664c8b2481SRoman Divacky   return Result;
2674c8b2481SRoman Divacky }
2684c8b2481SRoman Divacky 
2694c8b2481SRoman Divacky CodeCompletionString::Chunk
CreatePlaceholder(const char * Placeholder)270bca07a45SDimitry Andric CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) {
2714c8b2481SRoman Divacky   return Chunk(CK_Placeholder, Placeholder);
2724c8b2481SRoman Divacky }
2734c8b2481SRoman Divacky 
2744c8b2481SRoman Divacky CodeCompletionString::Chunk
CreateInformative(const char * Informative)275bca07a45SDimitry Andric CodeCompletionString::Chunk::CreateInformative(const char *Informative) {
2764c8b2481SRoman Divacky   return Chunk(CK_Informative, Informative);
2774c8b2481SRoman Divacky }
2784c8b2481SRoman Divacky 
279b3d5a323SRoman Divacky CodeCompletionString::Chunk
CreateResultType(const char * ResultType)280bca07a45SDimitry Andric CodeCompletionString::Chunk::CreateResultType(const char *ResultType) {
281abe15e55SRoman Divacky   return Chunk(CK_ResultType, ResultType);
282abe15e55SRoman Divacky }
283abe15e55SRoman Divacky 
CreateCurrentParameter(const char * CurrentParameter)284676fbe81SDimitry Andric CodeCompletionString::Chunk CodeCompletionString::Chunk::CreateCurrentParameter(
285bca07a45SDimitry Andric     const char *CurrentParameter) {
286b3d5a323SRoman Divacky   return Chunk(CK_CurrentParameter, CurrentParameter);
287b3d5a323SRoman Divacky }
288b3d5a323SRoman Divacky 
CodeCompletionString(const Chunk * Chunks,unsigned NumChunks,unsigned Priority,CXAvailabilityKind Availability,const char ** Annotations,unsigned NumAnnotations,StringRef ParentName,const char * BriefComment)289676fbe81SDimitry Andric CodeCompletionString::CodeCompletionString(
290676fbe81SDimitry Andric     const Chunk *Chunks, unsigned NumChunks, unsigned Priority,
291676fbe81SDimitry Andric     CXAvailabilityKind Availability, const char **Annotations,
292676fbe81SDimitry Andric     unsigned NumAnnotations, StringRef ParentName, const char *BriefComment)
293676fbe81SDimitry Andric     : NumChunks(NumChunks), NumAnnotations(NumAnnotations), Priority(Priority),
294676fbe81SDimitry Andric       Availability(Availability), ParentName(ParentName),
295676fbe81SDimitry Andric       BriefComment(BriefComment) {
29636981b17SDimitry Andric   assert(NumChunks <= 0xffff);
29736981b17SDimitry Andric   assert(NumAnnotations <= 0xffff);
29836981b17SDimitry Andric 
299bca07a45SDimitry Andric   Chunk *StoredChunks = reinterpret_cast<Chunk *>(this + 1);
300bca07a45SDimitry Andric   for (unsigned I = 0; I != NumChunks; ++I)
301bca07a45SDimitry Andric     StoredChunks[I] = Chunks[I];
30236981b17SDimitry Andric 
303676fbe81SDimitry Andric   const char **StoredAnnotations =
304676fbe81SDimitry Andric       reinterpret_cast<const char **>(StoredChunks + NumChunks);
30536981b17SDimitry Andric   for (unsigned I = 0; I != NumAnnotations; ++I)
30636981b17SDimitry Andric     StoredAnnotations[I] = Annotations[I];
3074c8b2481SRoman Divacky }
3084c8b2481SRoman Divacky 
getAnnotationCount() const30936981b17SDimitry Andric unsigned CodeCompletionString::getAnnotationCount() const {
31036981b17SDimitry Andric   return NumAnnotations;
31136981b17SDimitry Andric }
31236981b17SDimitry Andric 
getAnnotation(unsigned AnnotationNr) const31336981b17SDimitry Andric const char *CodeCompletionString::getAnnotation(unsigned AnnotationNr) const {
31436981b17SDimitry Andric   if (AnnotationNr < NumAnnotations)
31536981b17SDimitry Andric     return reinterpret_cast<const char *const *>(end())[AnnotationNr];
31636981b17SDimitry Andric   else
3179f4dbff6SDimitry Andric     return nullptr;
31836981b17SDimitry Andric }
31936981b17SDimitry Andric 
getAsString() const3204c8b2481SRoman Divacky std::string CodeCompletionString::getAsString() const {
3214c8b2481SRoman Divacky   std::string Result;
3224c8b2481SRoman Divacky   llvm::raw_string_ostream OS(Result);
3234c8b2481SRoman Divacky 
324676fbe81SDimitry Andric   for (const Chunk &C : *this) {
325676fbe81SDimitry Andric     switch (C.Kind) {
326676fbe81SDimitry Andric     case CK_Optional:
327676fbe81SDimitry Andric       OS << "{#" << C.Optional->getAsString() << "#}";
328676fbe81SDimitry Andric       break;
329676fbe81SDimitry Andric     case CK_Placeholder:
330676fbe81SDimitry Andric       OS << "<#" << C.Text << "#>";
331676fbe81SDimitry Andric       break;
332abe15e55SRoman Divacky     case CK_Informative:
333abe15e55SRoman Divacky     case CK_ResultType:
334676fbe81SDimitry Andric       OS << "[#" << C.Text << "#]";
335abe15e55SRoman Divacky       break;
336676fbe81SDimitry Andric     case CK_CurrentParameter:
337676fbe81SDimitry Andric       OS << "<#" << C.Text << "#>";
338676fbe81SDimitry Andric       break;
339676fbe81SDimitry Andric     default:
340676fbe81SDimitry Andric       OS << C.Text;
341676fbe81SDimitry Andric       break;
3424c8b2481SRoman Divacky     }
3434c8b2481SRoman Divacky   }
34477fc4c14SDimitry Andric   return Result;
3454c8b2481SRoman Divacky }
3464c8b2481SRoman Divacky 
getTypedText() const347f5bd02d2SRoman Divacky const char *CodeCompletionString::getTypedText() const {
348676fbe81SDimitry Andric   for (const Chunk &C : *this)
349676fbe81SDimitry Andric     if (C.Kind == CK_TypedText)
350676fbe81SDimitry Andric       return C.Text;
351f5bd02d2SRoman Divacky 
3529f4dbff6SDimitry Andric   return nullptr;
353f5bd02d2SRoman Divacky }
354f5bd02d2SRoman Divacky 
getAllTypedText() const355145449b1SDimitry Andric std::string CodeCompletionString::getAllTypedText() const {
356145449b1SDimitry Andric   std::string Res;
357145449b1SDimitry Andric   for (const Chunk &C : *this)
358145449b1SDimitry Andric     if (C.Kind == CK_TypedText)
359145449b1SDimitry Andric       Res += C.Text;
360145449b1SDimitry Andric 
361145449b1SDimitry Andric   return Res;
362145449b1SDimitry Andric }
363145449b1SDimitry Andric 
CopyString(const Twine & String)3645e20cdd8SDimitry Andric const char *CodeCompletionAllocator::CopyString(const Twine &String) {
3655e20cdd8SDimitry Andric   SmallString<128> Data;
3665e20cdd8SDimitry Andric   StringRef Ref = String.toStringRef(Data);
367bca07a45SDimitry Andric   // FIXME: It would be more efficient to teach Twine to tell us its size and
368bca07a45SDimitry Andric   // then add a routine there to fill in an allocated char* with the contents
369bca07a45SDimitry Andric   // of the string.
3705e20cdd8SDimitry Andric   char *Mem = (char *)Allocate(Ref.size() + 1, 1);
3715e20cdd8SDimitry Andric   std::copy(Ref.begin(), Ref.end(), Mem);
3725e20cdd8SDimitry Andric   Mem[Ref.size()] = 0;
3735e20cdd8SDimitry Andric   return Mem;
374bca07a45SDimitry Andric }
375bca07a45SDimitry Andric 
getParentName(const DeclContext * DC)376809500fcSDimitry Andric StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) {
377b60736ecSDimitry Andric   if (!isa<NamedDecl>(DC))
37848675466SDimitry Andric     return {};
379dbe13110SDimitry Andric 
380dbe13110SDimitry Andric   // Check whether we've already cached the parent name.
381dbe13110SDimitry Andric   StringRef &CachedParentName = ParentNames[DC];
382dbe13110SDimitry Andric   if (!CachedParentName.empty())
383dbe13110SDimitry Andric     return CachedParentName;
384dbe13110SDimitry Andric 
385dbe13110SDimitry Andric   // If we already processed this DeclContext and assigned empty to it, the
386dbe13110SDimitry Andric   // data pointer will be non-null.
3879f4dbff6SDimitry Andric   if (CachedParentName.data() != nullptr)
38848675466SDimitry Andric     return {};
389dbe13110SDimitry Andric 
390dbe13110SDimitry Andric   // Find the interesting names.
391809500fcSDimitry Andric   SmallVector<const DeclContext *, 2> Contexts;
392dbe13110SDimitry Andric   while (DC && !DC->isFunctionOrMethod()) {
393676fbe81SDimitry Andric     if (const auto *ND = dyn_cast<NamedDecl>(DC)) {
394dbe13110SDimitry Andric       if (ND->getIdentifier())
395dbe13110SDimitry Andric         Contexts.push_back(DC);
396dbe13110SDimitry Andric     }
397dbe13110SDimitry Andric 
398dbe13110SDimitry Andric     DC = DC->getParent();
399dbe13110SDimitry Andric   }
400dbe13110SDimitry Andric 
401dbe13110SDimitry Andric   {
402809500fcSDimitry Andric     SmallString<128> S;
403dbe13110SDimitry Andric     llvm::raw_svector_ostream OS(S);
404dbe13110SDimitry Andric     bool First = true;
405c0981da4SDimitry Andric     for (const DeclContext *CurDC : llvm::reverse(Contexts)) {
406dbe13110SDimitry Andric       if (First)
407dbe13110SDimitry Andric         First = false;
408dbe13110SDimitry Andric       else {
409dbe13110SDimitry Andric         OS << "::";
410dbe13110SDimitry Andric       }
411dbe13110SDimitry Andric 
412676fbe81SDimitry Andric       if (const auto *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
413dbe13110SDimitry Andric         CurDC = CatImpl->getCategoryDecl();
414dbe13110SDimitry Andric 
415676fbe81SDimitry Andric       if (const auto *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
416809500fcSDimitry Andric         const ObjCInterfaceDecl *Interface = Cat->getClassInterface();
417dbe13110SDimitry Andric         if (!Interface) {
418dbe13110SDimitry Andric           // Assign an empty StringRef but with non-null data to distinguish
419dbe13110SDimitry Andric           // between empty because we didn't process the DeclContext yet.
4202b6b257fSDimitry Andric           CachedParentName = StringRef((const char *)(uintptr_t)~0U, 0);
42148675466SDimitry Andric           return {};
422dbe13110SDimitry Andric         }
423dbe13110SDimitry Andric 
424dbe13110SDimitry Andric         OS << Interface->getName() << '(' << Cat->getName() << ')';
425dbe13110SDimitry Andric       } else {
426dbe13110SDimitry Andric         OS << cast<NamedDecl>(CurDC)->getName();
427dbe13110SDimitry Andric       }
428dbe13110SDimitry Andric     }
429dbe13110SDimitry Andric 
430dbe13110SDimitry Andric     CachedParentName = AllocatorRef->CopyString(OS.str());
431dbe13110SDimitry Andric   }
432dbe13110SDimitry Andric 
433dbe13110SDimitry Andric   return CachedParentName;
434dbe13110SDimitry Andric }
435dbe13110SDimitry Andric 
TakeString()436bca07a45SDimitry Andric CodeCompletionString *CodeCompletionBuilder::TakeString() {
437dbe13110SDimitry Andric   void *Mem = getAllocator().Allocate(
438bab175ecSDimitry Andric       sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size() +
439bab175ecSDimitry Andric           sizeof(const char *) * Annotations.size(),
440bab175ecSDimitry Andric       alignof(CodeCompletionString));
441676fbe81SDimitry Andric   CodeCompletionString *Result = new (Mem) CodeCompletionString(
442676fbe81SDimitry Andric       Chunks.data(), Chunks.size(), Priority, Availability, Annotations.data(),
443676fbe81SDimitry Andric       Annotations.size(), ParentName, BriefComment);
444bca07a45SDimitry Andric   Chunks.clear();
445f5bd02d2SRoman Divacky   return Result;
446f5bd02d2SRoman Divacky }
447b3d5a323SRoman Divacky 
AddTypedTextChunk(const char * Text)448dbe13110SDimitry Andric void CodeCompletionBuilder::AddTypedTextChunk(const char *Text) {
449dbe13110SDimitry Andric   Chunks.push_back(Chunk(CodeCompletionString::CK_TypedText, Text));
450dbe13110SDimitry Andric }
451dbe13110SDimitry Andric 
AddTextChunk(const char * Text)452dbe13110SDimitry Andric void CodeCompletionBuilder::AddTextChunk(const char *Text) {
453dbe13110SDimitry Andric   Chunks.push_back(Chunk::CreateText(Text));
454dbe13110SDimitry Andric }
455dbe13110SDimitry Andric 
AddOptionalChunk(CodeCompletionString * Optional)456dbe13110SDimitry Andric void CodeCompletionBuilder::AddOptionalChunk(CodeCompletionString *Optional) {
457dbe13110SDimitry Andric   Chunks.push_back(Chunk::CreateOptional(Optional));
458dbe13110SDimitry Andric }
459dbe13110SDimitry Andric 
AddPlaceholderChunk(const char * Placeholder)460dbe13110SDimitry Andric void CodeCompletionBuilder::AddPlaceholderChunk(const char *Placeholder) {
461dbe13110SDimitry Andric   Chunks.push_back(Chunk::CreatePlaceholder(Placeholder));
462dbe13110SDimitry Andric }
463dbe13110SDimitry Andric 
AddInformativeChunk(const char * Text)464dbe13110SDimitry Andric void CodeCompletionBuilder::AddInformativeChunk(const char *Text) {
465dbe13110SDimitry Andric   Chunks.push_back(Chunk::CreateInformative(Text));
466dbe13110SDimitry Andric }
467dbe13110SDimitry Andric 
AddResultTypeChunk(const char * ResultType)468dbe13110SDimitry Andric void CodeCompletionBuilder::AddResultTypeChunk(const char *ResultType) {
469dbe13110SDimitry Andric   Chunks.push_back(Chunk::CreateResultType(ResultType));
470dbe13110SDimitry Andric }
471dbe13110SDimitry Andric 
AddCurrentParameterChunk(const char * CurrentParameter)472676fbe81SDimitry Andric void CodeCompletionBuilder::AddCurrentParameterChunk(
473676fbe81SDimitry Andric     const char *CurrentParameter) {
474dbe13110SDimitry Andric   Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter));
475dbe13110SDimitry Andric }
476dbe13110SDimitry Andric 
AddChunk(CodeCompletionString::ChunkKind CK,const char * Text)477dbe13110SDimitry Andric void CodeCompletionBuilder::AddChunk(CodeCompletionString::ChunkKind CK,
478dbe13110SDimitry Andric                                      const char *Text) {
479dbe13110SDimitry Andric   Chunks.push_back(Chunk(CK, Text));
480dbe13110SDimitry Andric }
481dbe13110SDimitry Andric 
addParentContext(const DeclContext * DC)482809500fcSDimitry Andric void CodeCompletionBuilder::addParentContext(const DeclContext *DC) {
48348675466SDimitry Andric   if (DC->isTranslationUnit())
484dbe13110SDimitry Andric     return;
485dbe13110SDimitry Andric 
486dbe13110SDimitry Andric   if (DC->isFunctionOrMethod())
487dbe13110SDimitry Andric     return;
488dbe13110SDimitry Andric 
489b60736ecSDimitry Andric   if (!isa<NamedDecl>(DC))
490dbe13110SDimitry Andric     return;
491dbe13110SDimitry Andric 
492dbe13110SDimitry Andric   ParentName = getCodeCompletionTUInfo().getParentName(DC);
493dbe13110SDimitry Andric }
494dbe13110SDimitry Andric 
addBriefComment(StringRef Comment)49556d91b49SDimitry Andric void CodeCompletionBuilder::addBriefComment(StringRef Comment) {
49656d91b49SDimitry Andric   BriefComment = Allocator.CopyString(Comment);
49756d91b49SDimitry Andric }
49856d91b49SDimitry Andric 
4994c8b2481SRoman Divacky //===----------------------------------------------------------------------===//
5004c8b2481SRoman Divacky // Code completion overload candidate implementation
5014c8b2481SRoman Divacky //===----------------------------------------------------------------------===//
getFunction() const502676fbe81SDimitry Andric FunctionDecl *CodeCompleteConsumer::OverloadCandidate::getFunction() const {
5034c8b2481SRoman Divacky   if (getKind() == CK_Function)
5044c8b2481SRoman Divacky     return Function;
5054c8b2481SRoman Divacky   else if (getKind() == CK_FunctionTemplate)
5064c8b2481SRoman Divacky     return FunctionTemplate->getTemplatedDecl();
5074c8b2481SRoman Divacky   else
5089f4dbff6SDimitry Andric     return nullptr;
5094c8b2481SRoman Divacky }
5104c8b2481SRoman Divacky 
5114c8b2481SRoman Divacky const FunctionType *
getFunctionType() const5124c8b2481SRoman Divacky CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
5134c8b2481SRoman Divacky   switch (Kind) {
5144c8b2481SRoman Divacky   case CK_Function:
5154c8b2481SRoman Divacky     return Function->getType()->getAs<FunctionType>();
5164c8b2481SRoman Divacky 
5174c8b2481SRoman Divacky   case CK_FunctionTemplate:
518676fbe81SDimitry Andric     return FunctionTemplate->getTemplatedDecl()
519676fbe81SDimitry Andric         ->getType()
5204c8b2481SRoman Divacky         ->getAs<FunctionType>();
5214c8b2481SRoman Divacky 
5224c8b2481SRoman Divacky   case CK_FunctionType:
5234c8b2481SRoman Divacky     return Type;
5244b4fe385SDimitry Andric   case CK_FunctionProtoTypeLoc:
5254b4fe385SDimitry Andric     return ProtoTypeLoc.getTypePtr();
5266f8fc217SDimitry Andric   case CK_Template:
5276f8fc217SDimitry Andric   case CK_Aggregate:
5286f8fc217SDimitry Andric     return nullptr;
5294c8b2481SRoman Divacky   }
5304c8b2481SRoman Divacky 
531dbe13110SDimitry Andric   llvm_unreachable("Invalid CandidateKind!");
5324c8b2481SRoman Divacky }
5334c8b2481SRoman Divacky 
5344b4fe385SDimitry Andric const FunctionProtoTypeLoc
getFunctionProtoTypeLoc() const5354b4fe385SDimitry Andric CodeCompleteConsumer::OverloadCandidate::getFunctionProtoTypeLoc() const {
5364b4fe385SDimitry Andric   if (Kind == CK_FunctionProtoTypeLoc)
5374b4fe385SDimitry Andric     return ProtoTypeLoc;
5384b4fe385SDimitry Andric   return FunctionProtoTypeLoc();
5394b4fe385SDimitry Andric }
5404b4fe385SDimitry Andric 
getNumParams() const5416f8fc217SDimitry Andric unsigned CodeCompleteConsumer::OverloadCandidate::getNumParams() const {
5426f8fc217SDimitry Andric   if (Kind == CK_Template)
5436f8fc217SDimitry Andric     return Template->getTemplateParameters()->size();
5446f8fc217SDimitry Andric 
5456f8fc217SDimitry Andric   if (Kind == CK_Aggregate) {
5466f8fc217SDimitry Andric     unsigned Count =
5476f8fc217SDimitry Andric         std::distance(AggregateType->field_begin(), AggregateType->field_end());
5486f8fc217SDimitry Andric     if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType))
5496f8fc217SDimitry Andric       Count += CRD->getNumBases();
5506f8fc217SDimitry Andric     return Count;
5516f8fc217SDimitry Andric   }
5526f8fc217SDimitry Andric 
5536f8fc217SDimitry Andric   if (const auto *FT = getFunctionType())
5546f8fc217SDimitry Andric     if (const auto *FPT = dyn_cast<FunctionProtoType>(FT))
5556f8fc217SDimitry Andric       return FPT->getNumParams();
5566f8fc217SDimitry Andric 
5576f8fc217SDimitry Andric   return 0;
5586f8fc217SDimitry Andric }
5596f8fc217SDimitry Andric 
5606f8fc217SDimitry Andric QualType
getParamType(unsigned N) const5616f8fc217SDimitry Andric CodeCompleteConsumer::OverloadCandidate::getParamType(unsigned N) const {
5626f8fc217SDimitry Andric   if (Kind == CK_Aggregate) {
5636f8fc217SDimitry Andric     if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) {
5646f8fc217SDimitry Andric       if (N < CRD->getNumBases())
5656f8fc217SDimitry Andric         return std::next(CRD->bases_begin(), N)->getType();
5666f8fc217SDimitry Andric       N -= CRD->getNumBases();
5676f8fc217SDimitry Andric     }
5686f8fc217SDimitry Andric     for (const auto *Field : AggregateType->fields())
5696f8fc217SDimitry Andric       if (N-- == 0)
5706f8fc217SDimitry Andric         return Field->getType();
5716f8fc217SDimitry Andric     return QualType();
5726f8fc217SDimitry Andric   }
5736f8fc217SDimitry Andric 
5746f8fc217SDimitry Andric   if (Kind == CK_Template) {
5756f8fc217SDimitry Andric     TemplateParameterList *TPL = getTemplate()->getTemplateParameters();
5766f8fc217SDimitry Andric     if (N < TPL->size())
5776f8fc217SDimitry Andric       if (const auto *D = dyn_cast<NonTypeTemplateParmDecl>(TPL->getParam(N)))
5786f8fc217SDimitry Andric         return D->getType();
5796f8fc217SDimitry Andric     return QualType();
5806f8fc217SDimitry Andric   }
5816f8fc217SDimitry Andric 
5826f8fc217SDimitry Andric   if (const auto *FT = getFunctionType())
5836f8fc217SDimitry Andric     if (const auto *FPT = dyn_cast<FunctionProtoType>(FT))
5846f8fc217SDimitry Andric       if (N < FPT->getNumParams())
5856f8fc217SDimitry Andric         return FPT->getParamType(N);
5866f8fc217SDimitry Andric   return QualType();
5876f8fc217SDimitry Andric }
5886f8fc217SDimitry Andric 
5896f8fc217SDimitry Andric const NamedDecl *
getParamDecl(unsigned N) const5906f8fc217SDimitry Andric CodeCompleteConsumer::OverloadCandidate::getParamDecl(unsigned N) const {
5916f8fc217SDimitry Andric   if (Kind == CK_Aggregate) {
5926f8fc217SDimitry Andric     if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) {
5936f8fc217SDimitry Andric       if (N < CRD->getNumBases())
5946f8fc217SDimitry Andric         return std::next(CRD->bases_begin(), N)->getType()->getAsTagDecl();
5956f8fc217SDimitry Andric       N -= CRD->getNumBases();
5966f8fc217SDimitry Andric     }
5976f8fc217SDimitry Andric     for (const auto *Field : AggregateType->fields())
5986f8fc217SDimitry Andric       if (N-- == 0)
5996f8fc217SDimitry Andric         return Field;
6006f8fc217SDimitry Andric     return nullptr;
6016f8fc217SDimitry Andric   }
6026f8fc217SDimitry Andric 
6036f8fc217SDimitry Andric   if (Kind == CK_Template) {
6046f8fc217SDimitry Andric     TemplateParameterList *TPL = getTemplate()->getTemplateParameters();
6056f8fc217SDimitry Andric     if (N < TPL->size())
6066f8fc217SDimitry Andric       return TPL->getParam(N);
6076f8fc217SDimitry Andric     return nullptr;
6086f8fc217SDimitry Andric   }
6096f8fc217SDimitry Andric 
6106f8fc217SDimitry Andric   // Note that if we only have a FunctionProtoType, we don't have param decls.
6116f8fc217SDimitry Andric   if (const auto *FD = getFunction()) {
6126f8fc217SDimitry Andric     if (N < FD->param_size())
6136f8fc217SDimitry Andric       return FD->getParamDecl(N);
6144b4fe385SDimitry Andric   } else if (Kind == CK_FunctionProtoTypeLoc) {
6154b4fe385SDimitry Andric     if (N < ProtoTypeLoc.getNumParams()) {
6164b4fe385SDimitry Andric       return ProtoTypeLoc.getParam(N);
6176f8fc217SDimitry Andric     }
6184b4fe385SDimitry Andric   }
6194b4fe385SDimitry Andric 
6206f8fc217SDimitry Andric   return nullptr;
6216f8fc217SDimitry Andric }
6226f8fc217SDimitry Andric 
6234c8b2481SRoman Divacky //===----------------------------------------------------------------------===//
6244c8b2481SRoman Divacky // Code completion consumer implementation
6254c8b2481SRoman Divacky //===----------------------------------------------------------------------===//
6264c8b2481SRoman Divacky 
62748675466SDimitry Andric CodeCompleteConsumer::~CodeCompleteConsumer() = default;
6284c8b2481SRoman Divacky 
isResultFilteredOut(StringRef Filter,CodeCompletionResult Result)629676fbe81SDimitry Andric bool PrintingCodeCompleteConsumer::isResultFilteredOut(
630676fbe81SDimitry Andric     StringRef Filter, CodeCompletionResult Result) {
631bab175ecSDimitry Andric   switch (Result.Kind) {
63248675466SDimitry Andric   case CodeCompletionResult::RK_Declaration:
633312c0ed1SDimitry Andric     return !(
634312c0ed1SDimitry Andric         Result.Declaration->getIdentifier() &&
635312c0ed1SDimitry Andric         Result.Declaration->getIdentifier()->getName().starts_with(Filter));
63648675466SDimitry Andric   case CodeCompletionResult::RK_Keyword:
637312c0ed1SDimitry Andric     return !StringRef(Result.Keyword).starts_with(Filter);
63848675466SDimitry Andric   case CodeCompletionResult::RK_Macro:
639312c0ed1SDimitry Andric     return !Result.Macro->getName().starts_with(Filter);
64048675466SDimitry Andric   case CodeCompletionResult::RK_Pattern:
641676fbe81SDimitry Andric     return !(Result.Pattern->getTypedText() &&
642312c0ed1SDimitry Andric              StringRef(Result.Pattern->getTypedText()).starts_with(Filter));
643bab175ecSDimitry Andric   }
644bab175ecSDimitry Andric   llvm_unreachable("Unknown code completion result Kind.");
645bab175ecSDimitry Andric }
646bab175ecSDimitry Andric 
ProcessCodeCompleteResults(Sema & SemaRef,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)647676fbe81SDimitry Andric void PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(
648676fbe81SDimitry Andric     Sema &SemaRef, CodeCompletionContext Context, CodeCompletionResult *Results,
6494c8b2481SRoman Divacky     unsigned NumResults) {
6503d1dcd9bSDimitry Andric   std::stable_sort(Results, Results + NumResults);
6513d1dcd9bSDimitry Andric 
652676fbe81SDimitry Andric   if (!Context.getPreferredType().isNull())
653145449b1SDimitry Andric     OS << "PREFERRED-TYPE: " << Context.getPreferredType() << '\n';
654bab175ecSDimitry Andric 
655676fbe81SDimitry Andric   StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter();
656676fbe81SDimitry Andric   // Print the completions.
6574c8b2481SRoman Divacky   for (unsigned I = 0; I != NumResults; ++I) {
658bab175ecSDimitry Andric     if (!Filter.empty() && isResultFilteredOut(Filter, Results[I]))
659bab175ecSDimitry Andric       continue;
6604c8b2481SRoman Divacky     OS << "COMPLETION: ";
6614c8b2481SRoman Divacky     switch (Results[I].Kind) {
6623d1dcd9bSDimitry Andric     case CodeCompletionResult::RK_Declaration:
66336981b17SDimitry Andric       OS << *Results[I].Declaration;
664676fbe81SDimitry Andric       {
665676fbe81SDimitry Andric         std::vector<std::string> Tags;
6664c8b2481SRoman Divacky         if (Results[I].Hidden)
667676fbe81SDimitry Andric           Tags.push_back("Hidden");
668676fbe81SDimitry Andric         if (Results[I].InBaseClass)
669676fbe81SDimitry Andric           Tags.push_back("InBase");
670676fbe81SDimitry Andric         if (Results[I].Availability ==
671676fbe81SDimitry Andric             CXAvailabilityKind::CXAvailability_NotAccessible)
672676fbe81SDimitry Andric           Tags.push_back("Inaccessible");
673676fbe81SDimitry Andric         if (!Tags.empty())
674676fbe81SDimitry Andric           OS << " (" << llvm::join(Tags, ",") << ")";
675676fbe81SDimitry Andric       }
676676fbe81SDimitry Andric       if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(
677676fbe81SDimitry Andric               SemaRef, Context, getAllocator(), CCTUInfo,
67856d91b49SDimitry Andric               includeBriefComments())) {
6794c8b2481SRoman Divacky         OS << " : " << CCS->getAsString();
68056d91b49SDimitry Andric         if (const char *BriefComment = CCS->getBriefComment())
68156d91b49SDimitry Andric           OS << " : " << BriefComment;
6824c8b2481SRoman Divacky       }
683cfca06d7SDimitry Andric       break;
684cfca06d7SDimitry Andric 
685cfca06d7SDimitry Andric     case CodeCompletionResult::RK_Keyword:
686cfca06d7SDimitry Andric       OS << Results[I].Keyword;
687cfca06d7SDimitry Andric       break;
688cfca06d7SDimitry Andric 
689cfca06d7SDimitry Andric     case CodeCompletionResult::RK_Macro:
690cfca06d7SDimitry Andric       OS << Results[I].Macro->getName();
691cfca06d7SDimitry Andric       if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(
692cfca06d7SDimitry Andric               SemaRef, Context, getAllocator(), CCTUInfo,
693cfca06d7SDimitry Andric               includeBriefComments())) {
694cfca06d7SDimitry Andric         OS << " : " << CCS->getAsString();
695cfca06d7SDimitry Andric       }
696cfca06d7SDimitry Andric       break;
697cfca06d7SDimitry Andric 
698cfca06d7SDimitry Andric     case CodeCompletionResult::RK_Pattern:
699cfca06d7SDimitry Andric       OS << "Pattern : " << Results[I].Pattern->getAsString();
700cfca06d7SDimitry Andric       break;
701cfca06d7SDimitry Andric     }
70248675466SDimitry Andric     for (const FixItHint &FixIt : Results[I].FixIts) {
70348675466SDimitry Andric       const SourceLocation BLoc = FixIt.RemoveRange.getBegin();
70448675466SDimitry Andric       const SourceLocation ELoc = FixIt.RemoveRange.getEnd();
7054c8b2481SRoman Divacky 
70648675466SDimitry Andric       SourceManager &SM = SemaRef.SourceMgr;
70748675466SDimitry Andric       std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc);
70848675466SDimitry Andric       std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(ELoc);
70948675466SDimitry Andric       // Adjust for token ranges.
71048675466SDimitry Andric       if (FixIt.RemoveRange.isTokenRange())
71148675466SDimitry Andric         EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, SemaRef.LangOpts);
71248675466SDimitry Andric 
71348675466SDimitry Andric       OS << " (requires fix-it:"
71448675466SDimitry Andric          << " {" << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
71548675466SDimitry Andric          << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
71648675466SDimitry Andric          << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
71748675466SDimitry Andric          << SM.getColumnNumber(EInfo.first, EInfo.second) << "}"
71848675466SDimitry Andric          << " to \"" << FixIt.CodeToInsert << "\")";
71948675466SDimitry Andric     }
7204c8b2481SRoman Divacky     OS << '\n';
7214c8b2481SRoman Divacky   }
7224c8b2481SRoman Divacky }
7234c8b2481SRoman Divacky 
7245e20cdd8SDimitry Andric // This function is used solely to preserve the former presentation of overloads
7255e20cdd8SDimitry Andric // by "clang -cc1 -code-completion-at", since CodeCompletionString::getAsString
7265e20cdd8SDimitry Andric // needs to be improved for printing the newer and more detailed overload
7275e20cdd8SDimitry Andric // chunks.
getOverloadAsString(const CodeCompletionString & CCS)7285e20cdd8SDimitry Andric static std::string getOverloadAsString(const CodeCompletionString &CCS) {
7295e20cdd8SDimitry Andric   std::string Result;
7305e20cdd8SDimitry Andric   llvm::raw_string_ostream OS(Result);
7315e20cdd8SDimitry Andric 
7325e20cdd8SDimitry Andric   for (auto &C : CCS) {
7335e20cdd8SDimitry Andric     switch (C.Kind) {
7345e20cdd8SDimitry Andric     case CodeCompletionString::CK_Informative:
7355e20cdd8SDimitry Andric     case CodeCompletionString::CK_ResultType:
7365e20cdd8SDimitry Andric       OS << "[#" << C.Text << "#]";
7375e20cdd8SDimitry Andric       break;
7385e20cdd8SDimitry Andric 
7395e20cdd8SDimitry Andric     case CodeCompletionString::CK_CurrentParameter:
7405e20cdd8SDimitry Andric       OS << "<#" << C.Text << "#>";
7415e20cdd8SDimitry Andric       break;
7425e20cdd8SDimitry Andric 
743676fbe81SDimitry Andric     // FIXME: We can also print optional parameters of an overload.
744676fbe81SDimitry Andric     case CodeCompletionString::CK_Optional:
745676fbe81SDimitry Andric       break;
746676fbe81SDimitry Andric 
747676fbe81SDimitry Andric     default:
748676fbe81SDimitry Andric       OS << C.Text;
749676fbe81SDimitry Andric       break;
7505e20cdd8SDimitry Andric     }
7515e20cdd8SDimitry Andric   }
75277fc4c14SDimitry Andric   return Result;
7535e20cdd8SDimitry Andric }
7545e20cdd8SDimitry Andric 
ProcessOverloadCandidates(Sema & SemaRef,unsigned CurrentArg,OverloadCandidate * Candidates,unsigned NumCandidates,SourceLocation OpenParLoc,bool Braced)755676fbe81SDimitry Andric void PrintingCodeCompleteConsumer::ProcessOverloadCandidates(
756676fbe81SDimitry Andric     Sema &SemaRef, unsigned CurrentArg, OverloadCandidate *Candidates,
7576f8fc217SDimitry Andric     unsigned NumCandidates, SourceLocation OpenParLoc, bool Braced) {
758676fbe81SDimitry Andric   OS << "OPENING_PAREN_LOC: ";
759676fbe81SDimitry Andric   OpenParLoc.print(OS, SemaRef.getSourceManager());
760676fbe81SDimitry Andric   OS << "\n";
761676fbe81SDimitry Andric 
7624c8b2481SRoman Divacky   for (unsigned I = 0; I != NumCandidates; ++I) {
763676fbe81SDimitry Andric     if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString(
764676fbe81SDimitry Andric             CurrentArg, SemaRef, getAllocator(), CCTUInfo,
7656f8fc217SDimitry Andric             includeBriefComments(), Braced)) {
7665e20cdd8SDimitry Andric       OS << "OVERLOAD: " << getOverloadAsString(*CCS) << "\n";
7674c8b2481SRoman Divacky     }
7684c8b2481SRoman Divacky   }
7694c8b2481SRoman Divacky }
770b3d5a323SRoman Divacky 
77148675466SDimitry Andric /// Retrieve the effective availability of the given declaration.
getDeclAvailability(const Decl * D)772809500fcSDimitry Andric static AvailabilityResult getDeclAvailability(const Decl *D) {
773dbe13110SDimitry Andric   AvailabilityResult AR = D->getAvailability();
774dbe13110SDimitry Andric   if (isa<EnumConstantDecl>(D))
775dbe13110SDimitry Andric     AR = std::max(AR, cast<Decl>(D->getDeclContext())->getAvailability());
776dbe13110SDimitry Andric   return AR;
777dbe13110SDimitry Andric }
778dbe13110SDimitry Andric 
computeCursorKindAndAvailability(bool Accessible)77936981b17SDimitry Andric void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) {
7803d1dcd9bSDimitry Andric   switch (Kind) {
781dbe13110SDimitry Andric   case RK_Pattern:
782dbe13110SDimitry Andric     if (!Declaration) {
783dbe13110SDimitry Andric       // Do nothing: Patterns can come with cursor kinds!
784dbe13110SDimitry Andric       break;
785dbe13110SDimitry Andric     }
786e3b55780SDimitry Andric     [[fallthrough]];
787dbe13110SDimitry Andric 
788dbe13110SDimitry Andric   case RK_Declaration: {
7893d1dcd9bSDimitry Andric     // Set the availability based on attributes.
790dbe13110SDimitry Andric     switch (getDeclAvailability(Declaration)) {
79101af97d3SDimitry Andric     case AR_Available:
79201af97d3SDimitry Andric     case AR_NotYetIntroduced:
7933d1dcd9bSDimitry Andric       Availability = CXAvailability_Available;
79401af97d3SDimitry Andric       break;
79501af97d3SDimitry Andric 
79601af97d3SDimitry Andric     case AR_Deprecated:
7973d1dcd9bSDimitry Andric       Availability = CXAvailability_Deprecated;
79801af97d3SDimitry Andric       break;
79901af97d3SDimitry Andric 
80001af97d3SDimitry Andric     case AR_Unavailable:
80101af97d3SDimitry Andric       Availability = CXAvailability_NotAvailable;
80201af97d3SDimitry Andric       break;
80301af97d3SDimitry Andric     }
8043d1dcd9bSDimitry Andric 
805676fbe81SDimitry Andric     if (const auto *Function = dyn_cast<FunctionDecl>(Declaration))
8063d1dcd9bSDimitry Andric       if (Function->isDeleted())
8073d1dcd9bSDimitry Andric         Availability = CXAvailability_NotAvailable;
8083d1dcd9bSDimitry Andric 
8093d1dcd9bSDimitry Andric     CursorKind = getCursorKindForDecl(Declaration);
810dbe13110SDimitry Andric     if (CursorKind == CXCursor_UnexposedDecl) {
811dbe13110SDimitry Andric       // FIXME: Forward declarations of Objective-C classes and protocols
812dbe13110SDimitry Andric       // are not directly exposed, but we want code completion to treat them
813dbe13110SDimitry Andric       // like a definition.
814dbe13110SDimitry Andric       if (isa<ObjCInterfaceDecl>(Declaration))
815dbe13110SDimitry Andric         CursorKind = CXCursor_ObjCInterfaceDecl;
816dbe13110SDimitry Andric       else if (isa<ObjCProtocolDecl>(Declaration))
817dbe13110SDimitry Andric         CursorKind = CXCursor_ObjCProtocolDecl;
818dbe13110SDimitry Andric       else
8193d1dcd9bSDimitry Andric         CursorKind = CXCursor_NotImplemented;
820dbe13110SDimitry Andric     }
8213d1dcd9bSDimitry Andric     break;
822dbe13110SDimitry Andric   }
8233d1dcd9bSDimitry Andric 
8243d1dcd9bSDimitry Andric   case RK_Macro:
8253d1dcd9bSDimitry Andric   case RK_Keyword:
82656d91b49SDimitry Andric     llvm_unreachable("Macro and keyword kinds are handled by the constructors");
8273d1dcd9bSDimitry Andric   }
82836981b17SDimitry Andric 
82936981b17SDimitry Andric   if (!Accessible)
83036981b17SDimitry Andric     Availability = CXAvailability_NotAccessible;
8313d1dcd9bSDimitry Andric }
8323d1dcd9bSDimitry Andric 
83348675466SDimitry Andric /// Retrieve the name that should be used to order a result.
8343d1dcd9bSDimitry Andric ///
8353d1dcd9bSDimitry Andric /// If the name needs to be constructed as a string, that string will be
8363d1dcd9bSDimitry Andric /// saved into Saved and the returned StringRef will refer to it.
getOrderedName(std::string & Saved) const837461a67faSDimitry Andric StringRef CodeCompletionResult::getOrderedName(std::string &Saved) const {
838461a67faSDimitry Andric   switch (Kind) {
839461a67faSDimitry Andric   case RK_Keyword:
840461a67faSDimitry Andric     return Keyword;
841461a67faSDimitry Andric   case RK_Pattern:
842461a67faSDimitry Andric     return Pattern->getTypedText();
843461a67faSDimitry Andric   case RK_Macro:
844461a67faSDimitry Andric     return Macro->getName();
845461a67faSDimitry Andric   case RK_Declaration:
8463d1dcd9bSDimitry Andric     // Handle declarations below.
8473d1dcd9bSDimitry Andric     break;
8483d1dcd9bSDimitry Andric   }
8493d1dcd9bSDimitry Andric 
850461a67faSDimitry Andric   DeclarationName Name = Declaration->getDeclName();
8513d1dcd9bSDimitry Andric 
8523d1dcd9bSDimitry Andric   // If the name is a simple identifier (by far the common case), or a
8533d1dcd9bSDimitry Andric   // zero-argument selector, just return a reference to that identifier.
8543d1dcd9bSDimitry Andric   if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
8553d1dcd9bSDimitry Andric     return Id->getName();
8563d1dcd9bSDimitry Andric   if (Name.isObjCZeroArgSelector())
857ac9a064cSDimitry Andric     if (const IdentifierInfo *Id =
858ac9a064cSDimitry Andric             Name.getObjCSelector().getIdentifierInfoForSlot(0))
8593d1dcd9bSDimitry Andric       return Id->getName();
8603d1dcd9bSDimitry Andric 
8613d1dcd9bSDimitry Andric   Saved = Name.getAsString();
8623d1dcd9bSDimitry Andric   return Saved;
8633d1dcd9bSDimitry Andric }
8643d1dcd9bSDimitry Andric 
operator <(const CodeCompletionResult & X,const CodeCompletionResult & Y)8653d1dcd9bSDimitry Andric bool clang::operator<(const CodeCompletionResult &X,
8663d1dcd9bSDimitry Andric                       const CodeCompletionResult &Y) {
8673d1dcd9bSDimitry Andric   std::string XSaved, YSaved;
868461a67faSDimitry Andric   StringRef XStr = X.getOrderedName(XSaved);
869461a67faSDimitry Andric   StringRef YStr = Y.getOrderedName(YSaved);
870344a3780SDimitry Andric   int cmp = XStr.compare_insensitive(YStr);
8713d1dcd9bSDimitry Andric   if (cmp)
8723d1dcd9bSDimitry Andric     return cmp < 0;
8733d1dcd9bSDimitry Andric 
8743d1dcd9bSDimitry Andric   // If case-insensitive comparison fails, try case-sensitive comparison.
875676fbe81SDimitry Andric   return XStr.compare(YStr) < 0;
8763d1dcd9bSDimitry Andric }
877