1711964ddSEugene Zelenko //===- CodeCompleteConsumer.cpp - Code Completion Interface ---------------===//
22436e711SDouglas Gregor //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
62436e711SDouglas Gregor //
72436e711SDouglas Gregor //===----------------------------------------------------------------------===//
82436e711SDouglas Gregor //
92436e711SDouglas Gregor //  This file implements the CodeCompleteConsumer class.
102436e711SDouglas Gregor //
112436e711SDouglas Gregor //===----------------------------------------------------------------------===//
12711964ddSEugene Zelenko 
132436e711SDouglas Gregor #include "clang/Sema/CodeCompleteConsumer.h"
143a02247dSChandler Carruth #include "clang-c/Index.h"
15711964ddSEugene Zelenko #include "clang/AST/Decl.h"
16711964ddSEugene Zelenko #include "clang/AST/DeclBase.h"
17de6836a3SJohn McCall #include "clang/AST/DeclObjC.h"
1819c1bfd1SJohn McCall #include "clang/AST/DeclTemplate.h"
19711964ddSEugene Zelenko #include "clang/AST/DeclarationName.h"
20711964ddSEugene Zelenko #include "clang/AST/Type.h"
21711964ddSEugene Zelenko #include "clang/Basic/IdentifierTable.h"
22644ea61dSVassil Vassilev #include "clang/Lex/Preprocessor.h"
232fab2353SIlya Biryukov #include "clang/Sema/Sema.h"
243a02247dSChandler Carruth #include "llvm/ADT/SmallString.h"
25711964ddSEugene Zelenko #include "llvm/ADT/SmallVector.h"
2676221c73SReid Kleckner #include "llvm/ADT/StringExtras.h"
27711964ddSEugene Zelenko #include "llvm/ADT/StringRef.h"
28669a25aeSDouglas Gregor #include "llvm/ADT/Twine.h"
29711964ddSEugene Zelenko #include "llvm/Support/Casting.h"
30711964ddSEugene Zelenko #include "llvm/Support/Compiler.h"
31711964ddSEugene Zelenko #include "llvm/Support/ErrorHandling.h"
322fab2353SIlya Biryukov #include "llvm/Support/FormatVariadic.h"
332436e711SDouglas Gregor #include "llvm/Support/raw_ostream.h"
342436e711SDouglas Gregor #include <algorithm>
35711964ddSEugene Zelenko #include <cassert>
36711964ddSEugene Zelenko #include <cstdint>
37711964ddSEugene Zelenko #include <string>
38ab6ccb5fSDouglas Gregor 
392436e711SDouglas Gregor using namespace clang;
402436e711SDouglas Gregor 
41fedc328aSDouglas Gregor //===----------------------------------------------------------------------===//
420212fd71SDouglas Gregor // Code completion context implementation
430212fd71SDouglas Gregor //===----------------------------------------------------------------------===//
440212fd71SDouglas Gregor 
wantConstructorResults() const450212fd71SDouglas Gregor bool CodeCompletionContext::wantConstructorResults() const {
463289ab20SIlya Biryukov   switch (CCKind) {
470ac41389SDouglas Gregor   case CCC_Recovery:
480212fd71SDouglas Gregor   case CCC_Statement:
490212fd71SDouglas Gregor   case CCC_Expression:
500212fd71SDouglas Gregor   case CCC_ObjCMessageReceiver:
510212fd71SDouglas Gregor   case CCC_ParenthesizedExpression:
52b006e099SKadir Cetinkaya   case CCC_Symbol:
53b006e099SKadir Cetinkaya   case CCC_SymbolOrNewName:
540212fd71SDouglas Gregor     return true;
550212fd71SDouglas Gregor 
560212fd71SDouglas Gregor   case CCC_TopLevel:
570212fd71SDouglas Gregor   case CCC_ObjCInterface:
580212fd71SDouglas Gregor   case CCC_ObjCImplementation:
590212fd71SDouglas Gregor   case CCC_ObjCIvarList:
600212fd71SDouglas Gregor   case CCC_ClassStructUnion:
612132584dSDouglas Gregor   case CCC_DotMemberAccess:
622132584dSDouglas Gregor   case CCC_ArrowMemberAccess:
632132584dSDouglas Gregor   case CCC_ObjCPropertyAccess:
640212fd71SDouglas Gregor   case CCC_EnumTag:
650212fd71SDouglas Gregor   case CCC_UnionTag:
660212fd71SDouglas Gregor   case CCC_ClassOrStructTag:
670212fd71SDouglas Gregor   case CCC_ObjCProtocolName:
680212fd71SDouglas Gregor   case CCC_Namespace:
690212fd71SDouglas Gregor   case CCC_Type:
70b006e099SKadir Cetinkaya   case CCC_NewName:
710212fd71SDouglas Gregor   case CCC_MacroName:
720212fd71SDouglas Gregor   case CCC_MacroNameUse:
730212fd71SDouglas Gregor   case CCC_PreprocessorExpression:
740212fd71SDouglas Gregor   case CCC_PreprocessorDirective:
750212fd71SDouglas Gregor   case CCC_NaturalLanguage:
760212fd71SDouglas Gregor   case CCC_SelectorName:
770212fd71SDouglas Gregor   case CCC_TypeQualifiers:
780ac41389SDouglas Gregor   case CCC_Other:
793a69eafaSDouglas Gregor   case CCC_OtherWithMacros:
802132584dSDouglas Gregor   case CCC_ObjCInstanceMessage:
812132584dSDouglas Gregor   case CCC_ObjCClassMessage:
822c595adfSDouglas Gregor   case CCC_ObjCInterfaceName:
832132584dSDouglas Gregor   case CCC_ObjCCategoryName:
843d8051abSSam McCall   case CCC_IncludedFile:
85ece4e920SSam McCall   case CCC_Attribute:
860212fd71SDouglas Gregor     return false;
870212fd71SDouglas Gregor   }
880212fd71SDouglas Gregor 
898a40f700SDavid Blaikie   llvm_unreachable("Invalid CodeCompletionContext::Kind!");
900212fd71SDouglas Gregor }
910212fd71SDouglas Gregor 
getCompletionKindString(CodeCompletionContext::Kind Kind)923289ab20SIlya Biryukov StringRef clang::getCompletionKindString(CodeCompletionContext::Kind Kind) {
933289ab20SIlya Biryukov   using CCKind = CodeCompletionContext::Kind;
9427d82585SIlya Biryukov   switch (Kind) {
9527d82585SIlya Biryukov   case CCKind::CCC_Other:
9627d82585SIlya Biryukov     return "Other";
9727d82585SIlya Biryukov   case CCKind::CCC_OtherWithMacros:
9827d82585SIlya Biryukov     return "OtherWithMacros";
9927d82585SIlya Biryukov   case CCKind::CCC_TopLevel:
10027d82585SIlya Biryukov     return "TopLevel";
10127d82585SIlya Biryukov   case CCKind::CCC_ObjCInterface:
10227d82585SIlya Biryukov     return "ObjCInterface";
10327d82585SIlya Biryukov   case CCKind::CCC_ObjCImplementation:
10427d82585SIlya Biryukov     return "ObjCImplementation";
10527d82585SIlya Biryukov   case CCKind::CCC_ObjCIvarList:
10627d82585SIlya Biryukov     return "ObjCIvarList";
10727d82585SIlya Biryukov   case CCKind::CCC_ClassStructUnion:
10827d82585SIlya Biryukov     return "ClassStructUnion";
10927d82585SIlya Biryukov   case CCKind::CCC_Statement:
11027d82585SIlya Biryukov     return "Statement";
11127d82585SIlya Biryukov   case CCKind::CCC_Expression:
11227d82585SIlya Biryukov     return "Expression";
11327d82585SIlya Biryukov   case CCKind::CCC_ObjCMessageReceiver:
11427d82585SIlya Biryukov     return "ObjCMessageReceiver";
11527d82585SIlya Biryukov   case CCKind::CCC_DotMemberAccess:
11627d82585SIlya Biryukov     return "DotMemberAccess";
11727d82585SIlya Biryukov   case CCKind::CCC_ArrowMemberAccess:
11827d82585SIlya Biryukov     return "ArrowMemberAccess";
11927d82585SIlya Biryukov   case CCKind::CCC_ObjCPropertyAccess:
12027d82585SIlya Biryukov     return "ObjCPropertyAccess";
12127d82585SIlya Biryukov   case CCKind::CCC_EnumTag:
12227d82585SIlya Biryukov     return "EnumTag";
12327d82585SIlya Biryukov   case CCKind::CCC_UnionTag:
12427d82585SIlya Biryukov     return "UnionTag";
12527d82585SIlya Biryukov   case CCKind::CCC_ClassOrStructTag:
12627d82585SIlya Biryukov     return "ClassOrStructTag";
12727d82585SIlya Biryukov   case CCKind::CCC_ObjCProtocolName:
12827d82585SIlya Biryukov     return "ObjCProtocolName";
12927d82585SIlya Biryukov   case CCKind::CCC_Namespace:
13027d82585SIlya Biryukov     return "Namespace";
13127d82585SIlya Biryukov   case CCKind::CCC_Type:
13227d82585SIlya Biryukov     return "Type";
133b006e099SKadir Cetinkaya   case CCKind::CCC_NewName:
134b006e099SKadir Cetinkaya     return "NewName";
135b006e099SKadir Cetinkaya   case CCKind::CCC_Symbol:
136b006e099SKadir Cetinkaya     return "Symbol";
137b006e099SKadir Cetinkaya   case CCKind::CCC_SymbolOrNewName:
138b006e099SKadir Cetinkaya     return "SymbolOrNewName";
13927d82585SIlya Biryukov   case CCKind::CCC_MacroName:
14027d82585SIlya Biryukov     return "MacroName";
14127d82585SIlya Biryukov   case CCKind::CCC_MacroNameUse:
14227d82585SIlya Biryukov     return "MacroNameUse";
14327d82585SIlya Biryukov   case CCKind::CCC_PreprocessorExpression:
14427d82585SIlya Biryukov     return "PreprocessorExpression";
14527d82585SIlya Biryukov   case CCKind::CCC_PreprocessorDirective:
14627d82585SIlya Biryukov     return "PreprocessorDirective";
14727d82585SIlya Biryukov   case CCKind::CCC_NaturalLanguage:
14827d82585SIlya Biryukov     return "NaturalLanguage";
14927d82585SIlya Biryukov   case CCKind::CCC_SelectorName:
15027d82585SIlya Biryukov     return "SelectorName";
15127d82585SIlya Biryukov   case CCKind::CCC_TypeQualifiers:
15227d82585SIlya Biryukov     return "TypeQualifiers";
15327d82585SIlya Biryukov   case CCKind::CCC_ParenthesizedExpression:
15427d82585SIlya Biryukov     return "ParenthesizedExpression";
15527d82585SIlya Biryukov   case CCKind::CCC_ObjCInstanceMessage:
15627d82585SIlya Biryukov     return "ObjCInstanceMessage";
15727d82585SIlya Biryukov   case CCKind::CCC_ObjCClassMessage:
15827d82585SIlya Biryukov     return "ObjCClassMessage";
15927d82585SIlya Biryukov   case CCKind::CCC_ObjCInterfaceName:
16027d82585SIlya Biryukov     return "ObjCInterfaceName";
16127d82585SIlya Biryukov   case CCKind::CCC_ObjCCategoryName:
16227d82585SIlya Biryukov     return "ObjCCategoryName";
1633d8051abSSam McCall   case CCKind::CCC_IncludedFile:
1643d8051abSSam McCall     return "IncludedFile";
165ece4e920SSam McCall   case CCKind::CCC_Attribute:
166ece4e920SSam McCall     return "Attribute";
16727d82585SIlya Biryukov   case CCKind::CCC_Recovery:
16827d82585SIlya Biryukov     return "Recovery";
16927d82585SIlya Biryukov   }
17027d82585SIlya Biryukov   llvm_unreachable("Invalid CodeCompletionContext::Kind!");
17127d82585SIlya Biryukov }
17227d82585SIlya Biryukov 
1730212fd71SDouglas Gregor //===----------------------------------------------------------------------===//
174fedc328aSDouglas Gregor // Code completion string implementation
175fedc328aSDouglas Gregor //===----------------------------------------------------------------------===//
176711964ddSEugene Zelenko 
Chunk(ChunkKind Kind,const char * Text)177b278aafbSDouglas Gregor CodeCompletionString::Chunk::Chunk(ChunkKind Kind, const char *Text)
178711964ddSEugene Zelenko     : Kind(Kind), Text("") {
1799eb7701dSDouglas Gregor   switch (Kind) {
1809eb7701dSDouglas Gregor   case CK_TypedText:
1819eb7701dSDouglas Gregor   case CK_Text:
1829eb7701dSDouglas Gregor   case CK_Placeholder:
1839eb7701dSDouglas Gregor   case CK_Informative:
184b3fa919cSDouglas Gregor   case CK_ResultType:
185b278aafbSDouglas Gregor   case CK_CurrentParameter:
186b278aafbSDouglas Gregor     this->Text = Text;
1879eb7701dSDouglas Gregor     break;
1889eb7701dSDouglas Gregor 
1899eb7701dSDouglas Gregor   case CK_Optional:
1901615d45dSJeffrey Yasskin     llvm_unreachable("Optional strings cannot be created from text");
1919eb7701dSDouglas Gregor 
1929eb7701dSDouglas Gregor   case CK_LeftParen:
1939eb7701dSDouglas Gregor     this->Text = "(";
1949eb7701dSDouglas Gregor     break;
1959eb7701dSDouglas Gregor 
1969eb7701dSDouglas Gregor   case CK_RightParen:
1979eb7701dSDouglas Gregor     this->Text = ")";
1989eb7701dSDouglas Gregor     break;
1999eb7701dSDouglas Gregor 
2009eb7701dSDouglas Gregor   case CK_LeftBracket:
2019eb7701dSDouglas Gregor     this->Text = "[";
2029eb7701dSDouglas Gregor     break;
2039eb7701dSDouglas Gregor 
2049eb7701dSDouglas Gregor   case CK_RightBracket:
2059eb7701dSDouglas Gregor     this->Text = "]";
2069eb7701dSDouglas Gregor     break;
2079eb7701dSDouglas Gregor 
2089eb7701dSDouglas Gregor   case CK_LeftBrace:
2099eb7701dSDouglas Gregor     this->Text = "{";
2109eb7701dSDouglas Gregor     break;
2119eb7701dSDouglas Gregor 
2129eb7701dSDouglas Gregor   case CK_RightBrace:
2139eb7701dSDouglas Gregor     this->Text = "}";
2149eb7701dSDouglas Gregor     break;
2159eb7701dSDouglas Gregor 
2169eb7701dSDouglas Gregor   case CK_LeftAngle:
2179eb7701dSDouglas Gregor     this->Text = "<";
2189eb7701dSDouglas Gregor     break;
2199eb7701dSDouglas Gregor 
2209eb7701dSDouglas Gregor   case CK_RightAngle:
2219eb7701dSDouglas Gregor     this->Text = ">";
2229eb7701dSDouglas Gregor     break;
2239eb7701dSDouglas Gregor 
2249eb7701dSDouglas Gregor   case CK_Comma:
2259eb7701dSDouglas Gregor     this->Text = ", ";
2269eb7701dSDouglas Gregor     break;
227504a6ae8SDouglas Gregor 
228504a6ae8SDouglas Gregor   case CK_Colon:
229504a6ae8SDouglas Gregor     this->Text = ":";
230504a6ae8SDouglas Gregor     break;
231504a6ae8SDouglas Gregor 
232504a6ae8SDouglas Gregor   case CK_SemiColon:
233504a6ae8SDouglas Gregor     this->Text = ";";
234504a6ae8SDouglas Gregor     break;
235504a6ae8SDouglas Gregor 
236504a6ae8SDouglas Gregor   case CK_Equal:
237504a6ae8SDouglas Gregor     this->Text = " = ";
238504a6ae8SDouglas Gregor     break;
239504a6ae8SDouglas Gregor 
240504a6ae8SDouglas Gregor   case CK_HorizontalSpace:
241504a6ae8SDouglas Gregor     this->Text = " ";
242504a6ae8SDouglas Gregor     break;
243504a6ae8SDouglas Gregor 
244504a6ae8SDouglas Gregor   case CK_VerticalSpace:
245504a6ae8SDouglas Gregor     this->Text = "\n";
246504a6ae8SDouglas Gregor     break;
2479eb7701dSDouglas Gregor   }
2485bf52697SDouglas Gregor }
2495bf52697SDouglas Gregor 
2505bf52697SDouglas Gregor CodeCompletionString::Chunk
CreateText(const char * Text)251b278aafbSDouglas Gregor CodeCompletionString::Chunk::CreateText(const char *Text) {
2525bf52697SDouglas Gregor   return Chunk(CK_Text, Text);
253fedc328aSDouglas Gregor }
254fedc328aSDouglas Gregor 
255fedc328aSDouglas Gregor CodeCompletionString::Chunk
CreateOptional(CodeCompletionString * Optional)256b278aafbSDouglas Gregor CodeCompletionString::Chunk::CreateOptional(CodeCompletionString *Optional) {
257fedc328aSDouglas Gregor   Chunk Result;
258fedc328aSDouglas Gregor   Result.Kind = CK_Optional;
259b278aafbSDouglas Gregor   Result.Optional = Optional;
260fedc328aSDouglas Gregor   return Result;
261fedc328aSDouglas Gregor }
262fedc328aSDouglas Gregor 
263fedc328aSDouglas Gregor CodeCompletionString::Chunk
CreatePlaceholder(const char * Placeholder)264b278aafbSDouglas Gregor CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) {
2655bf52697SDouglas Gregor   return Chunk(CK_Placeholder, Placeholder);
2665bf52697SDouglas Gregor }
2675bf52697SDouglas Gregor 
2685bf52697SDouglas Gregor CodeCompletionString::Chunk
CreateInformative(const char * Informative)269b278aafbSDouglas Gregor CodeCompletionString::Chunk::CreateInformative(const char *Informative) {
2705bf52697SDouglas Gregor   return Chunk(CK_Informative, Informative);
271fedc328aSDouglas Gregor }
272fedc328aSDouglas Gregor 
2739eb7701dSDouglas Gregor CodeCompletionString::Chunk
CreateResultType(const char * ResultType)274b278aafbSDouglas Gregor CodeCompletionString::Chunk::CreateResultType(const char *ResultType) {
275b3fa919cSDouglas Gregor   return Chunk(CK_ResultType, ResultType);
276b3fa919cSDouglas Gregor }
277b3fa919cSDouglas Gregor 
CreateCurrentParameter(const char * CurrentParameter)278de314b39SFangrui Song CodeCompletionString::Chunk CodeCompletionString::Chunk::CreateCurrentParameter(
279b278aafbSDouglas Gregor     const char *CurrentParameter) {
2809eb7701dSDouglas Gregor   return Chunk(CK_CurrentParameter, CurrentParameter);
2819eb7701dSDouglas Gregor }
2829eb7701dSDouglas Gregor 
CodeCompletionString(const Chunk * Chunks,unsigned NumChunks,unsigned Priority,CXAvailabilityKind Availability,const char ** Annotations,unsigned NumAnnotations,StringRef ParentName,const char * BriefComment)283de314b39SFangrui Song CodeCompletionString::CodeCompletionString(
284de314b39SFangrui Song     const Chunk *Chunks, unsigned NumChunks, unsigned Priority,
285de314b39SFangrui Song     CXAvailabilityKind Availability, const char **Annotations,
286de314b39SFangrui Song     unsigned NumAnnotations, StringRef ParentName, const char *BriefComment)
287de314b39SFangrui Song     : NumChunks(NumChunks), NumAnnotations(NumAnnotations), Priority(Priority),
288de314b39SFangrui Song       Availability(Availability), ParentName(ParentName),
289de314b39SFangrui Song       BriefComment(BriefComment) {
29098ea7f67SErik Verbruggen   assert(NumChunks <= 0xffff);
29198ea7f67SErik Verbruggen   assert(NumAnnotations <= 0xffff);
29298ea7f67SErik Verbruggen 
2931e95bc0fSEugene Zelenko   Chunk *StoredChunks = reinterpret_cast<Chunk *>(this + 1);
294b278aafbSDouglas Gregor   for (unsigned I = 0; I != NumChunks; ++I)
295b278aafbSDouglas Gregor     StoredChunks[I] = Chunks[I];
29698ea7f67SErik Verbruggen 
297de314b39SFangrui Song   const char **StoredAnnotations =
298de314b39SFangrui Song       reinterpret_cast<const char **>(StoredChunks + NumChunks);
29998ea7f67SErik Verbruggen   for (unsigned I = 0; I != NumAnnotations; ++I)
30098ea7f67SErik Verbruggen     StoredAnnotations[I] = Annotations[I];
301fedc328aSDouglas Gregor }
302fedc328aSDouglas Gregor 
getAnnotationCount() const30398ea7f67SErik Verbruggen unsigned CodeCompletionString::getAnnotationCount() const {
30498ea7f67SErik Verbruggen   return NumAnnotations;
30598ea7f67SErik Verbruggen }
30698ea7f67SErik Verbruggen 
getAnnotation(unsigned AnnotationNr) const30798ea7f67SErik Verbruggen const char *CodeCompletionString::getAnnotation(unsigned AnnotationNr) const {
30898ea7f67SErik Verbruggen   if (AnnotationNr < NumAnnotations)
30998ea7f67SErik Verbruggen     return reinterpret_cast<const char *const *>(end())[AnnotationNr];
31098ea7f67SErik Verbruggen   else
311c3ec149bSCraig Topper     return nullptr;
31298ea7f67SErik Verbruggen }
31398ea7f67SErik Verbruggen 
getAsString() const314fedc328aSDouglas Gregor std::string CodeCompletionString::getAsString() const {
315fedc328aSDouglas Gregor   std::string Result;
316fedc328aSDouglas Gregor   llvm::raw_string_ostream OS(Result);
317fedc328aSDouglas Gregor 
318de314b39SFangrui Song   for (const Chunk &C : *this) {
319de314b39SFangrui Song     switch (C.Kind) {
320de314b39SFangrui Song     case CK_Optional:
321de314b39SFangrui Song       OS << "{#" << C.Optional->getAsString() << "#}";
322de314b39SFangrui Song       break;
323de314b39SFangrui Song     case CK_Placeholder:
324de314b39SFangrui Song       OS << "<#" << C.Text << "#>";
325de314b39SFangrui Song       break;
326b3fa919cSDouglas Gregor     case CK_Informative:
327b3fa919cSDouglas Gregor     case CK_ResultType:
328de314b39SFangrui Song       OS << "[#" << C.Text << "#]";
329b3fa919cSDouglas Gregor       break;
330de314b39SFangrui Song     case CK_CurrentParameter:
331de314b39SFangrui Song       OS << "<#" << C.Text << "#>";
332de314b39SFangrui Song       break;
333de314b39SFangrui Song     default:
334de314b39SFangrui Song       OS << C.Text;
335de314b39SFangrui Song       break;
336fedc328aSDouglas Gregor     }
337fedc328aSDouglas Gregor   }
3385276002aSLogan Smith   return Result;
339fedc328aSDouglas Gregor }
340fedc328aSDouglas Gregor 
getTypedText() const34145f83ee8SDouglas Gregor const char *CodeCompletionString::getTypedText() const {
342de314b39SFangrui Song   for (const Chunk &C : *this)
343de314b39SFangrui Song     if (C.Kind == CK_TypedText)
344de314b39SFangrui Song       return C.Text;
34545f83ee8SDouglas Gregor 
346c3ec149bSCraig Topper   return nullptr;
34745f83ee8SDouglas Gregor }
34845f83ee8SDouglas Gregor 
getAllTypedText() const349322e2a3bSDavid Goldman std::string CodeCompletionString::getAllTypedText() const {
350322e2a3bSDavid Goldman   std::string Res;
351322e2a3bSDavid Goldman   for (const Chunk &C : *this)
352322e2a3bSDavid Goldman     if (C.Kind == CK_TypedText)
353322e2a3bSDavid Goldman       Res += C.Text;
354322e2a3bSDavid Goldman 
355322e2a3bSDavid Goldman   return Res;
356322e2a3bSDavid Goldman }
357322e2a3bSDavid Goldman 
CopyString(const Twine & String)3581ee89fc4SYaron Keren const char *CodeCompletionAllocator::CopyString(const Twine &String) {
3591ee89fc4SYaron Keren   SmallString<128> Data;
3601ee89fc4SYaron Keren   StringRef Ref = String.toStringRef(Data);
361669a25aeSDouglas Gregor   // FIXME: It would be more efficient to teach Twine to tell us its size and
362669a25aeSDouglas Gregor   // then add a routine there to fill in an allocated char* with the contents
363669a25aeSDouglas Gregor   // of the string.
3641e95bc0fSEugene Zelenko   char *Mem = (char *)Allocate(Ref.size() + 1, 1);
3651ee89fc4SYaron Keren   std::copy(Ref.begin(), Ref.end(), Mem);
3661ee89fc4SYaron Keren   Mem[Ref.size()] = 0;
3671ee89fc4SYaron Keren   return Mem;
368669a25aeSDouglas Gregor }
369669a25aeSDouglas Gregor 
getParentName(const DeclContext * DC)370fe0483dbSDmitri Gribenko StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) {
3715e373b2eSSimon Pilgrim   if (!isa<NamedDecl>(DC))
372711964ddSEugene Zelenko     return {};
3739d7c0fefSArgyrios Kyrtzidis 
3749d7c0fefSArgyrios Kyrtzidis   // Check whether we've already cached the parent name.
3759d7c0fefSArgyrios Kyrtzidis   StringRef &CachedParentName = ParentNames[DC];
3769d7c0fefSArgyrios Kyrtzidis   if (!CachedParentName.empty())
3779d7c0fefSArgyrios Kyrtzidis     return CachedParentName;
3789d7c0fefSArgyrios Kyrtzidis 
3799d7c0fefSArgyrios Kyrtzidis   // If we already processed this DeclContext and assigned empty to it, the
3809d7c0fefSArgyrios Kyrtzidis   // data pointer will be non-null.
381c3ec149bSCraig Topper   if (CachedParentName.data() != nullptr)
382711964ddSEugene Zelenko     return {};
3839d7c0fefSArgyrios Kyrtzidis 
3849d7c0fefSArgyrios Kyrtzidis   // Find the interesting names.
385fe0483dbSDmitri Gribenko   SmallVector<const DeclContext *, 2> Contexts;
3869d7c0fefSArgyrios Kyrtzidis   while (DC && !DC->isFunctionOrMethod()) {
387de314b39SFangrui Song     if (const auto *ND = dyn_cast<NamedDecl>(DC)) {
3889d7c0fefSArgyrios Kyrtzidis       if (ND->getIdentifier())
3899d7c0fefSArgyrios Kyrtzidis         Contexts.push_back(DC);
3909d7c0fefSArgyrios Kyrtzidis     }
3919d7c0fefSArgyrios Kyrtzidis 
3929d7c0fefSArgyrios Kyrtzidis     DC = DC->getParent();
3939d7c0fefSArgyrios Kyrtzidis   }
3949d7c0fefSArgyrios Kyrtzidis 
3959d7c0fefSArgyrios Kyrtzidis   {
396f857950dSDmitri Gribenko     SmallString<128> S;
3979d7c0fefSArgyrios Kyrtzidis     llvm::raw_svector_ostream OS(S);
3989d7c0fefSArgyrios Kyrtzidis     bool First = true;
3998adb6d6dSBenjamin Kramer     for (const DeclContext *CurDC : llvm::reverse(Contexts)) {
4009d7c0fefSArgyrios Kyrtzidis       if (First)
4019d7c0fefSArgyrios Kyrtzidis         First = false;
4029d7c0fefSArgyrios Kyrtzidis       else {
4039d7c0fefSArgyrios Kyrtzidis         OS << "::";
4049d7c0fefSArgyrios Kyrtzidis       }
4059d7c0fefSArgyrios Kyrtzidis 
406de314b39SFangrui Song       if (const auto *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
4079d7c0fefSArgyrios Kyrtzidis         CurDC = CatImpl->getCategoryDecl();
4089d7c0fefSArgyrios Kyrtzidis 
409de314b39SFangrui Song       if (const auto *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
410fe0483dbSDmitri Gribenko         const ObjCInterfaceDecl *Interface = Cat->getClassInterface();
4119d7c0fefSArgyrios Kyrtzidis         if (!Interface) {
4129d7c0fefSArgyrios Kyrtzidis           // Assign an empty StringRef but with non-null data to distinguish
4139d7c0fefSArgyrios Kyrtzidis           // between empty because we didn't process the DeclContext yet.
414d16cebefSReid Kleckner           CachedParentName = StringRef((const char *)(uintptr_t)~0U, 0);
415711964ddSEugene Zelenko           return {};
4169d7c0fefSArgyrios Kyrtzidis         }
4179d7c0fefSArgyrios Kyrtzidis 
4189d7c0fefSArgyrios Kyrtzidis         OS << Interface->getName() << '(' << Cat->getName() << ')';
4199d7c0fefSArgyrios Kyrtzidis       } else {
4209d7c0fefSArgyrios Kyrtzidis         OS << cast<NamedDecl>(CurDC)->getName();
4219d7c0fefSArgyrios Kyrtzidis       }
4229d7c0fefSArgyrios Kyrtzidis     }
4239d7c0fefSArgyrios Kyrtzidis 
4249d7c0fefSArgyrios Kyrtzidis     CachedParentName = AllocatorRef->CopyString(OS.str());
4259d7c0fefSArgyrios Kyrtzidis   }
4269d7c0fefSArgyrios Kyrtzidis 
4279d7c0fefSArgyrios Kyrtzidis   return CachedParentName;
4289d7c0fefSArgyrios Kyrtzidis }
4299d7c0fefSArgyrios Kyrtzidis 
TakeString()430b278aafbSDouglas Gregor CodeCompletionString *CodeCompletionBuilder::TakeString() {
4319d7c0fefSArgyrios Kyrtzidis   void *Mem = getAllocator().Allocate(
432c3f89253SBenjamin Kramer       sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size() +
433c3f89253SBenjamin Kramer           sizeof(const char *) * Annotations.size(),
434c3f89253SBenjamin Kramer       alignof(CodeCompletionString));
435de314b39SFangrui Song   CodeCompletionString *Result = new (Mem) CodeCompletionString(
436de314b39SFangrui Song       Chunks.data(), Chunks.size(), Priority, Availability, Annotations.data(),
437de314b39SFangrui Song       Annotations.size(), ParentName, BriefComment);
438b278aafbSDouglas Gregor   Chunks.clear();
43945f83ee8SDouglas Gregor   return Result;
44045f83ee8SDouglas Gregor }
4419eb7701dSDouglas Gregor 
AddTypedTextChunk(const char * Text)442db534a4eSBenjamin Kramer void CodeCompletionBuilder::AddTypedTextChunk(const char *Text) {
443db534a4eSBenjamin Kramer   Chunks.push_back(Chunk(CodeCompletionString::CK_TypedText, Text));
444db534a4eSBenjamin Kramer }
445db534a4eSBenjamin Kramer 
AddTextChunk(const char * Text)446db534a4eSBenjamin Kramer void CodeCompletionBuilder::AddTextChunk(const char *Text) {
447db534a4eSBenjamin Kramer   Chunks.push_back(Chunk::CreateText(Text));
448db534a4eSBenjamin Kramer }
449db534a4eSBenjamin Kramer 
AddOptionalChunk(CodeCompletionString * Optional)450db534a4eSBenjamin Kramer void CodeCompletionBuilder::AddOptionalChunk(CodeCompletionString *Optional) {
451db534a4eSBenjamin Kramer   Chunks.push_back(Chunk::CreateOptional(Optional));
452db534a4eSBenjamin Kramer }
453db534a4eSBenjamin Kramer 
AddPlaceholderChunk(const char * Placeholder)454db534a4eSBenjamin Kramer void CodeCompletionBuilder::AddPlaceholderChunk(const char *Placeholder) {
455db534a4eSBenjamin Kramer   Chunks.push_back(Chunk::CreatePlaceholder(Placeholder));
456db534a4eSBenjamin Kramer }
457db534a4eSBenjamin Kramer 
AddInformativeChunk(const char * Text)458db534a4eSBenjamin Kramer void CodeCompletionBuilder::AddInformativeChunk(const char *Text) {
459db534a4eSBenjamin Kramer   Chunks.push_back(Chunk::CreateInformative(Text));
460db534a4eSBenjamin Kramer }
461db534a4eSBenjamin Kramer 
AddResultTypeChunk(const char * ResultType)462db534a4eSBenjamin Kramer void CodeCompletionBuilder::AddResultTypeChunk(const char *ResultType) {
463db534a4eSBenjamin Kramer   Chunks.push_back(Chunk::CreateResultType(ResultType));
464db534a4eSBenjamin Kramer }
465db534a4eSBenjamin Kramer 
AddCurrentParameterChunk(const char * CurrentParameter)466de314b39SFangrui Song void CodeCompletionBuilder::AddCurrentParameterChunk(
467de314b39SFangrui Song     const char *CurrentParameter) {
468db534a4eSBenjamin Kramer   Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter));
469db534a4eSBenjamin Kramer }
470db534a4eSBenjamin Kramer 
AddChunk(CodeCompletionString::ChunkKind CK,const char * Text)471db534a4eSBenjamin Kramer void CodeCompletionBuilder::AddChunk(CodeCompletionString::ChunkKind CK,
472db534a4eSBenjamin Kramer                                      const char *Text) {
473db534a4eSBenjamin Kramer   Chunks.push_back(Chunk(CK, Text));
474db534a4eSBenjamin Kramer }
475db534a4eSBenjamin Kramer 
addParentContext(const DeclContext * DC)476fe0483dbSDmitri Gribenko void CodeCompletionBuilder::addParentContext(const DeclContext *DC) {
477711964ddSEugene Zelenko   if (DC->isTranslationUnit())
47878254c88SDouglas Gregor     return;
47978254c88SDouglas Gregor 
48078254c88SDouglas Gregor   if (DC->isFunctionOrMethod())
48178254c88SDouglas Gregor     return;
48278254c88SDouglas Gregor 
4835e373b2eSSimon Pilgrim   if (!isa<NamedDecl>(DC))
48478254c88SDouglas Gregor     return;
48578254c88SDouglas Gregor 
4869d7c0fefSArgyrios Kyrtzidis   ParentName = getCodeCompletionTUInfo().getParentName(DC);
48778254c88SDouglas Gregor }
48878254c88SDouglas Gregor 
addBriefComment(StringRef Comment)4893292d06aSDmitri Gribenko void CodeCompletionBuilder::addBriefComment(StringRef Comment) {
4903292d06aSDmitri Gribenko   BriefComment = Allocator.CopyString(Comment);
4913292d06aSDmitri Gribenko }
4923292d06aSDmitri Gribenko 
493fedc328aSDouglas Gregor //===----------------------------------------------------------------------===//
49405f477c1SDouglas Gregor // Code completion overload candidate implementation
49505f477c1SDouglas Gregor //===----------------------------------------------------------------------===//
getFunction() const496de314b39SFangrui Song FunctionDecl *CodeCompleteConsumer::OverloadCandidate::getFunction() const {
49705f477c1SDouglas Gregor   if (getKind() == CK_Function)
49805f477c1SDouglas Gregor     return Function;
49905f477c1SDouglas Gregor   else if (getKind() == CK_FunctionTemplate)
50005f477c1SDouglas Gregor     return FunctionTemplate->getTemplatedDecl();
50105f477c1SDouglas Gregor   else
502c3ec149bSCraig Topper     return nullptr;
50305f477c1SDouglas Gregor }
50405f477c1SDouglas Gregor 
50505f477c1SDouglas Gregor const FunctionType *
getFunctionType() const50605f477c1SDouglas Gregor CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
50705f477c1SDouglas Gregor   switch (Kind) {
50805f477c1SDouglas Gregor   case CK_Function:
50905f477c1SDouglas Gregor     return Function->getType()->getAs<FunctionType>();
51005f477c1SDouglas Gregor 
51105f477c1SDouglas Gregor   case CK_FunctionTemplate:
512de314b39SFangrui Song     return FunctionTemplate->getTemplatedDecl()
513de314b39SFangrui Song         ->getType()
51405f477c1SDouglas Gregor         ->getAs<FunctionType>();
51505f477c1SDouglas Gregor 
51605f477c1SDouglas Gregor   case CK_FunctionType:
51705f477c1SDouglas Gregor     return Type;
518*3f73c579SQwinci   case CK_FunctionProtoTypeLoc:
519*3f73c579SQwinci     return ProtoTypeLoc.getTypePtr();
520cd45e8c7SSam McCall   case CK_Template:
521229c95abSSam McCall   case CK_Aggregate:
522cd45e8c7SSam McCall     return nullptr;
52305f477c1SDouglas Gregor   }
52405f477c1SDouglas Gregor 
5258a40f700SDavid Blaikie   llvm_unreachable("Invalid CandidateKind!");
52605f477c1SDouglas Gregor }
52705f477c1SDouglas Gregor 
528*3f73c579SQwinci const FunctionProtoTypeLoc
getFunctionProtoTypeLoc() const529*3f73c579SQwinci CodeCompleteConsumer::OverloadCandidate::getFunctionProtoTypeLoc() const {
530*3f73c579SQwinci   if (Kind == CK_FunctionProtoTypeLoc)
531*3f73c579SQwinci     return ProtoTypeLoc;
532*3f73c579SQwinci   return FunctionProtoTypeLoc();
533*3f73c579SQwinci }
534*3f73c579SQwinci 
getNumParams() const535cd45e8c7SSam McCall unsigned CodeCompleteConsumer::OverloadCandidate::getNumParams() const {
536cd45e8c7SSam McCall   if (Kind == CK_Template)
537cd45e8c7SSam McCall     return Template->getTemplateParameters()->size();
538229c95abSSam McCall 
539229c95abSSam McCall   if (Kind == CK_Aggregate) {
540229c95abSSam McCall     unsigned Count =
541229c95abSSam McCall         std::distance(AggregateType->field_begin(), AggregateType->field_end());
542229c95abSSam McCall     if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType))
543229c95abSSam McCall       Count += CRD->getNumBases();
544229c95abSSam McCall     return Count;
545229c95abSSam McCall   }
546229c95abSSam McCall 
547229c95abSSam McCall   if (const auto *FT = getFunctionType())
548229c95abSSam McCall     if (const auto *FPT = dyn_cast<FunctionProtoType>(FT))
549cd45e8c7SSam McCall       return FPT->getNumParams();
550229c95abSSam McCall 
551cd45e8c7SSam McCall   return 0;
552cd45e8c7SSam McCall }
553cd45e8c7SSam McCall 
554229c95abSSam McCall QualType
getParamType(unsigned N) const555229c95abSSam McCall CodeCompleteConsumer::OverloadCandidate::getParamType(unsigned N) const {
556229c95abSSam McCall   if (Kind == CK_Aggregate) {
557229c95abSSam McCall     if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) {
558229c95abSSam McCall       if (N < CRD->getNumBases())
559229c95abSSam McCall         return std::next(CRD->bases_begin(), N)->getType();
560229c95abSSam McCall       N -= CRD->getNumBases();
561229c95abSSam McCall     }
562229c95abSSam McCall     for (const auto *Field : AggregateType->fields())
563229c95abSSam McCall       if (N-- == 0)
564229c95abSSam McCall         return Field->getType();
565229c95abSSam McCall     return QualType();
566229c95abSSam McCall   }
567229c95abSSam McCall 
568229c95abSSam McCall   if (Kind == CK_Template) {
569229c95abSSam McCall     TemplateParameterList *TPL = getTemplate()->getTemplateParameters();
570229c95abSSam McCall     if (N < TPL->size())
571229c95abSSam McCall       if (const auto *D = dyn_cast<NonTypeTemplateParmDecl>(TPL->getParam(N)))
572229c95abSSam McCall         return D->getType();
573229c95abSSam McCall     return QualType();
574229c95abSSam McCall   }
575229c95abSSam McCall 
576229c95abSSam McCall   if (const auto *FT = getFunctionType())
577229c95abSSam McCall     if (const auto *FPT = dyn_cast<FunctionProtoType>(FT))
578229c95abSSam McCall       if (N < FPT->getNumParams())
579229c95abSSam McCall         return FPT->getParamType(N);
580229c95abSSam McCall   return QualType();
581229c95abSSam McCall }
582229c95abSSam McCall 
583229c95abSSam McCall const NamedDecl *
getParamDecl(unsigned N) const584229c95abSSam McCall CodeCompleteConsumer::OverloadCandidate::getParamDecl(unsigned N) const {
585229c95abSSam McCall   if (Kind == CK_Aggregate) {
586229c95abSSam McCall     if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) {
587229c95abSSam McCall       if (N < CRD->getNumBases())
588229c95abSSam McCall         return std::next(CRD->bases_begin(), N)->getType()->getAsTagDecl();
589229c95abSSam McCall       N -= CRD->getNumBases();
590229c95abSSam McCall     }
591229c95abSSam McCall     for (const auto *Field : AggregateType->fields())
592229c95abSSam McCall       if (N-- == 0)
593229c95abSSam McCall         return Field;
594229c95abSSam McCall     return nullptr;
595229c95abSSam McCall   }
596229c95abSSam McCall 
597229c95abSSam McCall   if (Kind == CK_Template) {
598229c95abSSam McCall     TemplateParameterList *TPL = getTemplate()->getTemplateParameters();
599229c95abSSam McCall     if (N < TPL->size())
600229c95abSSam McCall       return TPL->getParam(N);
601229c95abSSam McCall     return nullptr;
602229c95abSSam McCall   }
603229c95abSSam McCall 
604229c95abSSam McCall   // Note that if we only have a FunctionProtoType, we don't have param decls.
605229c95abSSam McCall   if (const auto *FD = getFunction()) {
606229c95abSSam McCall     if (N < FD->param_size())
607229c95abSSam McCall       return FD->getParamDecl(N);
608*3f73c579SQwinci   } else if (Kind == CK_FunctionProtoTypeLoc) {
609*3f73c579SQwinci     if (N < ProtoTypeLoc.getNumParams()) {
610*3f73c579SQwinci       return ProtoTypeLoc.getParam(N);
611229c95abSSam McCall     }
612*3f73c579SQwinci   }
613*3f73c579SQwinci 
614229c95abSSam McCall   return nullptr;
615229c95abSSam McCall }
616229c95abSSam McCall 
61705f477c1SDouglas Gregor //===----------------------------------------------------------------------===//
618fedc328aSDouglas Gregor // Code completion consumer implementation
619fedc328aSDouglas Gregor //===----------------------------------------------------------------------===//
620fedc328aSDouglas Gregor 
621711964ddSEugene Zelenko CodeCompleteConsumer::~CodeCompleteConsumer() = default;
622fedc328aSDouglas Gregor 
isResultFilteredOut(StringRef Filter,CodeCompletionResult Result)623de314b39SFangrui Song bool PrintingCodeCompleteConsumer::isResultFilteredOut(
624de314b39SFangrui Song     StringRef Filter, CodeCompletionResult Result) {
625644ea61dSVassil Vassilev   switch (Result.Kind) {
626711964ddSEugene Zelenko   case CodeCompletionResult::RK_Declaration:
627644ea61dSVassil Vassilev     return !(Result.Declaration->getIdentifier() &&
628644ea61dSVassil Vassilev              Result.Declaration->getIdentifier()->getName().startswith(Filter));
629711964ddSEugene Zelenko   case CodeCompletionResult::RK_Keyword:
630644ea61dSVassil Vassilev     return !StringRef(Result.Keyword).startswith(Filter);
631711964ddSEugene Zelenko   case CodeCompletionResult::RK_Macro:
632644ea61dSVassil Vassilev     return !Result.Macro->getName().startswith(Filter);
633711964ddSEugene Zelenko   case CodeCompletionResult::RK_Pattern:
6343d8051abSSam McCall     return !(Result.Pattern->getTypedText() &&
6353d8051abSSam McCall              StringRef(Result.Pattern->getTypedText()).startswith(Filter));
636644ea61dSVassil Vassilev   }
637e71a1f90SSimon Pilgrim   llvm_unreachable("Unknown code completion result Kind.");
638644ea61dSVassil Vassilev }
639644ea61dSVassil Vassilev 
ProcessCodeCompleteResults(Sema & SemaRef,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)640de314b39SFangrui Song void PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(
641de314b39SFangrui Song     Sema &SemaRef, CodeCompletionContext Context, CodeCompletionResult *Results,
6422436e711SDouglas Gregor     unsigned NumResults) {
64349f67ce4SDouglas Gregor   std::stable_sort(Results, Results + NumResults);
64449f67ce4SDouglas Gregor 
6454110967cSIlya Biryukov   if (!Context.getPreferredType().isNull())
646cfb81690SNathan James     OS << "PREFERRED-TYPE: " << Context.getPreferredType() << '\n';
647644ea61dSVassil Vassilev 
6484110967cSIlya Biryukov   StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter();
6494110967cSIlya Biryukov   // Print the completions.
6502436e711SDouglas Gregor   for (unsigned I = 0; I != NumResults; ++I) {
651644ea61dSVassil Vassilev     if (!Filter.empty() && isResultFilteredOut(Filter, Results[I]))
652644ea61dSVassil Vassilev       continue;
65358acf32aSDouglas Gregor     OS << "COMPLETION: ";
6542436e711SDouglas Gregor     switch (Results[I].Kind) {
655276321a9SJohn McCall     case CodeCompletionResult::RK_Declaration:
656b89514a9SBenjamin Kramer       OS << *Results[I].Declaration;
6574a7cd637SEric Liu       {
6584a7cd637SEric Liu         std::vector<std::string> Tags;
6592436e711SDouglas Gregor         if (Results[I].Hidden)
6604a7cd637SEric Liu           Tags.push_back("Hidden");
6614a7cd637SEric Liu         if (Results[I].InBaseClass)
6624a7cd637SEric Liu           Tags.push_back("InBase");
663f1822ec4SIlya Biryukov         if (Results[I].Availability ==
664f1822ec4SIlya Biryukov             CXAvailabilityKind::CXAvailability_NotAccessible)
665f1822ec4SIlya Biryukov           Tags.push_back("Inaccessible");
6664a7cd637SEric Liu         if (!Tags.empty())
6674a7cd637SEric Liu           OS << " (" << llvm::join(Tags, ",") << ")";
6684a7cd637SEric Liu       }
6694a7cd637SEric Liu       if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(
6704a7cd637SEric Liu               SemaRef, Context, getAllocator(), CCTUInfo,
6713292d06aSDmitri Gribenko               includeBriefComments())) {
672fedc328aSDouglas Gregor         OS << " : " << CCS->getAsString();
6733292d06aSDmitri Gribenko         if (const char *BriefComment = CCS->getBriefComment())
6743292d06aSDmitri Gribenko           OS << " : " << BriefComment;
675fedc328aSDouglas Gregor       }
676a76e68c9SSam McCall       break;
677a76e68c9SSam McCall 
678a76e68c9SSam McCall     case CodeCompletionResult::RK_Keyword:
679a76e68c9SSam McCall       OS << Results[I].Keyword;
680a76e68c9SSam McCall       break;
681a76e68c9SSam McCall 
682a76e68c9SSam McCall     case CodeCompletionResult::RK_Macro:
683a76e68c9SSam McCall       OS << Results[I].Macro->getName();
684a76e68c9SSam McCall       if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(
685a76e68c9SSam McCall               SemaRef, Context, getAllocator(), CCTUInfo,
686a76e68c9SSam McCall               includeBriefComments())) {
687a76e68c9SSam McCall         OS << " : " << CCS->getAsString();
688a76e68c9SSam McCall       }
689a76e68c9SSam McCall       break;
690a76e68c9SSam McCall 
691a76e68c9SSam McCall     case CodeCompletionResult::RK_Pattern:
692a76e68c9SSam McCall       OS << "Pattern : " << Results[I].Pattern->getAsString();
693a76e68c9SSam McCall       break;
694a76e68c9SSam McCall     }
695b4670fc7SIvan Donchevskii     for (const FixItHint &FixIt : Results[I].FixIts) {
696b4670fc7SIvan Donchevskii       const SourceLocation BLoc = FixIt.RemoveRange.getBegin();
697b4670fc7SIvan Donchevskii       const SourceLocation ELoc = FixIt.RemoveRange.getEnd();
698b4670fc7SIvan Donchevskii 
699b4670fc7SIvan Donchevskii       SourceManager &SM = SemaRef.SourceMgr;
700b4670fc7SIvan Donchevskii       std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc);
701b4670fc7SIvan Donchevskii       std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(ELoc);
702b4670fc7SIvan Donchevskii       // Adjust for token ranges.
703b4670fc7SIvan Donchevskii       if (FixIt.RemoveRange.isTokenRange())
704b4670fc7SIvan Donchevskii         EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, SemaRef.LangOpts);
705b4670fc7SIvan Donchevskii 
706b4670fc7SIvan Donchevskii       OS << " (requires fix-it:"
707b4670fc7SIvan Donchevskii          << " {" << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
708b4670fc7SIvan Donchevskii          << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
709b4670fc7SIvan Donchevskii          << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
710b4670fc7SIvan Donchevskii          << SM.getColumnNumber(EInfo.first, EInfo.second) << "}"
711b4670fc7SIvan Donchevskii          << " to \"" << FixIt.CodeToInsert << "\")";
712b4670fc7SIvan Donchevskii     }
7132436e711SDouglas Gregor     OS << '\n';
7142436e711SDouglas Gregor   }
7152436e711SDouglas Gregor }
71605f477c1SDouglas Gregor 
7170c010cddSFrancisco Lopes da Silva // This function is used solely to preserve the former presentation of overloads
7180c010cddSFrancisco Lopes da Silva // by "clang -cc1 -code-completion-at", since CodeCompletionString::getAsString
7190c010cddSFrancisco Lopes da Silva // needs to be improved for printing the newer and more detailed overload
7200c010cddSFrancisco Lopes da Silva // chunks.
getOverloadAsString(const CodeCompletionString & CCS)7210c010cddSFrancisco Lopes da Silva static std::string getOverloadAsString(const CodeCompletionString &CCS) {
7220c010cddSFrancisco Lopes da Silva   std::string Result;
7230c010cddSFrancisco Lopes da Silva   llvm::raw_string_ostream OS(Result);
7240c010cddSFrancisco Lopes da Silva 
7250c010cddSFrancisco Lopes da Silva   for (auto &C : CCS) {
7260c010cddSFrancisco Lopes da Silva     switch (C.Kind) {
7270c010cddSFrancisco Lopes da Silva     case CodeCompletionString::CK_Informative:
7280c010cddSFrancisco Lopes da Silva     case CodeCompletionString::CK_ResultType:
7290c010cddSFrancisco Lopes da Silva       OS << "[#" << C.Text << "#]";
7300c010cddSFrancisco Lopes da Silva       break;
7310c010cddSFrancisco Lopes da Silva 
7320c010cddSFrancisco Lopes da Silva     case CodeCompletionString::CK_CurrentParameter:
7330c010cddSFrancisco Lopes da Silva       OS << "<#" << C.Text << "#>";
7340c010cddSFrancisco Lopes da Silva       break;
7350c010cddSFrancisco Lopes da Silva 
736a32d253fSKadir Cetinkaya     // FIXME: We can also print optional parameters of an overload.
737a32d253fSKadir Cetinkaya     case CodeCompletionString::CK_Optional:
738a32d253fSKadir Cetinkaya       break;
739a32d253fSKadir Cetinkaya 
740de314b39SFangrui Song     default:
741de314b39SFangrui Song       OS << C.Text;
742de314b39SFangrui Song       break;
7430c010cddSFrancisco Lopes da Silva     }
7440c010cddSFrancisco Lopes da Silva   }
7455276002aSLogan Smith   return Result;
7460c010cddSFrancisco Lopes da Silva }
7470c010cddSFrancisco Lopes da Silva 
ProcessOverloadCandidates(Sema & SemaRef,unsigned CurrentArg,OverloadCandidate * Candidates,unsigned NumCandidates,SourceLocation OpenParLoc,bool Braced)7482fab2353SIlya Biryukov void PrintingCodeCompleteConsumer::ProcessOverloadCandidates(
7492fab2353SIlya Biryukov     Sema &SemaRef, unsigned CurrentArg, OverloadCandidate *Candidates,
75092417eafSSam McCall     unsigned NumCandidates, SourceLocation OpenParLoc, bool Braced) {
7512fab2353SIlya Biryukov   OS << "OPENING_PAREN_LOC: ";
7522fab2353SIlya Biryukov   OpenParLoc.print(OS, SemaRef.getSourceManager());
7532fab2353SIlya Biryukov   OS << "\n";
7542fab2353SIlya Biryukov 
75505f477c1SDouglas Gregor   for (unsigned I = 0; I != NumCandidates; ++I) {
7562fab2353SIlya Biryukov     if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString(
7572fab2353SIlya Biryukov             CurrentArg, SemaRef, getAllocator(), CCTUInfo,
75892417eafSSam McCall             includeBriefComments(), Braced)) {
7590c010cddSFrancisco Lopes da Silva       OS << "OVERLOAD: " << getOverloadAsString(*CCS) << "\n";
76005f477c1SDouglas Gregor     }
76105f477c1SDouglas Gregor   }
76205f477c1SDouglas Gregor }
7639eb7701dSDouglas Gregor 
7649fc8faf9SAdrian Prantl /// Retrieve the effective availability of the given declaration.
getDeclAvailability(const Decl * D)765fe0483dbSDmitri Gribenko static AvailabilityResult getDeclAvailability(const Decl *D) {
7667b316825SDouglas Gregor   AvailabilityResult AR = D->getAvailability();
7677b316825SDouglas Gregor   if (isa<EnumConstantDecl>(D))
7687b316825SDouglas Gregor     AR = std::max(AR, cast<Decl>(D->getDeclContext())->getAvailability());
7697b316825SDouglas Gregor   return AR;
7707b316825SDouglas Gregor }
7717b316825SDouglas Gregor 
computeCursorKindAndAvailability(bool Accessible)7722e657ffdSErik Verbruggen void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) {
773b14904c4SDouglas Gregor   switch (Kind) {
77478254c88SDouglas Gregor   case RK_Pattern:
77578254c88SDouglas Gregor     if (!Declaration) {
77678254c88SDouglas Gregor       // Do nothing: Patterns can come with cursor kinds!
77778254c88SDouglas Gregor       break;
77878254c88SDouglas Gregor     }
779f3b3ccdaSAdrian Prantl     LLVM_FALLTHROUGH;
78078254c88SDouglas Gregor 
7817b316825SDouglas Gregor   case RK_Declaration: {
782f757a12dSDouglas Gregor     // Set the availability based on attributes.
7837b316825SDouglas Gregor     switch (getDeclAvailability(Declaration)) {
78420b2ebd7SDouglas Gregor     case AR_Available:
78520b2ebd7SDouglas Gregor     case AR_NotYetIntroduced:
786f757a12dSDouglas Gregor       Availability = CXAvailability_Available;
78720b2ebd7SDouglas Gregor       break;
78820b2ebd7SDouglas Gregor 
78920b2ebd7SDouglas Gregor     case AR_Deprecated:
790f757a12dSDouglas Gregor       Availability = CXAvailability_Deprecated;
79120b2ebd7SDouglas Gregor       break;
79220b2ebd7SDouglas Gregor 
79320b2ebd7SDouglas Gregor     case AR_Unavailable:
79420b2ebd7SDouglas Gregor       Availability = CXAvailability_NotAvailable;
79520b2ebd7SDouglas Gregor       break;
79620b2ebd7SDouglas Gregor     }
797f757a12dSDouglas Gregor 
798de314b39SFangrui Song     if (const auto *Function = dyn_cast<FunctionDecl>(Declaration))
79909c0eb15SDouglas Gregor       if (Function->isDeleted())
800f757a12dSDouglas Gregor         Availability = CXAvailability_NotAvailable;
801f09935f1SDouglas Gregor 
80209c0eb15SDouglas Gregor     CursorKind = getCursorKindForDecl(Declaration);
803deafd0b2SDouglas Gregor     if (CursorKind == CXCursor_UnexposedDecl) {
804f6102675SDouglas Gregor       // FIXME: Forward declarations of Objective-C classes and protocols
805f6102675SDouglas Gregor       // are not directly exposed, but we want code completion to treat them
806f6102675SDouglas Gregor       // like a definition.
807deafd0b2SDouglas Gregor       if (isa<ObjCInterfaceDecl>(Declaration))
808deafd0b2SDouglas Gregor         CursorKind = CXCursor_ObjCInterfaceDecl;
809f6102675SDouglas Gregor       else if (isa<ObjCProtocolDecl>(Declaration))
810f6102675SDouglas Gregor         CursorKind = CXCursor_ObjCProtocolDecl;
811deafd0b2SDouglas Gregor       else
812b14904c4SDouglas Gregor         CursorKind = CXCursor_NotImplemented;
813deafd0b2SDouglas Gregor     }
814f09935f1SDouglas Gregor     break;
8157b316825SDouglas Gregor   }
8169eb7701dSDouglas Gregor 
817276321a9SJohn McCall   case RK_Macro:
818276321a9SJohn McCall   case RK_Keyword:
819c25c0b9dSBenjamin Kramer     llvm_unreachable("Macro and keyword kinds are handled by the constructors");
8208e984da8SDouglas Gregor   }
8212e657ffdSErik Verbruggen 
8222e657ffdSErik Verbruggen   if (!Accessible)
8232e657ffdSErik Verbruggen     Availability = CXAvailability_NotAccessible;
824f09935f1SDouglas Gregor }
8259eb7701dSDouglas Gregor 
8269fc8faf9SAdrian Prantl /// Retrieve the name that should be used to order a result.
8270de55cecSDouglas Gregor ///
8280de55cecSDouglas Gregor /// If the name needs to be constructed as a string, that string will be
8290de55cecSDouglas Gregor /// saved into Saved and the returned StringRef will refer to it.
getOrderedName(std::string & Saved) const8301102a861SSam McCall StringRef CodeCompletionResult::getOrderedName(std::string &Saved) const {
8311102a861SSam McCall   switch (Kind) {
8321102a861SSam McCall   case RK_Keyword:
8331102a861SSam McCall     return Keyword;
8341102a861SSam McCall   case RK_Pattern:
8351102a861SSam McCall     return Pattern->getTypedText();
8361102a861SSam McCall   case RK_Macro:
8371102a861SSam McCall     return Macro->getName();
8381102a861SSam McCall   case RK_Declaration:
8390de55cecSDouglas Gregor     // Handle declarations below.
8400de55cecSDouglas Gregor     break;
8410de55cecSDouglas Gregor   }
8420de55cecSDouglas Gregor 
8431102a861SSam McCall   DeclarationName Name = Declaration->getDeclName();
8440de55cecSDouglas Gregor 
8450de55cecSDouglas Gregor   // If the name is a simple identifier (by far the common case), or a
8460de55cecSDouglas Gregor   // zero-argument selector, just return a reference to that identifier.
8470de55cecSDouglas Gregor   if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
8480de55cecSDouglas Gregor     return Id->getName();
8490de55cecSDouglas Gregor   if (Name.isObjCZeroArgSelector())
850de314b39SFangrui Song     if (IdentifierInfo *Id = Name.getObjCSelector().getIdentifierInfoForSlot(0))
8510de55cecSDouglas Gregor       return Id->getName();
8520de55cecSDouglas Gregor 
8530de55cecSDouglas Gregor   Saved = Name.getAsString();
8540de55cecSDouglas Gregor   return Saved;
8550de55cecSDouglas Gregor }
8560de55cecSDouglas Gregor 
operator <(const CodeCompletionResult & X,const CodeCompletionResult & Y)8570de55cecSDouglas Gregor bool clang::operator<(const CodeCompletionResult &X,
8580de55cecSDouglas Gregor                       const CodeCompletionResult &Y) {
8590de55cecSDouglas Gregor   std::string XSaved, YSaved;
8601102a861SSam McCall   StringRef XStr = X.getOrderedName(XSaved);
8611102a861SSam McCall   StringRef YStr = Y.getOrderedName(YSaved);
862e5c7c171SMartin Storsjö   int cmp = XStr.compare_insensitive(YStr);
8630de55cecSDouglas Gregor   if (cmp)
8640de55cecSDouglas Gregor     return cmp < 0;
8650de55cecSDouglas Gregor 
86649f67ce4SDouglas Gregor   // If case-insensitive comparison fails, try case-sensitive comparison.
867de314b39SFangrui Song   return XStr.compare(YStr) < 0;
8680de55cecSDouglas Gregor }
869