10b57cec5SDimitry Andric //===- CodeCompleteConsumer.cpp - Code Completion Interface ---------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the CodeCompleteConsumer class.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "clang/Sema/CodeCompleteConsumer.h"
140b57cec5SDimitry Andric #include "clang-c/Index.h"
150b57cec5SDimitry Andric #include "clang/AST/Decl.h"
160b57cec5SDimitry Andric #include "clang/AST/DeclBase.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h"
180b57cec5SDimitry Andric #include "clang/AST/DeclTemplate.h"
190b57cec5SDimitry Andric #include "clang/AST/DeclarationName.h"
200b57cec5SDimitry Andric #include "clang/AST/Type.h"
210b57cec5SDimitry Andric #include "clang/Basic/IdentifierTable.h"
220b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h"
230b57cec5SDimitry Andric #include "clang/Sema/Sema.h"
240b57cec5SDimitry Andric #include "llvm/ADT/SmallString.h"
250b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
265ffd83dbSDimitry Andric #include "llvm/ADT/StringExtras.h"
270b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
280b57cec5SDimitry Andric #include "llvm/ADT/Twine.h"
290b57cec5SDimitry Andric #include "llvm/Support/Casting.h"
300b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
310b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
320b57cec5SDimitry Andric #include "llvm/Support/FormatVariadic.h"
330b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
340b57cec5SDimitry Andric #include <algorithm>
350b57cec5SDimitry Andric #include <cassert>
360b57cec5SDimitry Andric #include <cstdint>
370b57cec5SDimitry Andric #include <string>
380b57cec5SDimitry Andric
390b57cec5SDimitry Andric using namespace clang;
400b57cec5SDimitry Andric
410b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
420b57cec5SDimitry Andric // Code completion context implementation
430b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
440b57cec5SDimitry Andric
wantConstructorResults() const450b57cec5SDimitry Andric bool CodeCompletionContext::wantConstructorResults() const {
460b57cec5SDimitry Andric switch (CCKind) {
470b57cec5SDimitry Andric case CCC_Recovery:
480b57cec5SDimitry Andric case CCC_Statement:
490b57cec5SDimitry Andric case CCC_Expression:
500b57cec5SDimitry Andric case CCC_ObjCMessageReceiver:
510b57cec5SDimitry Andric case CCC_ParenthesizedExpression:
520b57cec5SDimitry Andric case CCC_Symbol:
530b57cec5SDimitry Andric case CCC_SymbolOrNewName:
545f757f3fSDimitry Andric case CCC_TopLevelOrExpression:
550b57cec5SDimitry Andric return true;
560b57cec5SDimitry Andric
570b57cec5SDimitry Andric case CCC_TopLevel:
580b57cec5SDimitry Andric case CCC_ObjCInterface:
590b57cec5SDimitry Andric case CCC_ObjCImplementation:
600b57cec5SDimitry Andric case CCC_ObjCIvarList:
610b57cec5SDimitry Andric case CCC_ClassStructUnion:
620b57cec5SDimitry Andric case CCC_DotMemberAccess:
630b57cec5SDimitry Andric case CCC_ArrowMemberAccess:
640b57cec5SDimitry Andric case CCC_ObjCPropertyAccess:
650b57cec5SDimitry Andric case CCC_EnumTag:
660b57cec5SDimitry Andric case CCC_UnionTag:
670b57cec5SDimitry Andric case CCC_ClassOrStructTag:
680b57cec5SDimitry Andric case CCC_ObjCProtocolName:
690b57cec5SDimitry Andric case CCC_Namespace:
700b57cec5SDimitry Andric case CCC_Type:
710b57cec5SDimitry Andric case CCC_NewName:
720b57cec5SDimitry Andric case CCC_MacroName:
730b57cec5SDimitry Andric case CCC_MacroNameUse:
740b57cec5SDimitry Andric case CCC_PreprocessorExpression:
750b57cec5SDimitry Andric case CCC_PreprocessorDirective:
760b57cec5SDimitry Andric case CCC_NaturalLanguage:
770b57cec5SDimitry Andric case CCC_SelectorName:
780b57cec5SDimitry Andric case CCC_TypeQualifiers:
790b57cec5SDimitry Andric case CCC_Other:
800b57cec5SDimitry Andric case CCC_OtherWithMacros:
810b57cec5SDimitry Andric case CCC_ObjCInstanceMessage:
820b57cec5SDimitry Andric case CCC_ObjCClassMessage:
830b57cec5SDimitry Andric case CCC_ObjCInterfaceName:
840b57cec5SDimitry Andric case CCC_ObjCCategoryName:
850b57cec5SDimitry Andric case CCC_IncludedFile:
86349cc55cSDimitry Andric case CCC_Attribute:
8706c3fb27SDimitry Andric case CCC_ObjCClassForwardDecl:
880b57cec5SDimitry Andric return false;
890b57cec5SDimitry Andric }
900b57cec5SDimitry Andric
910b57cec5SDimitry Andric llvm_unreachable("Invalid CodeCompletionContext::Kind!");
920b57cec5SDimitry Andric }
930b57cec5SDimitry Andric
getCompletionKindString(CodeCompletionContext::Kind Kind)940b57cec5SDimitry Andric StringRef clang::getCompletionKindString(CodeCompletionContext::Kind Kind) {
950b57cec5SDimitry Andric using CCKind = CodeCompletionContext::Kind;
960b57cec5SDimitry Andric switch (Kind) {
970b57cec5SDimitry Andric case CCKind::CCC_Other:
980b57cec5SDimitry Andric return "Other";
990b57cec5SDimitry Andric case CCKind::CCC_OtherWithMacros:
1000b57cec5SDimitry Andric return "OtherWithMacros";
1010b57cec5SDimitry Andric case CCKind::CCC_TopLevel:
1020b57cec5SDimitry Andric return "TopLevel";
1030b57cec5SDimitry Andric case CCKind::CCC_ObjCInterface:
1040b57cec5SDimitry Andric return "ObjCInterface";
1050b57cec5SDimitry Andric case CCKind::CCC_ObjCImplementation:
1060b57cec5SDimitry Andric return "ObjCImplementation";
1070b57cec5SDimitry Andric case CCKind::CCC_ObjCIvarList:
1080b57cec5SDimitry Andric return "ObjCIvarList";
1090b57cec5SDimitry Andric case CCKind::CCC_ClassStructUnion:
1100b57cec5SDimitry Andric return "ClassStructUnion";
1110b57cec5SDimitry Andric case CCKind::CCC_Statement:
1120b57cec5SDimitry Andric return "Statement";
1130b57cec5SDimitry Andric case CCKind::CCC_Expression:
1140b57cec5SDimitry Andric return "Expression";
1150b57cec5SDimitry Andric case CCKind::CCC_ObjCMessageReceiver:
1160b57cec5SDimitry Andric return "ObjCMessageReceiver";
1170b57cec5SDimitry Andric case CCKind::CCC_DotMemberAccess:
1180b57cec5SDimitry Andric return "DotMemberAccess";
1190b57cec5SDimitry Andric case CCKind::CCC_ArrowMemberAccess:
1200b57cec5SDimitry Andric return "ArrowMemberAccess";
1210b57cec5SDimitry Andric case CCKind::CCC_ObjCPropertyAccess:
1220b57cec5SDimitry Andric return "ObjCPropertyAccess";
1230b57cec5SDimitry Andric case CCKind::CCC_EnumTag:
1240b57cec5SDimitry Andric return "EnumTag";
1250b57cec5SDimitry Andric case CCKind::CCC_UnionTag:
1260b57cec5SDimitry Andric return "UnionTag";
1270b57cec5SDimitry Andric case CCKind::CCC_ClassOrStructTag:
1280b57cec5SDimitry Andric return "ClassOrStructTag";
1290b57cec5SDimitry Andric case CCKind::CCC_ObjCProtocolName:
1300b57cec5SDimitry Andric return "ObjCProtocolName";
1310b57cec5SDimitry Andric case CCKind::CCC_Namespace:
1320b57cec5SDimitry Andric return "Namespace";
1330b57cec5SDimitry Andric case CCKind::CCC_Type:
1340b57cec5SDimitry Andric return "Type";
1350b57cec5SDimitry Andric case CCKind::CCC_NewName:
1360b57cec5SDimitry Andric return "NewName";
1370b57cec5SDimitry Andric case CCKind::CCC_Symbol:
1380b57cec5SDimitry Andric return "Symbol";
1390b57cec5SDimitry Andric case CCKind::CCC_SymbolOrNewName:
1400b57cec5SDimitry Andric return "SymbolOrNewName";
1410b57cec5SDimitry Andric case CCKind::CCC_MacroName:
1420b57cec5SDimitry Andric return "MacroName";
1430b57cec5SDimitry Andric case CCKind::CCC_MacroNameUse:
1440b57cec5SDimitry Andric return "MacroNameUse";
1450b57cec5SDimitry Andric case CCKind::CCC_PreprocessorExpression:
1460b57cec5SDimitry Andric return "PreprocessorExpression";
1470b57cec5SDimitry Andric case CCKind::CCC_PreprocessorDirective:
1480b57cec5SDimitry Andric return "PreprocessorDirective";
1490b57cec5SDimitry Andric case CCKind::CCC_NaturalLanguage:
1500b57cec5SDimitry Andric return "NaturalLanguage";
1510b57cec5SDimitry Andric case CCKind::CCC_SelectorName:
1520b57cec5SDimitry Andric return "SelectorName";
1530b57cec5SDimitry Andric case CCKind::CCC_TypeQualifiers:
1540b57cec5SDimitry Andric return "TypeQualifiers";
1550b57cec5SDimitry Andric case CCKind::CCC_ParenthesizedExpression:
1560b57cec5SDimitry Andric return "ParenthesizedExpression";
1570b57cec5SDimitry Andric case CCKind::CCC_ObjCInstanceMessage:
1580b57cec5SDimitry Andric return "ObjCInstanceMessage";
1590b57cec5SDimitry Andric case CCKind::CCC_ObjCClassMessage:
1600b57cec5SDimitry Andric return "ObjCClassMessage";
1610b57cec5SDimitry Andric case CCKind::CCC_ObjCInterfaceName:
1620b57cec5SDimitry Andric return "ObjCInterfaceName";
1630b57cec5SDimitry Andric case CCKind::CCC_ObjCCategoryName:
1640b57cec5SDimitry Andric return "ObjCCategoryName";
1650b57cec5SDimitry Andric case CCKind::CCC_IncludedFile:
1660b57cec5SDimitry Andric return "IncludedFile";
167349cc55cSDimitry Andric case CCKind::CCC_Attribute:
168349cc55cSDimitry Andric return "Attribute";
1690b57cec5SDimitry Andric case CCKind::CCC_Recovery:
1700b57cec5SDimitry Andric return "Recovery";
17106c3fb27SDimitry Andric case CCKind::CCC_ObjCClassForwardDecl:
17206c3fb27SDimitry Andric return "ObjCClassForwardDecl";
1735f757f3fSDimitry Andric case CCKind::CCC_TopLevelOrExpression:
1745f757f3fSDimitry Andric return "ReplTopLevel";
1750b57cec5SDimitry Andric }
1760b57cec5SDimitry Andric llvm_unreachable("Invalid CodeCompletionContext::Kind!");
1770b57cec5SDimitry Andric }
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1800b57cec5SDimitry Andric // Code completion string implementation
1810b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1820b57cec5SDimitry Andric
Chunk(ChunkKind Kind,const char * Text)1830b57cec5SDimitry Andric CodeCompletionString::Chunk::Chunk(ChunkKind Kind, const char *Text)
1840b57cec5SDimitry Andric : Kind(Kind), Text("") {
1850b57cec5SDimitry Andric switch (Kind) {
1860b57cec5SDimitry Andric case CK_TypedText:
1870b57cec5SDimitry Andric case CK_Text:
1880b57cec5SDimitry Andric case CK_Placeholder:
1890b57cec5SDimitry Andric case CK_Informative:
1900b57cec5SDimitry Andric case CK_ResultType:
1910b57cec5SDimitry Andric case CK_CurrentParameter:
1920b57cec5SDimitry Andric this->Text = Text;
1930b57cec5SDimitry Andric break;
1940b57cec5SDimitry Andric
1950b57cec5SDimitry Andric case CK_Optional:
1960b57cec5SDimitry Andric llvm_unreachable("Optional strings cannot be created from text");
1970b57cec5SDimitry Andric
1980b57cec5SDimitry Andric case CK_LeftParen:
1990b57cec5SDimitry Andric this->Text = "(";
2000b57cec5SDimitry Andric break;
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric case CK_RightParen:
2030b57cec5SDimitry Andric this->Text = ")";
2040b57cec5SDimitry Andric break;
2050b57cec5SDimitry Andric
2060b57cec5SDimitry Andric case CK_LeftBracket:
2070b57cec5SDimitry Andric this->Text = "[";
2080b57cec5SDimitry Andric break;
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric case CK_RightBracket:
2110b57cec5SDimitry Andric this->Text = "]";
2120b57cec5SDimitry Andric break;
2130b57cec5SDimitry Andric
2140b57cec5SDimitry Andric case CK_LeftBrace:
2150b57cec5SDimitry Andric this->Text = "{";
2160b57cec5SDimitry Andric break;
2170b57cec5SDimitry Andric
2180b57cec5SDimitry Andric case CK_RightBrace:
2190b57cec5SDimitry Andric this->Text = "}";
2200b57cec5SDimitry Andric break;
2210b57cec5SDimitry Andric
2220b57cec5SDimitry Andric case CK_LeftAngle:
2230b57cec5SDimitry Andric this->Text = "<";
2240b57cec5SDimitry Andric break;
2250b57cec5SDimitry Andric
2260b57cec5SDimitry Andric case CK_RightAngle:
2270b57cec5SDimitry Andric this->Text = ">";
2280b57cec5SDimitry Andric break;
2290b57cec5SDimitry Andric
2300b57cec5SDimitry Andric case CK_Comma:
2310b57cec5SDimitry Andric this->Text = ", ";
2320b57cec5SDimitry Andric break;
2330b57cec5SDimitry Andric
2340b57cec5SDimitry Andric case CK_Colon:
2350b57cec5SDimitry Andric this->Text = ":";
2360b57cec5SDimitry Andric break;
2370b57cec5SDimitry Andric
2380b57cec5SDimitry Andric case CK_SemiColon:
2390b57cec5SDimitry Andric this->Text = ";";
2400b57cec5SDimitry Andric break;
2410b57cec5SDimitry Andric
2420b57cec5SDimitry Andric case CK_Equal:
2430b57cec5SDimitry Andric this->Text = " = ";
2440b57cec5SDimitry Andric break;
2450b57cec5SDimitry Andric
2460b57cec5SDimitry Andric case CK_HorizontalSpace:
2470b57cec5SDimitry Andric this->Text = " ";
2480b57cec5SDimitry Andric break;
2490b57cec5SDimitry Andric
2500b57cec5SDimitry Andric case CK_VerticalSpace:
2510b57cec5SDimitry Andric this->Text = "\n";
2520b57cec5SDimitry Andric break;
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric }
2550b57cec5SDimitry Andric
2560b57cec5SDimitry Andric CodeCompletionString::Chunk
CreateText(const char * Text)2570b57cec5SDimitry Andric CodeCompletionString::Chunk::CreateText(const char *Text) {
2580b57cec5SDimitry Andric return Chunk(CK_Text, Text);
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric
2610b57cec5SDimitry Andric CodeCompletionString::Chunk
CreateOptional(CodeCompletionString * Optional)2620b57cec5SDimitry Andric CodeCompletionString::Chunk::CreateOptional(CodeCompletionString *Optional) {
2630b57cec5SDimitry Andric Chunk Result;
2640b57cec5SDimitry Andric Result.Kind = CK_Optional;
2650b57cec5SDimitry Andric Result.Optional = Optional;
2660b57cec5SDimitry Andric return Result;
2670b57cec5SDimitry Andric }
2680b57cec5SDimitry Andric
2690b57cec5SDimitry Andric CodeCompletionString::Chunk
CreatePlaceholder(const char * Placeholder)2700b57cec5SDimitry Andric CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) {
2710b57cec5SDimitry Andric return Chunk(CK_Placeholder, Placeholder);
2720b57cec5SDimitry Andric }
2730b57cec5SDimitry Andric
2740b57cec5SDimitry Andric CodeCompletionString::Chunk
CreateInformative(const char * Informative)2750b57cec5SDimitry Andric CodeCompletionString::Chunk::CreateInformative(const char *Informative) {
2760b57cec5SDimitry Andric return Chunk(CK_Informative, Informative);
2770b57cec5SDimitry Andric }
2780b57cec5SDimitry Andric
2790b57cec5SDimitry Andric CodeCompletionString::Chunk
CreateResultType(const char * ResultType)2800b57cec5SDimitry Andric CodeCompletionString::Chunk::CreateResultType(const char *ResultType) {
2810b57cec5SDimitry Andric return Chunk(CK_ResultType, ResultType);
2820b57cec5SDimitry Andric }
2830b57cec5SDimitry Andric
CreateCurrentParameter(const char * CurrentParameter)2840b57cec5SDimitry Andric CodeCompletionString::Chunk CodeCompletionString::Chunk::CreateCurrentParameter(
2850b57cec5SDimitry Andric const char *CurrentParameter) {
2860b57cec5SDimitry Andric return Chunk(CK_CurrentParameter, CurrentParameter);
2870b57cec5SDimitry Andric }
2880b57cec5SDimitry Andric
CodeCompletionString(const Chunk * Chunks,unsigned NumChunks,unsigned Priority,CXAvailabilityKind Availability,const char ** Annotations,unsigned NumAnnotations,StringRef ParentName,const char * BriefComment)2890b57cec5SDimitry Andric CodeCompletionString::CodeCompletionString(
2900b57cec5SDimitry Andric const Chunk *Chunks, unsigned NumChunks, unsigned Priority,
2910b57cec5SDimitry Andric CXAvailabilityKind Availability, const char **Annotations,
2920b57cec5SDimitry Andric unsigned NumAnnotations, StringRef ParentName, const char *BriefComment)
2930b57cec5SDimitry Andric : NumChunks(NumChunks), NumAnnotations(NumAnnotations), Priority(Priority),
2940b57cec5SDimitry Andric Availability(Availability), ParentName(ParentName),
2950b57cec5SDimitry Andric BriefComment(BriefComment) {
2960b57cec5SDimitry Andric assert(NumChunks <= 0xffff);
2970b57cec5SDimitry Andric assert(NumAnnotations <= 0xffff);
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric Chunk *StoredChunks = reinterpret_cast<Chunk *>(this + 1);
3000b57cec5SDimitry Andric for (unsigned I = 0; I != NumChunks; ++I)
3010b57cec5SDimitry Andric StoredChunks[I] = Chunks[I];
3020b57cec5SDimitry Andric
3030b57cec5SDimitry Andric const char **StoredAnnotations =
3040b57cec5SDimitry Andric reinterpret_cast<const char **>(StoredChunks + NumChunks);
3050b57cec5SDimitry Andric for (unsigned I = 0; I != NumAnnotations; ++I)
3060b57cec5SDimitry Andric StoredAnnotations[I] = Annotations[I];
3070b57cec5SDimitry Andric }
3080b57cec5SDimitry Andric
getAnnotationCount() const3090b57cec5SDimitry Andric unsigned CodeCompletionString::getAnnotationCount() const {
3100b57cec5SDimitry Andric return NumAnnotations;
3110b57cec5SDimitry Andric }
3120b57cec5SDimitry Andric
getAnnotation(unsigned AnnotationNr) const3130b57cec5SDimitry Andric const char *CodeCompletionString::getAnnotation(unsigned AnnotationNr) const {
3140b57cec5SDimitry Andric if (AnnotationNr < NumAnnotations)
3150b57cec5SDimitry Andric return reinterpret_cast<const char *const *>(end())[AnnotationNr];
3160b57cec5SDimitry Andric else
3170b57cec5SDimitry Andric return nullptr;
3180b57cec5SDimitry Andric }
3190b57cec5SDimitry Andric
getAsString() const3200b57cec5SDimitry Andric std::string CodeCompletionString::getAsString() const {
3210b57cec5SDimitry Andric std::string Result;
3220b57cec5SDimitry Andric llvm::raw_string_ostream OS(Result);
3230b57cec5SDimitry Andric
3240b57cec5SDimitry Andric for (const Chunk &C : *this) {
3250b57cec5SDimitry Andric switch (C.Kind) {
3260b57cec5SDimitry Andric case CK_Optional:
3270b57cec5SDimitry Andric OS << "{#" << C.Optional->getAsString() << "#}";
3280b57cec5SDimitry Andric break;
3290b57cec5SDimitry Andric case CK_Placeholder:
3300b57cec5SDimitry Andric OS << "<#" << C.Text << "#>";
3310b57cec5SDimitry Andric break;
3320b57cec5SDimitry Andric case CK_Informative:
3330b57cec5SDimitry Andric case CK_ResultType:
3340b57cec5SDimitry Andric OS << "[#" << C.Text << "#]";
3350b57cec5SDimitry Andric break;
3360b57cec5SDimitry Andric case CK_CurrentParameter:
3370b57cec5SDimitry Andric OS << "<#" << C.Text << "#>";
3380b57cec5SDimitry Andric break;
3390b57cec5SDimitry Andric default:
3400b57cec5SDimitry Andric OS << C.Text;
3410b57cec5SDimitry Andric break;
3420b57cec5SDimitry Andric }
3430b57cec5SDimitry Andric }
3440eae32dcSDimitry Andric return Result;
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric
getTypedText() const3470b57cec5SDimitry Andric const char *CodeCompletionString::getTypedText() const {
3480b57cec5SDimitry Andric for (const Chunk &C : *this)
3490b57cec5SDimitry Andric if (C.Kind == CK_TypedText)
3500b57cec5SDimitry Andric return C.Text;
3510b57cec5SDimitry Andric
3520b57cec5SDimitry Andric return nullptr;
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric
getAllTypedText() const35581ad6265SDimitry Andric std::string CodeCompletionString::getAllTypedText() const {
35681ad6265SDimitry Andric std::string Res;
35781ad6265SDimitry Andric for (const Chunk &C : *this)
35881ad6265SDimitry Andric if (C.Kind == CK_TypedText)
35981ad6265SDimitry Andric Res += C.Text;
36081ad6265SDimitry Andric
36181ad6265SDimitry Andric return Res;
36281ad6265SDimitry Andric }
36381ad6265SDimitry Andric
CopyString(const Twine & String)3640b57cec5SDimitry Andric const char *CodeCompletionAllocator::CopyString(const Twine &String) {
3650b57cec5SDimitry Andric SmallString<128> Data;
3660b57cec5SDimitry Andric StringRef Ref = String.toStringRef(Data);
3670b57cec5SDimitry Andric // FIXME: It would be more efficient to teach Twine to tell us its size and
3680b57cec5SDimitry Andric // then add a routine there to fill in an allocated char* with the contents
3690b57cec5SDimitry Andric // of the string.
3700b57cec5SDimitry Andric char *Mem = (char *)Allocate(Ref.size() + 1, 1);
3710b57cec5SDimitry Andric std::copy(Ref.begin(), Ref.end(), Mem);
3720b57cec5SDimitry Andric Mem[Ref.size()] = 0;
3730b57cec5SDimitry Andric return Mem;
3740b57cec5SDimitry Andric }
3750b57cec5SDimitry Andric
getParentName(const DeclContext * DC)3760b57cec5SDimitry Andric StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) {
377e8d8bef9SDimitry Andric if (!isa<NamedDecl>(DC))
3780b57cec5SDimitry Andric return {};
3790b57cec5SDimitry Andric
3800b57cec5SDimitry Andric // Check whether we've already cached the parent name.
3810b57cec5SDimitry Andric StringRef &CachedParentName = ParentNames[DC];
3820b57cec5SDimitry Andric if (!CachedParentName.empty())
3830b57cec5SDimitry Andric return CachedParentName;
3840b57cec5SDimitry Andric
3850b57cec5SDimitry Andric // If we already processed this DeclContext and assigned empty to it, the
3860b57cec5SDimitry Andric // data pointer will be non-null.
3870b57cec5SDimitry Andric if (CachedParentName.data() != nullptr)
3880b57cec5SDimitry Andric return {};
3890b57cec5SDimitry Andric
3900b57cec5SDimitry Andric // Find the interesting names.
3910b57cec5SDimitry Andric SmallVector<const DeclContext *, 2> Contexts;
3920b57cec5SDimitry Andric while (DC && !DC->isFunctionOrMethod()) {
3930b57cec5SDimitry Andric if (const auto *ND = dyn_cast<NamedDecl>(DC)) {
3940b57cec5SDimitry Andric if (ND->getIdentifier())
3950b57cec5SDimitry Andric Contexts.push_back(DC);
3960b57cec5SDimitry Andric }
3970b57cec5SDimitry Andric
3980b57cec5SDimitry Andric DC = DC->getParent();
3990b57cec5SDimitry Andric }
4000b57cec5SDimitry Andric
4010b57cec5SDimitry Andric {
4020b57cec5SDimitry Andric SmallString<128> S;
4030b57cec5SDimitry Andric llvm::raw_svector_ostream OS(S);
4040b57cec5SDimitry Andric bool First = true;
405349cc55cSDimitry Andric for (const DeclContext *CurDC : llvm::reverse(Contexts)) {
4060b57cec5SDimitry Andric if (First)
4070b57cec5SDimitry Andric First = false;
4080b57cec5SDimitry Andric else {
4090b57cec5SDimitry Andric OS << "::";
4100b57cec5SDimitry Andric }
4110b57cec5SDimitry Andric
4120b57cec5SDimitry Andric if (const auto *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
4130b57cec5SDimitry Andric CurDC = CatImpl->getCategoryDecl();
4140b57cec5SDimitry Andric
4150b57cec5SDimitry Andric if (const auto *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
4160b57cec5SDimitry Andric const ObjCInterfaceDecl *Interface = Cat->getClassInterface();
4170b57cec5SDimitry Andric if (!Interface) {
4180b57cec5SDimitry Andric // Assign an empty StringRef but with non-null data to distinguish
4190b57cec5SDimitry Andric // between empty because we didn't process the DeclContext yet.
4200b57cec5SDimitry Andric CachedParentName = StringRef((const char *)(uintptr_t)~0U, 0);
4210b57cec5SDimitry Andric return {};
4220b57cec5SDimitry Andric }
4230b57cec5SDimitry Andric
4240b57cec5SDimitry Andric OS << Interface->getName() << '(' << Cat->getName() << ')';
4250b57cec5SDimitry Andric } else {
4260b57cec5SDimitry Andric OS << cast<NamedDecl>(CurDC)->getName();
4270b57cec5SDimitry Andric }
4280b57cec5SDimitry Andric }
4290b57cec5SDimitry Andric
4300b57cec5SDimitry Andric CachedParentName = AllocatorRef->CopyString(OS.str());
4310b57cec5SDimitry Andric }
4320b57cec5SDimitry Andric
4330b57cec5SDimitry Andric return CachedParentName;
4340b57cec5SDimitry Andric }
4350b57cec5SDimitry Andric
TakeString()4360b57cec5SDimitry Andric CodeCompletionString *CodeCompletionBuilder::TakeString() {
4370b57cec5SDimitry Andric void *Mem = getAllocator().Allocate(
4380b57cec5SDimitry Andric sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size() +
4390b57cec5SDimitry Andric sizeof(const char *) * Annotations.size(),
4400b57cec5SDimitry Andric alignof(CodeCompletionString));
4410b57cec5SDimitry Andric CodeCompletionString *Result = new (Mem) CodeCompletionString(
4420b57cec5SDimitry Andric Chunks.data(), Chunks.size(), Priority, Availability, Annotations.data(),
4430b57cec5SDimitry Andric Annotations.size(), ParentName, BriefComment);
4440b57cec5SDimitry Andric Chunks.clear();
4450b57cec5SDimitry Andric return Result;
4460b57cec5SDimitry Andric }
4470b57cec5SDimitry Andric
AddTypedTextChunk(const char * Text)4480b57cec5SDimitry Andric void CodeCompletionBuilder::AddTypedTextChunk(const char *Text) {
4490b57cec5SDimitry Andric Chunks.push_back(Chunk(CodeCompletionString::CK_TypedText, Text));
4500b57cec5SDimitry Andric }
4510b57cec5SDimitry Andric
AddTextChunk(const char * Text)4520b57cec5SDimitry Andric void CodeCompletionBuilder::AddTextChunk(const char *Text) {
4530b57cec5SDimitry Andric Chunks.push_back(Chunk::CreateText(Text));
4540b57cec5SDimitry Andric }
4550b57cec5SDimitry Andric
AddOptionalChunk(CodeCompletionString * Optional)4560b57cec5SDimitry Andric void CodeCompletionBuilder::AddOptionalChunk(CodeCompletionString *Optional) {
4570b57cec5SDimitry Andric Chunks.push_back(Chunk::CreateOptional(Optional));
4580b57cec5SDimitry Andric }
4590b57cec5SDimitry Andric
AddPlaceholderChunk(const char * Placeholder)4600b57cec5SDimitry Andric void CodeCompletionBuilder::AddPlaceholderChunk(const char *Placeholder) {
4610b57cec5SDimitry Andric Chunks.push_back(Chunk::CreatePlaceholder(Placeholder));
4620b57cec5SDimitry Andric }
4630b57cec5SDimitry Andric
AddInformativeChunk(const char * Text)4640b57cec5SDimitry Andric void CodeCompletionBuilder::AddInformativeChunk(const char *Text) {
4650b57cec5SDimitry Andric Chunks.push_back(Chunk::CreateInformative(Text));
4660b57cec5SDimitry Andric }
4670b57cec5SDimitry Andric
AddResultTypeChunk(const char * ResultType)4680b57cec5SDimitry Andric void CodeCompletionBuilder::AddResultTypeChunk(const char *ResultType) {
4690b57cec5SDimitry Andric Chunks.push_back(Chunk::CreateResultType(ResultType));
4700b57cec5SDimitry Andric }
4710b57cec5SDimitry Andric
AddCurrentParameterChunk(const char * CurrentParameter)4720b57cec5SDimitry Andric void CodeCompletionBuilder::AddCurrentParameterChunk(
4730b57cec5SDimitry Andric const char *CurrentParameter) {
4740b57cec5SDimitry Andric Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter));
4750b57cec5SDimitry Andric }
4760b57cec5SDimitry Andric
AddChunk(CodeCompletionString::ChunkKind CK,const char * Text)4770b57cec5SDimitry Andric void CodeCompletionBuilder::AddChunk(CodeCompletionString::ChunkKind CK,
4780b57cec5SDimitry Andric const char *Text) {
4790b57cec5SDimitry Andric Chunks.push_back(Chunk(CK, Text));
4800b57cec5SDimitry Andric }
4810b57cec5SDimitry Andric
addParentContext(const DeclContext * DC)4820b57cec5SDimitry Andric void CodeCompletionBuilder::addParentContext(const DeclContext *DC) {
4830b57cec5SDimitry Andric if (DC->isTranslationUnit())
4840b57cec5SDimitry Andric return;
4850b57cec5SDimitry Andric
4860b57cec5SDimitry Andric if (DC->isFunctionOrMethod())
4870b57cec5SDimitry Andric return;
4880b57cec5SDimitry Andric
489e8d8bef9SDimitry Andric if (!isa<NamedDecl>(DC))
4900b57cec5SDimitry Andric return;
4910b57cec5SDimitry Andric
4920b57cec5SDimitry Andric ParentName = getCodeCompletionTUInfo().getParentName(DC);
4930b57cec5SDimitry Andric }
4940b57cec5SDimitry Andric
addBriefComment(StringRef Comment)4950b57cec5SDimitry Andric void CodeCompletionBuilder::addBriefComment(StringRef Comment) {
4960b57cec5SDimitry Andric BriefComment = Allocator.CopyString(Comment);
4970b57cec5SDimitry Andric }
4980b57cec5SDimitry Andric
4990b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
5000b57cec5SDimitry Andric // Code completion overload candidate implementation
5010b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
getFunction() const5020b57cec5SDimitry Andric FunctionDecl *CodeCompleteConsumer::OverloadCandidate::getFunction() const {
5030b57cec5SDimitry Andric if (getKind() == CK_Function)
5040b57cec5SDimitry Andric return Function;
5050b57cec5SDimitry Andric else if (getKind() == CK_FunctionTemplate)
5060b57cec5SDimitry Andric return FunctionTemplate->getTemplatedDecl();
5070b57cec5SDimitry Andric else
5080b57cec5SDimitry Andric return nullptr;
5090b57cec5SDimitry Andric }
5100b57cec5SDimitry Andric
5110b57cec5SDimitry Andric const FunctionType *
getFunctionType() const5120b57cec5SDimitry Andric CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
5130b57cec5SDimitry Andric switch (Kind) {
5140b57cec5SDimitry Andric case CK_Function:
5150b57cec5SDimitry Andric return Function->getType()->getAs<FunctionType>();
5160b57cec5SDimitry Andric
5170b57cec5SDimitry Andric case CK_FunctionTemplate:
5180b57cec5SDimitry Andric return FunctionTemplate->getTemplatedDecl()
5190b57cec5SDimitry Andric ->getType()
5200b57cec5SDimitry Andric ->getAs<FunctionType>();
5210b57cec5SDimitry Andric
5220b57cec5SDimitry Andric case CK_FunctionType:
5230b57cec5SDimitry Andric return Type;
524fcaf7f86SDimitry Andric case CK_FunctionProtoTypeLoc:
525fcaf7f86SDimitry Andric return ProtoTypeLoc.getTypePtr();
52604eeddc0SDimitry Andric case CK_Template:
52704eeddc0SDimitry Andric case CK_Aggregate:
52804eeddc0SDimitry Andric return nullptr;
5290b57cec5SDimitry Andric }
5300b57cec5SDimitry Andric
5310b57cec5SDimitry Andric llvm_unreachable("Invalid CandidateKind!");
5320b57cec5SDimitry Andric }
5330b57cec5SDimitry Andric
534fcaf7f86SDimitry Andric const FunctionProtoTypeLoc
getFunctionProtoTypeLoc() const535fcaf7f86SDimitry Andric CodeCompleteConsumer::OverloadCandidate::getFunctionProtoTypeLoc() const {
536fcaf7f86SDimitry Andric if (Kind == CK_FunctionProtoTypeLoc)
537fcaf7f86SDimitry Andric return ProtoTypeLoc;
538fcaf7f86SDimitry Andric return FunctionProtoTypeLoc();
539fcaf7f86SDimitry Andric }
540fcaf7f86SDimitry Andric
getNumParams() const54104eeddc0SDimitry Andric unsigned CodeCompleteConsumer::OverloadCandidate::getNumParams() const {
54204eeddc0SDimitry Andric if (Kind == CK_Template)
54304eeddc0SDimitry Andric return Template->getTemplateParameters()->size();
54404eeddc0SDimitry Andric
54504eeddc0SDimitry Andric if (Kind == CK_Aggregate) {
54604eeddc0SDimitry Andric unsigned Count =
54704eeddc0SDimitry Andric std::distance(AggregateType->field_begin(), AggregateType->field_end());
54804eeddc0SDimitry Andric if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType))
54904eeddc0SDimitry Andric Count += CRD->getNumBases();
55004eeddc0SDimitry Andric return Count;
55104eeddc0SDimitry Andric }
55204eeddc0SDimitry Andric
55304eeddc0SDimitry Andric if (const auto *FT = getFunctionType())
55404eeddc0SDimitry Andric if (const auto *FPT = dyn_cast<FunctionProtoType>(FT))
55504eeddc0SDimitry Andric return FPT->getNumParams();
55604eeddc0SDimitry Andric
55704eeddc0SDimitry Andric return 0;
55804eeddc0SDimitry Andric }
55904eeddc0SDimitry Andric
56004eeddc0SDimitry Andric QualType
getParamType(unsigned N) const56104eeddc0SDimitry Andric CodeCompleteConsumer::OverloadCandidate::getParamType(unsigned N) const {
56204eeddc0SDimitry Andric if (Kind == CK_Aggregate) {
56304eeddc0SDimitry Andric if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) {
56404eeddc0SDimitry Andric if (N < CRD->getNumBases())
56504eeddc0SDimitry Andric return std::next(CRD->bases_begin(), N)->getType();
56604eeddc0SDimitry Andric N -= CRD->getNumBases();
56704eeddc0SDimitry Andric }
56804eeddc0SDimitry Andric for (const auto *Field : AggregateType->fields())
56904eeddc0SDimitry Andric if (N-- == 0)
57004eeddc0SDimitry Andric return Field->getType();
57104eeddc0SDimitry Andric return QualType();
57204eeddc0SDimitry Andric }
57304eeddc0SDimitry Andric
57404eeddc0SDimitry Andric if (Kind == CK_Template) {
57504eeddc0SDimitry Andric TemplateParameterList *TPL = getTemplate()->getTemplateParameters();
57604eeddc0SDimitry Andric if (N < TPL->size())
57704eeddc0SDimitry Andric if (const auto *D = dyn_cast<NonTypeTemplateParmDecl>(TPL->getParam(N)))
57804eeddc0SDimitry Andric return D->getType();
57904eeddc0SDimitry Andric return QualType();
58004eeddc0SDimitry Andric }
58104eeddc0SDimitry Andric
58204eeddc0SDimitry Andric if (const auto *FT = getFunctionType())
58304eeddc0SDimitry Andric if (const auto *FPT = dyn_cast<FunctionProtoType>(FT))
58404eeddc0SDimitry Andric if (N < FPT->getNumParams())
58504eeddc0SDimitry Andric return FPT->getParamType(N);
58604eeddc0SDimitry Andric return QualType();
58704eeddc0SDimitry Andric }
58804eeddc0SDimitry Andric
58904eeddc0SDimitry Andric const NamedDecl *
getParamDecl(unsigned N) const59004eeddc0SDimitry Andric CodeCompleteConsumer::OverloadCandidate::getParamDecl(unsigned N) const {
59104eeddc0SDimitry Andric if (Kind == CK_Aggregate) {
59204eeddc0SDimitry Andric if (const auto *CRD = dyn_cast<CXXRecordDecl>(AggregateType)) {
59304eeddc0SDimitry Andric if (N < CRD->getNumBases())
59404eeddc0SDimitry Andric return std::next(CRD->bases_begin(), N)->getType()->getAsTagDecl();
59504eeddc0SDimitry Andric N -= CRD->getNumBases();
59604eeddc0SDimitry Andric }
59704eeddc0SDimitry Andric for (const auto *Field : AggregateType->fields())
59804eeddc0SDimitry Andric if (N-- == 0)
59904eeddc0SDimitry Andric return Field;
60004eeddc0SDimitry Andric return nullptr;
60104eeddc0SDimitry Andric }
60204eeddc0SDimitry Andric
60304eeddc0SDimitry Andric if (Kind == CK_Template) {
60404eeddc0SDimitry Andric TemplateParameterList *TPL = getTemplate()->getTemplateParameters();
60504eeddc0SDimitry Andric if (N < TPL->size())
60604eeddc0SDimitry Andric return TPL->getParam(N);
60704eeddc0SDimitry Andric return nullptr;
60804eeddc0SDimitry Andric }
60904eeddc0SDimitry Andric
61004eeddc0SDimitry Andric // Note that if we only have a FunctionProtoType, we don't have param decls.
61104eeddc0SDimitry Andric if (const auto *FD = getFunction()) {
61204eeddc0SDimitry Andric if (N < FD->param_size())
61304eeddc0SDimitry Andric return FD->getParamDecl(N);
614fcaf7f86SDimitry Andric } else if (Kind == CK_FunctionProtoTypeLoc) {
615fcaf7f86SDimitry Andric if (N < ProtoTypeLoc.getNumParams()) {
616fcaf7f86SDimitry Andric return ProtoTypeLoc.getParam(N);
61704eeddc0SDimitry Andric }
618fcaf7f86SDimitry Andric }
619fcaf7f86SDimitry Andric
62004eeddc0SDimitry Andric return nullptr;
62104eeddc0SDimitry Andric }
62204eeddc0SDimitry Andric
6230b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6240b57cec5SDimitry Andric // Code completion consumer implementation
6250b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
6260b57cec5SDimitry Andric
6270b57cec5SDimitry Andric CodeCompleteConsumer::~CodeCompleteConsumer() = default;
6280b57cec5SDimitry Andric
isResultFilteredOut(StringRef Filter,CodeCompletionResult Result)6290b57cec5SDimitry Andric bool PrintingCodeCompleteConsumer::isResultFilteredOut(
6300b57cec5SDimitry Andric StringRef Filter, CodeCompletionResult Result) {
6310b57cec5SDimitry Andric switch (Result.Kind) {
6320b57cec5SDimitry Andric case CodeCompletionResult::RK_Declaration:
6335f757f3fSDimitry Andric return !(
6345f757f3fSDimitry Andric Result.Declaration->getIdentifier() &&
6355f757f3fSDimitry Andric Result.Declaration->getIdentifier()->getName().starts_with(Filter));
6360b57cec5SDimitry Andric case CodeCompletionResult::RK_Keyword:
6375f757f3fSDimitry Andric return !StringRef(Result.Keyword).starts_with(Filter);
6380b57cec5SDimitry Andric case CodeCompletionResult::RK_Macro:
6395f757f3fSDimitry Andric return !Result.Macro->getName().starts_with(Filter);
6400b57cec5SDimitry Andric case CodeCompletionResult::RK_Pattern:
6410b57cec5SDimitry Andric return !(Result.Pattern->getTypedText() &&
6425f757f3fSDimitry Andric StringRef(Result.Pattern->getTypedText()).starts_with(Filter));
6430b57cec5SDimitry Andric }
6440b57cec5SDimitry Andric llvm_unreachable("Unknown code completion result Kind.");
6450b57cec5SDimitry Andric }
6460b57cec5SDimitry Andric
ProcessCodeCompleteResults(Sema & SemaRef,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)6470b57cec5SDimitry Andric void PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(
6480b57cec5SDimitry Andric Sema &SemaRef, CodeCompletionContext Context, CodeCompletionResult *Results,
6490b57cec5SDimitry Andric unsigned NumResults) {
6500b57cec5SDimitry Andric std::stable_sort(Results, Results + NumResults);
6510b57cec5SDimitry Andric
6520b57cec5SDimitry Andric if (!Context.getPreferredType().isNull())
65381ad6265SDimitry Andric OS << "PREFERRED-TYPE: " << Context.getPreferredType() << '\n';
6540b57cec5SDimitry Andric
6550b57cec5SDimitry Andric StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter();
6560b57cec5SDimitry Andric // Print the completions.
6570b57cec5SDimitry Andric for (unsigned I = 0; I != NumResults; ++I) {
6580b57cec5SDimitry Andric if (!Filter.empty() && isResultFilteredOut(Filter, Results[I]))
6590b57cec5SDimitry Andric continue;
6600b57cec5SDimitry Andric OS << "COMPLETION: ";
6610b57cec5SDimitry Andric switch (Results[I].Kind) {
6620b57cec5SDimitry Andric case CodeCompletionResult::RK_Declaration:
6630b57cec5SDimitry Andric OS << *Results[I].Declaration;
6640b57cec5SDimitry Andric {
6650b57cec5SDimitry Andric std::vector<std::string> Tags;
6660b57cec5SDimitry Andric if (Results[I].Hidden)
6670b57cec5SDimitry Andric Tags.push_back("Hidden");
6680b57cec5SDimitry Andric if (Results[I].InBaseClass)
6690b57cec5SDimitry Andric Tags.push_back("InBase");
6700b57cec5SDimitry Andric if (Results[I].Availability ==
6710b57cec5SDimitry Andric CXAvailabilityKind::CXAvailability_NotAccessible)
6720b57cec5SDimitry Andric Tags.push_back("Inaccessible");
6730b57cec5SDimitry Andric if (!Tags.empty())
6740b57cec5SDimitry Andric OS << " (" << llvm::join(Tags, ",") << ")";
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(
6770b57cec5SDimitry Andric SemaRef, Context, getAllocator(), CCTUInfo,
6780b57cec5SDimitry Andric includeBriefComments())) {
6790b57cec5SDimitry Andric OS << " : " << CCS->getAsString();
6800b57cec5SDimitry Andric if (const char *BriefComment = CCS->getBriefComment())
6810b57cec5SDimitry Andric OS << " : " << BriefComment;
6820b57cec5SDimitry Andric }
6835ffd83dbSDimitry Andric break;
6845ffd83dbSDimitry Andric
6855ffd83dbSDimitry Andric case CodeCompletionResult::RK_Keyword:
6865ffd83dbSDimitry Andric OS << Results[I].Keyword;
6875ffd83dbSDimitry Andric break;
6885ffd83dbSDimitry Andric
6895ffd83dbSDimitry Andric case CodeCompletionResult::RK_Macro:
6905ffd83dbSDimitry Andric OS << Results[I].Macro->getName();
6915ffd83dbSDimitry Andric if (CodeCompletionString *CCS = Results[I].CreateCodeCompletionString(
6925ffd83dbSDimitry Andric SemaRef, Context, getAllocator(), CCTUInfo,
6935ffd83dbSDimitry Andric includeBriefComments())) {
6945ffd83dbSDimitry Andric OS << " : " << CCS->getAsString();
6955ffd83dbSDimitry Andric }
6965ffd83dbSDimitry Andric break;
6975ffd83dbSDimitry Andric
6985ffd83dbSDimitry Andric case CodeCompletionResult::RK_Pattern:
6995ffd83dbSDimitry Andric OS << "Pattern : " << Results[I].Pattern->getAsString();
7005ffd83dbSDimitry Andric break;
7015ffd83dbSDimitry Andric }
7020b57cec5SDimitry Andric for (const FixItHint &FixIt : Results[I].FixIts) {
7030b57cec5SDimitry Andric const SourceLocation BLoc = FixIt.RemoveRange.getBegin();
7040b57cec5SDimitry Andric const SourceLocation ELoc = FixIt.RemoveRange.getEnd();
7050b57cec5SDimitry Andric
7060b57cec5SDimitry Andric SourceManager &SM = SemaRef.SourceMgr;
7070b57cec5SDimitry Andric std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc);
7080b57cec5SDimitry Andric std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(ELoc);
7090b57cec5SDimitry Andric // Adjust for token ranges.
7100b57cec5SDimitry Andric if (FixIt.RemoveRange.isTokenRange())
7110b57cec5SDimitry Andric EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, SemaRef.LangOpts);
7120b57cec5SDimitry Andric
7130b57cec5SDimitry Andric OS << " (requires fix-it:"
7140b57cec5SDimitry Andric << " {" << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
7150b57cec5SDimitry Andric << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
7160b57cec5SDimitry Andric << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
7170b57cec5SDimitry Andric << SM.getColumnNumber(EInfo.first, EInfo.second) << "}"
7180b57cec5SDimitry Andric << " to \"" << FixIt.CodeToInsert << "\")";
7190b57cec5SDimitry Andric }
7200b57cec5SDimitry Andric OS << '\n';
7210b57cec5SDimitry Andric }
7220b57cec5SDimitry Andric }
7230b57cec5SDimitry Andric
7240b57cec5SDimitry Andric // This function is used solely to preserve the former presentation of overloads
7250b57cec5SDimitry Andric // by "clang -cc1 -code-completion-at", since CodeCompletionString::getAsString
7260b57cec5SDimitry Andric // needs to be improved for printing the newer and more detailed overload
7270b57cec5SDimitry Andric // chunks.
getOverloadAsString(const CodeCompletionString & CCS)7280b57cec5SDimitry Andric static std::string getOverloadAsString(const CodeCompletionString &CCS) {
7290b57cec5SDimitry Andric std::string Result;
7300b57cec5SDimitry Andric llvm::raw_string_ostream OS(Result);
7310b57cec5SDimitry Andric
7320b57cec5SDimitry Andric for (auto &C : CCS) {
7330b57cec5SDimitry Andric switch (C.Kind) {
7340b57cec5SDimitry Andric case CodeCompletionString::CK_Informative:
7350b57cec5SDimitry Andric case CodeCompletionString::CK_ResultType:
7360b57cec5SDimitry Andric OS << "[#" << C.Text << "#]";
7370b57cec5SDimitry Andric break;
7380b57cec5SDimitry Andric
7390b57cec5SDimitry Andric case CodeCompletionString::CK_CurrentParameter:
7400b57cec5SDimitry Andric OS << "<#" << C.Text << "#>";
7410b57cec5SDimitry Andric break;
7420b57cec5SDimitry Andric
7430b57cec5SDimitry Andric // FIXME: We can also print optional parameters of an overload.
7440b57cec5SDimitry Andric case CodeCompletionString::CK_Optional:
7450b57cec5SDimitry Andric break;
7460b57cec5SDimitry Andric
7470b57cec5SDimitry Andric default:
7480b57cec5SDimitry Andric OS << C.Text;
7490b57cec5SDimitry Andric break;
7500b57cec5SDimitry Andric }
7510b57cec5SDimitry Andric }
7520eae32dcSDimitry Andric return Result;
7530b57cec5SDimitry Andric }
7540b57cec5SDimitry Andric
ProcessOverloadCandidates(Sema & SemaRef,unsigned CurrentArg,OverloadCandidate * Candidates,unsigned NumCandidates,SourceLocation OpenParLoc,bool Braced)7550b57cec5SDimitry Andric void PrintingCodeCompleteConsumer::ProcessOverloadCandidates(
7560b57cec5SDimitry Andric Sema &SemaRef, unsigned CurrentArg, OverloadCandidate *Candidates,
75704eeddc0SDimitry Andric unsigned NumCandidates, SourceLocation OpenParLoc, bool Braced) {
7580b57cec5SDimitry Andric OS << "OPENING_PAREN_LOC: ";
7590b57cec5SDimitry Andric OpenParLoc.print(OS, SemaRef.getSourceManager());
7600b57cec5SDimitry Andric OS << "\n";
7610b57cec5SDimitry Andric
7620b57cec5SDimitry Andric for (unsigned I = 0; I != NumCandidates; ++I) {
7630b57cec5SDimitry Andric if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString(
7640b57cec5SDimitry Andric CurrentArg, SemaRef, getAllocator(), CCTUInfo,
76504eeddc0SDimitry Andric includeBriefComments(), Braced)) {
7660b57cec5SDimitry Andric OS << "OVERLOAD: " << getOverloadAsString(*CCS) << "\n";
7670b57cec5SDimitry Andric }
7680b57cec5SDimitry Andric }
7690b57cec5SDimitry Andric }
7700b57cec5SDimitry Andric
7710b57cec5SDimitry Andric /// Retrieve the effective availability of the given declaration.
getDeclAvailability(const Decl * D)7720b57cec5SDimitry Andric static AvailabilityResult getDeclAvailability(const Decl *D) {
7730b57cec5SDimitry Andric AvailabilityResult AR = D->getAvailability();
7740b57cec5SDimitry Andric if (isa<EnumConstantDecl>(D))
7750b57cec5SDimitry Andric AR = std::max(AR, cast<Decl>(D->getDeclContext())->getAvailability());
7760b57cec5SDimitry Andric return AR;
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric
computeCursorKindAndAvailability(bool Accessible)7790b57cec5SDimitry Andric void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) {
7800b57cec5SDimitry Andric switch (Kind) {
7810b57cec5SDimitry Andric case RK_Pattern:
7820b57cec5SDimitry Andric if (!Declaration) {
7830b57cec5SDimitry Andric // Do nothing: Patterns can come with cursor kinds!
7840b57cec5SDimitry Andric break;
7850b57cec5SDimitry Andric }
786bdd1243dSDimitry Andric [[fallthrough]];
7870b57cec5SDimitry Andric
7880b57cec5SDimitry Andric case RK_Declaration: {
7890b57cec5SDimitry Andric // Set the availability based on attributes.
7900b57cec5SDimitry Andric switch (getDeclAvailability(Declaration)) {
7910b57cec5SDimitry Andric case AR_Available:
7920b57cec5SDimitry Andric case AR_NotYetIntroduced:
7930b57cec5SDimitry Andric Availability = CXAvailability_Available;
7940b57cec5SDimitry Andric break;
7950b57cec5SDimitry Andric
7960b57cec5SDimitry Andric case AR_Deprecated:
7970b57cec5SDimitry Andric Availability = CXAvailability_Deprecated;
7980b57cec5SDimitry Andric break;
7990b57cec5SDimitry Andric
8000b57cec5SDimitry Andric case AR_Unavailable:
8010b57cec5SDimitry Andric Availability = CXAvailability_NotAvailable;
8020b57cec5SDimitry Andric break;
8030b57cec5SDimitry Andric }
8040b57cec5SDimitry Andric
8050b57cec5SDimitry Andric if (const auto *Function = dyn_cast<FunctionDecl>(Declaration))
8060b57cec5SDimitry Andric if (Function->isDeleted())
8070b57cec5SDimitry Andric Availability = CXAvailability_NotAvailable;
8080b57cec5SDimitry Andric
8090b57cec5SDimitry Andric CursorKind = getCursorKindForDecl(Declaration);
8100b57cec5SDimitry Andric if (CursorKind == CXCursor_UnexposedDecl) {
8110b57cec5SDimitry Andric // FIXME: Forward declarations of Objective-C classes and protocols
8120b57cec5SDimitry Andric // are not directly exposed, but we want code completion to treat them
8130b57cec5SDimitry Andric // like a definition.
8140b57cec5SDimitry Andric if (isa<ObjCInterfaceDecl>(Declaration))
8150b57cec5SDimitry Andric CursorKind = CXCursor_ObjCInterfaceDecl;
8160b57cec5SDimitry Andric else if (isa<ObjCProtocolDecl>(Declaration))
8170b57cec5SDimitry Andric CursorKind = CXCursor_ObjCProtocolDecl;
8180b57cec5SDimitry Andric else
8190b57cec5SDimitry Andric CursorKind = CXCursor_NotImplemented;
8200b57cec5SDimitry Andric }
8210b57cec5SDimitry Andric break;
8220b57cec5SDimitry Andric }
8230b57cec5SDimitry Andric
8240b57cec5SDimitry Andric case RK_Macro:
8250b57cec5SDimitry Andric case RK_Keyword:
8260b57cec5SDimitry Andric llvm_unreachable("Macro and keyword kinds are handled by the constructors");
8270b57cec5SDimitry Andric }
8280b57cec5SDimitry Andric
8290b57cec5SDimitry Andric if (!Accessible)
8300b57cec5SDimitry Andric Availability = CXAvailability_NotAccessible;
8310b57cec5SDimitry Andric }
8320b57cec5SDimitry Andric
8330b57cec5SDimitry Andric /// Retrieve the name that should be used to order a result.
8340b57cec5SDimitry Andric ///
8350b57cec5SDimitry Andric /// If the name needs to be constructed as a string, that string will be
8360b57cec5SDimitry Andric /// saved into Saved and the returned StringRef will refer to it.
getOrderedName(std::string & Saved) const8370b57cec5SDimitry Andric StringRef CodeCompletionResult::getOrderedName(std::string &Saved) const {
8380b57cec5SDimitry Andric switch (Kind) {
8390b57cec5SDimitry Andric case RK_Keyword:
8400b57cec5SDimitry Andric return Keyword;
8410b57cec5SDimitry Andric case RK_Pattern:
8420b57cec5SDimitry Andric return Pattern->getTypedText();
8430b57cec5SDimitry Andric case RK_Macro:
8440b57cec5SDimitry Andric return Macro->getName();
8450b57cec5SDimitry Andric case RK_Declaration:
8460b57cec5SDimitry Andric // Handle declarations below.
8470b57cec5SDimitry Andric break;
8480b57cec5SDimitry Andric }
8490b57cec5SDimitry Andric
8500b57cec5SDimitry Andric DeclarationName Name = Declaration->getDeclName();
8510b57cec5SDimitry Andric
8520b57cec5SDimitry Andric // If the name is a simple identifier (by far the common case), or a
8530b57cec5SDimitry Andric // zero-argument selector, just return a reference to that identifier.
8540b57cec5SDimitry Andric if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
8550b57cec5SDimitry Andric return Id->getName();
8560b57cec5SDimitry Andric if (Name.isObjCZeroArgSelector())
857*0fca6ea1SDimitry Andric if (const IdentifierInfo *Id =
858*0fca6ea1SDimitry Andric Name.getObjCSelector().getIdentifierInfoForSlot(0))
8590b57cec5SDimitry Andric return Id->getName();
8600b57cec5SDimitry Andric
8610b57cec5SDimitry Andric Saved = Name.getAsString();
8620b57cec5SDimitry Andric return Saved;
8630b57cec5SDimitry Andric }
8640b57cec5SDimitry Andric
operator <(const CodeCompletionResult & X,const CodeCompletionResult & Y)8650b57cec5SDimitry Andric bool clang::operator<(const CodeCompletionResult &X,
8660b57cec5SDimitry Andric const CodeCompletionResult &Y) {
8670b57cec5SDimitry Andric std::string XSaved, YSaved;
8680b57cec5SDimitry Andric StringRef XStr = X.getOrderedName(XSaved);
8690b57cec5SDimitry Andric StringRef YStr = Y.getOrderedName(YSaved);
870fe6060f1SDimitry Andric int cmp = XStr.compare_insensitive(YStr);
8710b57cec5SDimitry Andric if (cmp)
8720b57cec5SDimitry Andric return cmp < 0;
8730b57cec5SDimitry Andric
8740b57cec5SDimitry Andric // If case-insensitive comparison fails, try case-sensitive comparison.
8750b57cec5SDimitry Andric return XStr.compare(YStr) < 0;
8760b57cec5SDimitry Andric }
877