blob: 226257dd395b7e97a73ff4ed88470636e789761f [file] [log] [blame]
Eugene Zelenko711964d2018-02-20 02:16:28 +00001//===- CodeCompleteConsumer.cpp - Code Completion Interface ---------------===//
Douglas Gregor2436e712009-09-17 21:32:03 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements the CodeCompleteConsumer class.
11//
12//===----------------------------------------------------------------------===//
Eugene Zelenko711964d2018-02-20 02:16:28 +000013
Douglas Gregor2436e712009-09-17 21:32:03 +000014#include "clang/Sema/CodeCompleteConsumer.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000015#include "clang-c/Index.h"
Eugene Zelenko711964d2018-02-20 02:16:28 +000016#include "clang/AST/Decl.h"
17#include "clang/AST/DeclBase.h"
John McCallde6836a2010-08-24 07:21:54 +000018#include "clang/AST/DeclObjC.h"
John McCall19c1bfd2010-08-25 05:32:35 +000019#include "clang/AST/DeclTemplate.h"
Eugene Zelenko711964d2018-02-20 02:16:28 +000020#include "clang/AST/DeclarationName.h"
21#include "clang/AST/Type.h"
22#include "clang/Basic/IdentifierTable.h"
Vassil Vassilev644ea612016-07-27 14:56:59 +000023#include "clang/Lex/Preprocessor.h"
Ilya Biryukov2fab2352018-08-30 13:08:03 +000024#include "clang/Sema/Sema.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000025#include "llvm/ADT/SmallString.h"
Eugene Zelenko711964d2018-02-20 02:16:28 +000026#include "llvm/ADT/SmallVector.h"
27#include "llvm/ADT/StringRef.h"
Douglas Gregor669a25a2011-02-17 00:22:45 +000028#include "llvm/ADT/Twine.h"
Eugene Zelenko711964d2018-02-20 02:16:28 +000029#include "llvm/Support/Casting.h"
30#include "llvm/Support/Compiler.h"
31#include "llvm/Support/ErrorHandling.h"
Ilya Biryukov2fab2352018-08-30 13:08:03 +000032#include "llvm/Support/FormatVariadic.h"
Douglas Gregor2436e712009-09-17 21:32:03 +000033#include "llvm/Support/raw_ostream.h"
34#include <algorithm>
Eugene Zelenko711964d2018-02-20 02:16:28 +000035#include <cassert>
36#include <cstdint>
37#include <string>
Douglas Gregorab6ccb52009-11-17 16:43:05 +000038
Douglas Gregor2436e712009-09-17 21:32:03 +000039using namespace clang;
40
Douglas Gregorfedc3282009-09-18 22:15:54 +000041//===----------------------------------------------------------------------===//
Douglas Gregor0212fd72010-09-21 16:06:22 +000042// Code completion context implementation
43//===----------------------------------------------------------------------===//
44
45bool CodeCompletionContext::wantConstructorResults() const {
Ilya Biryukov3289ab22018-02-19 13:53:49 +000046 switch (CCKind) {
Douglas Gregor0ac41382010-09-23 23:01:17 +000047 case CCC_Recovery:
Douglas Gregor0212fd72010-09-21 16:06:22 +000048 case CCC_Statement:
49 case CCC_Expression:
50 case CCC_ObjCMessageReceiver:
51 case CCC_ParenthesizedExpression:
52 return true;
Fangrui Song6907ce22018-07-30 19:24:48 +000053
Douglas Gregor0212fd72010-09-21 16:06:22 +000054 case CCC_TopLevel:
55 case CCC_ObjCInterface:
56 case CCC_ObjCImplementation:
57 case CCC_ObjCIvarList:
58 case CCC_ClassStructUnion:
Douglas Gregor21325842011-07-07 16:03:39 +000059 case CCC_DotMemberAccess:
60 case CCC_ArrowMemberAccess:
61 case CCC_ObjCPropertyAccess:
Douglas Gregor0212fd72010-09-21 16:06:22 +000062 case CCC_EnumTag:
63 case CCC_UnionTag:
64 case CCC_ClassOrStructTag:
65 case CCC_ObjCProtocolName:
66 case CCC_Namespace:
67 case CCC_Type:
68 case CCC_Name:
69 case CCC_PotentiallyQualifiedName:
70 case CCC_MacroName:
71 case CCC_MacroNameUse:
72 case CCC_PreprocessorExpression:
73 case CCC_PreprocessorDirective:
74 case CCC_NaturalLanguage:
75 case CCC_SelectorName:
76 case CCC_TypeQualifiers:
Douglas Gregor0ac41382010-09-23 23:01:17 +000077 case CCC_Other:
Douglas Gregor3a69eaf2011-02-18 23:30:37 +000078 case CCC_OtherWithMacros:
Douglas Gregor21325842011-07-07 16:03:39 +000079 case CCC_ObjCInstanceMessage:
80 case CCC_ObjCClassMessage:
Douglas Gregor2c595ad2011-07-30 06:55:39 +000081 case CCC_ObjCInterfaceName:
Douglas Gregor21325842011-07-07 16:03:39 +000082 case CCC_ObjCCategoryName:
Douglas Gregor0212fd72010-09-21 16:06:22 +000083 return false;
84 }
David Blaikie8a40f702012-01-17 06:56:22 +000085
86 llvm_unreachable("Invalid CodeCompletionContext::Kind!");
Douglas Gregor0212fd72010-09-21 16:06:22 +000087}
88
Ilya Biryukov3289ab22018-02-19 13:53:49 +000089StringRef clang::getCompletionKindString(CodeCompletionContext::Kind Kind) {
90 using CCKind = CodeCompletionContext::Kind;
Ilya Biryukov27d82582018-02-19 12:35:33 +000091 switch (Kind) {
92 case CCKind::CCC_Other:
93 return "Other";
94 case CCKind::CCC_OtherWithMacros:
95 return "OtherWithMacros";
96 case CCKind::CCC_TopLevel:
97 return "TopLevel";
98 case CCKind::CCC_ObjCInterface:
99 return "ObjCInterface";
100 case CCKind::CCC_ObjCImplementation:
101 return "ObjCImplementation";
102 case CCKind::CCC_ObjCIvarList:
103 return "ObjCIvarList";
104 case CCKind::CCC_ClassStructUnion:
105 return "ClassStructUnion";
106 case CCKind::CCC_Statement:
107 return "Statement";
108 case CCKind::CCC_Expression:
109 return "Expression";
110 case CCKind::CCC_ObjCMessageReceiver:
111 return "ObjCMessageReceiver";
112 case CCKind::CCC_DotMemberAccess:
113 return "DotMemberAccess";
114 case CCKind::CCC_ArrowMemberAccess:
115 return "ArrowMemberAccess";
116 case CCKind::CCC_ObjCPropertyAccess:
117 return "ObjCPropertyAccess";
118 case CCKind::CCC_EnumTag:
119 return "EnumTag";
120 case CCKind::CCC_UnionTag:
121 return "UnionTag";
122 case CCKind::CCC_ClassOrStructTag:
123 return "ClassOrStructTag";
124 case CCKind::CCC_ObjCProtocolName:
125 return "ObjCProtocolName";
126 case CCKind::CCC_Namespace:
127 return "Namespace";
128 case CCKind::CCC_Type:
129 return "Type";
130 case CCKind::CCC_Name:
131 return "Name";
132 case CCKind::CCC_PotentiallyQualifiedName:
133 return "PotentiallyQualifiedName";
134 case CCKind::CCC_MacroName:
135 return "MacroName";
136 case CCKind::CCC_MacroNameUse:
137 return "MacroNameUse";
138 case CCKind::CCC_PreprocessorExpression:
139 return "PreprocessorExpression";
140 case CCKind::CCC_PreprocessorDirective:
141 return "PreprocessorDirective";
142 case CCKind::CCC_NaturalLanguage:
143 return "NaturalLanguage";
144 case CCKind::CCC_SelectorName:
145 return "SelectorName";
146 case CCKind::CCC_TypeQualifiers:
147 return "TypeQualifiers";
148 case CCKind::CCC_ParenthesizedExpression:
149 return "ParenthesizedExpression";
150 case CCKind::CCC_ObjCInstanceMessage:
151 return "ObjCInstanceMessage";
152 case CCKind::CCC_ObjCClassMessage:
153 return "ObjCClassMessage";
154 case CCKind::CCC_ObjCInterfaceName:
155 return "ObjCInterfaceName";
156 case CCKind::CCC_ObjCCategoryName:
157 return "ObjCCategoryName";
158 case CCKind::CCC_Recovery:
159 return "Recovery";
160 }
161 llvm_unreachable("Invalid CodeCompletionContext::Kind!");
162}
163
Douglas Gregor0212fd72010-09-21 16:06:22 +0000164//===----------------------------------------------------------------------===//
Douglas Gregorfedc3282009-09-18 22:15:54 +0000165// Code completion string implementation
166//===----------------------------------------------------------------------===//
Eugene Zelenko711964d2018-02-20 02:16:28 +0000167
Fangrui Song6907ce22018-07-30 19:24:48 +0000168CodeCompletionString::Chunk::Chunk(ChunkKind Kind, const char *Text)
Eugene Zelenko711964d2018-02-20 02:16:28 +0000169 : Kind(Kind), Text("") {
Douglas Gregor9eb77012009-11-07 00:00:49 +0000170 switch (Kind) {
171 case CK_TypedText:
172 case CK_Text:
173 case CK_Placeholder:
174 case CK_Informative:
Douglas Gregorb3fa9192009-12-18 18:53:37 +0000175 case CK_ResultType:
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000176 case CK_CurrentParameter:
177 this->Text = Text;
Douglas Gregor9eb77012009-11-07 00:00:49 +0000178 break;
Douglas Gregor9eb77012009-11-07 00:00:49 +0000179
180 case CK_Optional:
Jeffrey Yasskin1615d452009-12-12 05:05:38 +0000181 llvm_unreachable("Optional strings cannot be created from text");
Fangrui Song6907ce22018-07-30 19:24:48 +0000182
Douglas Gregor9eb77012009-11-07 00:00:49 +0000183 case CK_LeftParen:
184 this->Text = "(";
185 break;
186
187 case CK_RightParen:
188 this->Text = ")";
189 break;
190
191 case CK_LeftBracket:
192 this->Text = "[";
193 break;
Fangrui Song6907ce22018-07-30 19:24:48 +0000194
Douglas Gregor9eb77012009-11-07 00:00:49 +0000195 case CK_RightBracket:
196 this->Text = "]";
197 break;
Fangrui Song6907ce22018-07-30 19:24:48 +0000198
Douglas Gregor9eb77012009-11-07 00:00:49 +0000199 case CK_LeftBrace:
200 this->Text = "{";
201 break;
202
203 case CK_RightBrace:
204 this->Text = "}";
205 break;
206
207 case CK_LeftAngle:
208 this->Text = "<";
209 break;
Fangrui Song6907ce22018-07-30 19:24:48 +0000210
Douglas Gregor9eb77012009-11-07 00:00:49 +0000211 case CK_RightAngle:
212 this->Text = ">";
213 break;
Fangrui Song6907ce22018-07-30 19:24:48 +0000214
Douglas Gregor9eb77012009-11-07 00:00:49 +0000215 case CK_Comma:
216 this->Text = ", ";
217 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000218
219 case CK_Colon:
Douglas Gregor636a61e2010-04-07 00:21:17 +0000220 this->Text = ":";
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000221 break;
222
223 case CK_SemiColon:
224 this->Text = ";";
225 break;
226
227 case CK_Equal:
228 this->Text = " = ";
229 break;
230
231 case CK_HorizontalSpace:
232 this->Text = " ";
233 break;
234
235 case CK_VerticalSpace:
236 this->Text = "\n";
237 break;
Douglas Gregor9eb77012009-11-07 00:00:49 +0000238 }
Douglas Gregor5bf52692009-09-22 23:15:58 +0000239}
240
241CodeCompletionString::Chunk
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000242CodeCompletionString::Chunk::CreateText(const char *Text) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000243 return Chunk(CK_Text, Text);
Douglas Gregorfedc3282009-09-18 22:15:54 +0000244}
245
Fangrui Song6907ce22018-07-30 19:24:48 +0000246CodeCompletionString::Chunk
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000247CodeCompletionString::Chunk::CreateOptional(CodeCompletionString *Optional) {
Douglas Gregorfedc3282009-09-18 22:15:54 +0000248 Chunk Result;
249 Result.Kind = CK_Optional;
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000250 Result.Optional = Optional;
Douglas Gregorfedc3282009-09-18 22:15:54 +0000251 return Result;
252}
253
Fangrui Song6907ce22018-07-30 19:24:48 +0000254CodeCompletionString::Chunk
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000255CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000256 return Chunk(CK_Placeholder, Placeholder);
257}
258
Fangrui Song6907ce22018-07-30 19:24:48 +0000259CodeCompletionString::Chunk
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000260CodeCompletionString::Chunk::CreateInformative(const char *Informative) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000261 return Chunk(CK_Informative, Informative);
Douglas Gregorfedc3282009-09-18 22:15:54 +0000262}
263
Fangrui Song6907ce22018-07-30 19:24:48 +0000264CodeCompletionString::Chunk
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000265CodeCompletionString::Chunk::CreateResultType(const char *ResultType) {
Douglas Gregorb3fa9192009-12-18 18:53:37 +0000266 return Chunk(CK_ResultType, ResultType);
267}
268
Fangrui Song6907ce22018-07-30 19:24:48 +0000269CodeCompletionString::Chunk
Douglas Gregor9eb77012009-11-07 00:00:49 +0000270CodeCompletionString::Chunk::CreateCurrentParameter(
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000271 const char *CurrentParameter) {
Douglas Gregor9eb77012009-11-07 00:00:49 +0000272 return Chunk(CK_CurrentParameter, CurrentParameter);
273}
274
Fangrui Song6907ce22018-07-30 19:24:48 +0000275CodeCompletionString::CodeCompletionString(const Chunk *Chunks,
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000276 unsigned NumChunks,
Fangrui Song6907ce22018-07-30 19:24:48 +0000277 unsigned Priority,
Erik Verbruggen98ea7f62011-10-14 15:31:08 +0000278 CXAvailabilityKind Availability,
279 const char **Annotations,
Douglas Gregor78254c82012-03-27 23:34:16 +0000280 unsigned NumAnnotations,
Dmitri Gribenko3292d062012-07-02 17:35:10 +0000281 StringRef ParentName,
282 const char *BriefComment)
Eugene Zelenko711964d2018-02-20 02:16:28 +0000283 : NumChunks(NumChunks), NumAnnotations(NumAnnotations),
284 Priority(Priority), Availability(Availability),
Fangrui Song6907ce22018-07-30 19:24:48 +0000285 ParentName(ParentName), BriefComment(BriefComment) {
Erik Verbruggen98ea7f62011-10-14 15:31:08 +0000286 assert(NumChunks <= 0xffff);
287 assert(NumAnnotations <= 0xffff);
288
Eugene Zelenko1e95bc02018-04-05 22:15:42 +0000289 Chunk *StoredChunks = reinterpret_cast<Chunk *>(this + 1);
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000290 for (unsigned I = 0; I != NumChunks; ++I)
291 StoredChunks[I] = Chunks[I];
Erik Verbruggen98ea7f62011-10-14 15:31:08 +0000292
Eugene Zelenko1e95bc02018-04-05 22:15:42 +0000293 const char **StoredAnnotations = reinterpret_cast<const char **>(StoredChunks + NumChunks);
Erik Verbruggen98ea7f62011-10-14 15:31:08 +0000294 for (unsigned I = 0; I != NumAnnotations; ++I)
295 StoredAnnotations[I] = Annotations[I];
Douglas Gregorfedc3282009-09-18 22:15:54 +0000296}
297
Erik Verbruggen98ea7f62011-10-14 15:31:08 +0000298unsigned CodeCompletionString::getAnnotationCount() const {
299 return NumAnnotations;
300}
301
302const char *CodeCompletionString::getAnnotation(unsigned AnnotationNr) const {
303 if (AnnotationNr < NumAnnotations)
304 return reinterpret_cast<const char * const*>(end())[AnnotationNr];
305 else
Craig Topperc3ec1492014-05-26 06:22:03 +0000306 return nullptr;
Erik Verbruggen98ea7f62011-10-14 15:31:08 +0000307}
308
Douglas Gregorfedc3282009-09-18 22:15:54 +0000309std::string CodeCompletionString::getAsString() const {
310 std::string Result;
311 llvm::raw_string_ostream OS(Result);
Fangrui Song6907ce22018-07-30 19:24:48 +0000312
Douglas Gregorfedc3282009-09-18 22:15:54 +0000313 for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
314 switch (C->Kind) {
Douglas Gregorfedc3282009-09-18 22:15:54 +0000315 case CK_Optional: OS << "{#" << C->Optional->getAsString() << "#}"; break;
Douglas Gregor5bf52692009-09-22 23:15:58 +0000316 case CK_Placeholder: OS << "<#" << C->Text << "#>"; break;
Fangrui Song6907ce22018-07-30 19:24:48 +0000317
318 case CK_Informative:
Douglas Gregorb3fa9192009-12-18 18:53:37 +0000319 case CK_ResultType:
Fangrui Song6907ce22018-07-30 19:24:48 +0000320 OS << "[#" << C->Text << "#]";
Douglas Gregorb3fa9192009-12-18 18:53:37 +0000321 break;
Fangrui Song6907ce22018-07-30 19:24:48 +0000322
Douglas Gregor9eb77012009-11-07 00:00:49 +0000323 case CK_CurrentParameter: OS << "<#" << C->Text << "#>"; break;
324 default: OS << C->Text; break;
Douglas Gregorfedc3282009-09-18 22:15:54 +0000325 }
326 }
Dan Gohman4888f1a2010-07-26 21:33:22 +0000327 return OS.str();
Douglas Gregorfedc3282009-09-18 22:15:54 +0000328}
329
Douglas Gregor45f83ee2009-11-19 00:01:57 +0000330const char *CodeCompletionString::getTypedText() const {
331 for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
332 if (C->Kind == CK_TypedText)
333 return C->Text;
Craig Topperc3ec1492014-05-26 06:22:03 +0000334
335 return nullptr;
Douglas Gregor45f83ee2009-11-19 00:01:57 +0000336}
337
Yaron Keren1ee89fc2015-03-17 09:51:17 +0000338const char *CodeCompletionAllocator::CopyString(const Twine &String) {
339 SmallString<128> Data;
340 StringRef Ref = String.toStringRef(Data);
Douglas Gregor669a25a2011-02-17 00:22:45 +0000341 // FIXME: It would be more efficient to teach Twine to tell us its size and
342 // then add a routine there to fill in an allocated char* with the contents
343 // of the string.
Eugene Zelenko1e95bc02018-04-05 22:15:42 +0000344 char *Mem = (char *)Allocate(Ref.size() + 1, 1);
Yaron Keren1ee89fc2015-03-17 09:51:17 +0000345 std::copy(Ref.begin(), Ref.end(), Mem);
346 Mem[Ref.size()] = 0;
347 return Mem;
Douglas Gregor669a25a2011-02-17 00:22:45 +0000348}
349
Dmitri Gribenkofe0483d2013-01-23 17:21:11 +0000350StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) {
Eugene Zelenko1e95bc02018-04-05 22:15:42 +0000351 const NamedDecl *ND = dyn_cast<NamedDecl>(DC);
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000352 if (!ND)
Eugene Zelenko711964d2018-02-20 02:16:28 +0000353 return {};
Fangrui Song6907ce22018-07-30 19:24:48 +0000354
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000355 // Check whether we've already cached the parent name.
356 StringRef &CachedParentName = ParentNames[DC];
357 if (!CachedParentName.empty())
358 return CachedParentName;
359
360 // If we already processed this DeclContext and assigned empty to it, the
361 // data pointer will be non-null.
Craig Topperc3ec1492014-05-26 06:22:03 +0000362 if (CachedParentName.data() != nullptr)
Eugene Zelenko711964d2018-02-20 02:16:28 +0000363 return {};
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000364
365 // Find the interesting names.
Dmitri Gribenkofe0483d2013-01-23 17:21:11 +0000366 SmallVector<const DeclContext *, 2> Contexts;
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000367 while (DC && !DC->isFunctionOrMethod()) {
Eugene Zelenko1e95bc02018-04-05 22:15:42 +0000368 if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000369 if (ND->getIdentifier())
370 Contexts.push_back(DC);
371 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000372
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000373 DC = DC->getParent();
374 }
375
376 {
Dmitri Gribenkof8579502013-01-12 19:30:44 +0000377 SmallString<128> S;
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000378 llvm::raw_svector_ostream OS(S);
379 bool First = true;
380 for (unsigned I = Contexts.size(); I != 0; --I) {
381 if (First)
382 First = false;
383 else {
384 OS << "::";
385 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000386
Dmitri Gribenkofe0483d2013-01-23 17:21:11 +0000387 const DeclContext *CurDC = Contexts[I-1];
Eugene Zelenko1e95bc02018-04-05 22:15:42 +0000388 if (const ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000389 CurDC = CatImpl->getCategoryDecl();
Fangrui Song6907ce22018-07-30 19:24:48 +0000390
Eugene Zelenko1e95bc02018-04-05 22:15:42 +0000391 if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
Dmitri Gribenkofe0483d2013-01-23 17:21:11 +0000392 const ObjCInterfaceDecl *Interface = Cat->getClassInterface();
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000393 if (!Interface) {
394 // Assign an empty StringRef but with non-null data to distinguish
395 // between empty because we didn't process the DeclContext yet.
Reid Klecknerd16cebe2016-02-10 19:09:15 +0000396 CachedParentName = StringRef((const char *)(uintptr_t)~0U, 0);
Eugene Zelenko711964d2018-02-20 02:16:28 +0000397 return {};
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000398 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000399
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000400 OS << Interface->getName() << '(' << Cat->getName() << ')';
401 } else {
402 OS << cast<NamedDecl>(CurDC)->getName();
403 }
404 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000405
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000406 CachedParentName = AllocatorRef->CopyString(OS.str());
407 }
408
409 return CachedParentName;
410}
411
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000412CodeCompletionString *CodeCompletionBuilder::TakeString() {
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000413 void *Mem = getAllocator().Allocate(
Benjamin Kramerc3f89252016-10-20 14:27:22 +0000414 sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size() +
415 sizeof(const char *) * Annotations.size(),
416 alignof(CodeCompletionString));
Fangrui Song6907ce22018-07-30 19:24:48 +0000417 CodeCompletionString *Result
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000418 = new (Mem) CodeCompletionString(Chunks.data(), Chunks.size(),
Erik Verbruggen98ea7f62011-10-14 15:31:08 +0000419 Priority, Availability,
Douglas Gregor78254c82012-03-27 23:34:16 +0000420 Annotations.data(), Annotations.size(),
Argyrios Kyrtzidis9ae39562012-09-26 16:39:56 +0000421 ParentName, BriefComment);
Douglas Gregorb278aaf2011-02-01 19:23:04 +0000422 Chunks.clear();
Douglas Gregor45f83ee2009-11-19 00:01:57 +0000423 return Result;
424}
Douglas Gregor9eb77012009-11-07 00:00:49 +0000425
Benjamin Kramerdb534a42012-03-26 16:57:36 +0000426void CodeCompletionBuilder::AddTypedTextChunk(const char *Text) {
427 Chunks.push_back(Chunk(CodeCompletionString::CK_TypedText, Text));
428}
429
430void CodeCompletionBuilder::AddTextChunk(const char *Text) {
431 Chunks.push_back(Chunk::CreateText(Text));
432}
433
434void CodeCompletionBuilder::AddOptionalChunk(CodeCompletionString *Optional) {
435 Chunks.push_back(Chunk::CreateOptional(Optional));
436}
437
438void CodeCompletionBuilder::AddPlaceholderChunk(const char *Placeholder) {
439 Chunks.push_back(Chunk::CreatePlaceholder(Placeholder));
440}
441
442void CodeCompletionBuilder::AddInformativeChunk(const char *Text) {
443 Chunks.push_back(Chunk::CreateInformative(Text));
444}
445
446void CodeCompletionBuilder::AddResultTypeChunk(const char *ResultType) {
447 Chunks.push_back(Chunk::CreateResultType(ResultType));
448}
449
450void
451CodeCompletionBuilder::AddCurrentParameterChunk(const char *CurrentParameter) {
452 Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter));
453}
454
455void CodeCompletionBuilder::AddChunk(CodeCompletionString::ChunkKind CK,
456 const char *Text) {
457 Chunks.push_back(Chunk(CK, Text));
458}
459
Dmitri Gribenkofe0483d2013-01-23 17:21:11 +0000460void CodeCompletionBuilder::addParentContext(const DeclContext *DC) {
Eugene Zelenko711964d2018-02-20 02:16:28 +0000461 if (DC->isTranslationUnit())
Douglas Gregor78254c82012-03-27 23:34:16 +0000462 return;
Fangrui Song6907ce22018-07-30 19:24:48 +0000463
Douglas Gregor78254c82012-03-27 23:34:16 +0000464 if (DC->isFunctionOrMethod())
465 return;
Fangrui Song6907ce22018-07-30 19:24:48 +0000466
Eugene Zelenko1e95bc02018-04-05 22:15:42 +0000467 const NamedDecl *ND = dyn_cast<NamedDecl>(DC);
Douglas Gregor78254c82012-03-27 23:34:16 +0000468 if (!ND)
469 return;
Fangrui Song6907ce22018-07-30 19:24:48 +0000470
Argyrios Kyrtzidis9d7c0fe2012-04-10 17:23:48 +0000471 ParentName = getCodeCompletionTUInfo().getParentName(DC);
Douglas Gregor78254c82012-03-27 23:34:16 +0000472}
473
Dmitri Gribenko3292d062012-07-02 17:35:10 +0000474void CodeCompletionBuilder::addBriefComment(StringRef Comment) {
475 BriefComment = Allocator.CopyString(Comment);
476}
477
Douglas Gregorfedc3282009-09-18 22:15:54 +0000478//===----------------------------------------------------------------------===//
Douglas Gregor05f477c2009-09-23 00:16:58 +0000479// Code completion overload candidate implementation
480//===----------------------------------------------------------------------===//
481FunctionDecl *
482CodeCompleteConsumer::OverloadCandidate::getFunction() const {
483 if (getKind() == CK_Function)
484 return Function;
485 else if (getKind() == CK_FunctionTemplate)
486 return FunctionTemplate->getTemplatedDecl();
487 else
Craig Topperc3ec1492014-05-26 06:22:03 +0000488 return nullptr;
Douglas Gregor05f477c2009-09-23 00:16:58 +0000489}
490
491const FunctionType *
492CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
493 switch (Kind) {
494 case CK_Function:
495 return Function->getType()->getAs<FunctionType>();
Fangrui Song6907ce22018-07-30 19:24:48 +0000496
Douglas Gregor05f477c2009-09-23 00:16:58 +0000497 case CK_FunctionTemplate:
498 return FunctionTemplate->getTemplatedDecl()->getType()
499 ->getAs<FunctionType>();
Fangrui Song6907ce22018-07-30 19:24:48 +0000500
Douglas Gregor05f477c2009-09-23 00:16:58 +0000501 case CK_FunctionType:
502 return Type;
503 }
David Blaikie8a40f702012-01-17 06:56:22 +0000504
505 llvm_unreachable("Invalid CandidateKind!");
Douglas Gregor05f477c2009-09-23 00:16:58 +0000506}
507
508//===----------------------------------------------------------------------===//
Douglas Gregorfedc3282009-09-18 22:15:54 +0000509// Code completion consumer implementation
510//===----------------------------------------------------------------------===//
511
Eugene Zelenko711964d2018-02-20 02:16:28 +0000512CodeCompleteConsumer::~CodeCompleteConsumer() = default;
Douglas Gregorfedc3282009-09-18 22:15:54 +0000513
Vassil Vassilev644ea612016-07-27 14:56:59 +0000514bool PrintingCodeCompleteConsumer::isResultFilteredOut(StringRef Filter,
515 CodeCompletionResult Result) {
516 switch (Result.Kind) {
Eugene Zelenko711964d2018-02-20 02:16:28 +0000517 case CodeCompletionResult::RK_Declaration:
Vassil Vassilev644ea612016-07-27 14:56:59 +0000518 return !(Result.Declaration->getIdentifier() &&
519 Result.Declaration->getIdentifier()->getName().startswith(Filter));
Eugene Zelenko711964d2018-02-20 02:16:28 +0000520 case CodeCompletionResult::RK_Keyword:
Vassil Vassilev644ea612016-07-27 14:56:59 +0000521 return !StringRef(Result.Keyword).startswith(Filter);
Eugene Zelenko711964d2018-02-20 02:16:28 +0000522 case CodeCompletionResult::RK_Macro:
Vassil Vassilev644ea612016-07-27 14:56:59 +0000523 return !Result.Macro->getName().startswith(Filter);
Eugene Zelenko711964d2018-02-20 02:16:28 +0000524 case CodeCompletionResult::RK_Pattern:
Vassil Vassilev644ea612016-07-27 14:56:59 +0000525 return !StringRef(Result.Pattern->getAsString()).startswith(Filter);
526 }
Simon Pilgrime71a1f92016-07-27 16:41:56 +0000527 llvm_unreachable("Unknown code completion result Kind.");
Vassil Vassilev644ea612016-07-27 14:56:59 +0000528}
529
Fangrui Song6907ce22018-07-30 19:24:48 +0000530void
Daniel Dunbar242ea9a2009-11-13 08:58:20 +0000531PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
Douglas Gregor00c37ef2010-08-11 21:23:17 +0000532 CodeCompletionContext Context,
John McCall276321a2010-08-25 06:19:51 +0000533 CodeCompletionResult *Results,
Douglas Gregor2436e712009-09-17 21:32:03 +0000534 unsigned NumResults) {
Douglas Gregor49f67ce2010-08-26 13:48:20 +0000535 std::stable_sort(Results, Results + NumResults);
Fangrui Song6907ce22018-07-30 19:24:48 +0000536
Vassil Vassilev644ea612016-07-27 14:56:59 +0000537 StringRef Filter = SemaRef.getPreprocessor().getCodeCompletionFilter();
538
Douglas Gregor2436e712009-09-17 21:32:03 +0000539 // Print the results.
540 for (unsigned I = 0; I != NumResults; ++I) {
Vassil Vassilev644ea612016-07-27 14:56:59 +0000541 if(!Filter.empty() && isResultFilteredOut(Filter, Results[I]))
542 continue;
Douglas Gregor58acf322009-10-09 22:16:47 +0000543 OS << "COMPLETION: ";
Douglas Gregor2436e712009-09-17 21:32:03 +0000544 switch (Results[I].Kind) {
John McCall276321a2010-08-25 06:19:51 +0000545 case CodeCompletionResult::RK_Declaration:
Benjamin Kramerb89514a2011-10-14 18:45:37 +0000546 OS << *Results[I].Declaration;
Douglas Gregor2436e712009-09-17 21:32:03 +0000547 if (Results[I].Hidden)
548 OS << " (Hidden)";
Fangrui Song6907ce22018-07-30 19:24:48 +0000549 if (CodeCompletionString *CCS
Douglas Gregorc3425b12015-07-07 06:20:19 +0000550 = Results[I].CreateCodeCompletionString(SemaRef, Context,
551 getAllocator(),
Dmitri Gribenko3292d062012-07-02 17:35:10 +0000552 CCTUInfo,
553 includeBriefComments())) {
Douglas Gregorfedc3282009-09-18 22:15:54 +0000554 OS << " : " << CCS->getAsString();
Dmitri Gribenko3292d062012-07-02 17:35:10 +0000555 if (const char *BriefComment = CCS->getBriefComment())
556 OS << " : " << BriefComment;
Douglas Gregorfedc3282009-09-18 22:15:54 +0000557 }
Ivan Donchevskiib4670fc2018-05-25 12:56:26 +0000558 for (const FixItHint &FixIt : Results[I].FixIts) {
559 const SourceLocation BLoc = FixIt.RemoveRange.getBegin();
560 const SourceLocation ELoc = FixIt.RemoveRange.getEnd();
561
562 SourceManager &SM = SemaRef.SourceMgr;
563 std::pair<FileID, unsigned> BInfo = SM.getDecomposedLoc(BLoc);
564 std::pair<FileID, unsigned> EInfo = SM.getDecomposedLoc(ELoc);
565 // Adjust for token ranges.
566 if (FixIt.RemoveRange.isTokenRange())
567 EInfo.second += Lexer::MeasureTokenLength(ELoc, SM, SemaRef.LangOpts);
568
569 OS << " (requires fix-it:"
570 << " {" << SM.getLineNumber(BInfo.first, BInfo.second) << ':'
571 << SM.getColumnNumber(BInfo.first, BInfo.second) << '-'
572 << SM.getLineNumber(EInfo.first, EInfo.second) << ':'
573 << SM.getColumnNumber(EInfo.first, EInfo.second) << "}"
574 << " to \"" << FixIt.CodeToInsert << "\")";
575 }
Douglas Gregor2436e712009-09-17 21:32:03 +0000576 OS << '\n';
577 break;
Fangrui Song6907ce22018-07-30 19:24:48 +0000578
John McCall276321a2010-08-25 06:19:51 +0000579 case CodeCompletionResult::RK_Keyword:
Douglas Gregor52ce62f2010-01-13 23:24:38 +0000580 OS << Results[I].Keyword << '\n';
Douglas Gregor2436e712009-09-17 21:32:03 +0000581 break;
Fangrui Song6907ce22018-07-30 19:24:48 +0000582
Eugene Zelenko711964d2018-02-20 02:16:28 +0000583 case CodeCompletionResult::RK_Macro:
Douglas Gregor52ce62f2010-01-13 23:24:38 +0000584 OS << Results[I].Macro->getName();
Fangrui Song6907ce22018-07-30 19:24:48 +0000585 if (CodeCompletionString *CCS
Douglas Gregorc3425b12015-07-07 06:20:19 +0000586 = Results[I].CreateCodeCompletionString(SemaRef, Context,
587 getAllocator(),
Dmitri Gribenko3292d062012-07-02 17:35:10 +0000588 CCTUInfo,
589 includeBriefComments())) {
Douglas Gregorf329c7c2009-10-30 16:50:04 +0000590 OS << " : " << CCS->getAsString();
Douglas Gregorf329c7c2009-10-30 16:50:04 +0000591 }
592 OS << '\n';
593 break;
Fangrui Song6907ce22018-07-30 19:24:48 +0000594
Eugene Zelenko711964d2018-02-20 02:16:28 +0000595 case CodeCompletionResult::RK_Pattern:
Fangrui Song6907ce22018-07-30 19:24:48 +0000596 OS << "Pattern : "
Douglas Gregor45f83ee2009-11-19 00:01:57 +0000597 << Results[I].Pattern->getAsString() << '\n';
598 break;
599 }
Douglas Gregor2436e712009-09-17 21:32:03 +0000600 }
Douglas Gregor2436e712009-09-17 21:32:03 +0000601}
Douglas Gregor05f477c2009-09-23 00:16:58 +0000602
Francisco Lopes da Silva0c010cd2015-01-28 14:17:22 +0000603// This function is used solely to preserve the former presentation of overloads
604// by "clang -cc1 -code-completion-at", since CodeCompletionString::getAsString
605// needs to be improved for printing the newer and more detailed overload
606// chunks.
607static std::string getOverloadAsString(const CodeCompletionString &CCS) {
608 std::string Result;
609 llvm::raw_string_ostream OS(Result);
610
611 for (auto &C : CCS) {
612 switch (C.Kind) {
613 case CodeCompletionString::CK_Informative:
614 case CodeCompletionString::CK_ResultType:
615 OS << "[#" << C.Text << "#]";
616 break;
617
618 case CodeCompletionString::CK_CurrentParameter:
619 OS << "<#" << C.Text << "#>";
620 break;
621
Kadir Cetinkayaa32d2532018-09-10 13:46:28 +0000622 // FIXME: We can also print optional parameters of an overload.
623 case CodeCompletionString::CK_Optional:
624 break;
625
Francisco Lopes da Silva0c010cd2015-01-28 14:17:22 +0000626 default: OS << C.Text; break;
627 }
628 }
629 return OS.str();
630}
631
Ilya Biryukov2fab2352018-08-30 13:08:03 +0000632void PrintingCodeCompleteConsumer::ProcessOverloadCandidates(
633 Sema &SemaRef, unsigned CurrentArg, OverloadCandidate *Candidates,
634 unsigned NumCandidates, SourceLocation OpenParLoc) {
635 OS << "OPENING_PAREN_LOC: ";
636 OpenParLoc.print(OS, SemaRef.getSourceManager());
637 OS << "\n";
638
Douglas Gregor05f477c2009-09-23 00:16:58 +0000639 for (unsigned I = 0; I != NumCandidates; ++I) {
Ilya Biryukov2fab2352018-08-30 13:08:03 +0000640 if (CodeCompletionString *CCS = Candidates[I].CreateSignatureString(
641 CurrentArg, SemaRef, getAllocator(), CCTUInfo,
642 includeBriefComments())) {
Francisco Lopes da Silva0c010cd2015-01-28 14:17:22 +0000643 OS << "OVERLOAD: " << getOverloadAsString(*CCS) << "\n";
Douglas Gregor05f477c2009-09-23 00:16:58 +0000644 }
645 }
Douglas Gregor05f477c2009-09-23 00:16:58 +0000646}
Douglas Gregor9eb77012009-11-07 00:00:49 +0000647
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000648/// Retrieve the effective availability of the given declaration.
Dmitri Gribenkofe0483d2013-01-23 17:21:11 +0000649static AvailabilityResult getDeclAvailability(const Decl *D) {
Douglas Gregor7b316822012-03-17 06:39:06 +0000650 AvailabilityResult AR = D->getAvailability();
651 if (isa<EnumConstantDecl>(D))
652 AR = std::max(AR, cast<Decl>(D->getDeclContext())->getAvailability());
653 return AR;
654}
655
Erik Verbruggen2e657ff2011-10-06 07:27:49 +0000656void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) {
Douglas Gregorb14904c2010-08-13 22:48:40 +0000657 switch (Kind) {
Douglas Gregor78254c82012-03-27 23:34:16 +0000658 case RK_Pattern:
659 if (!Declaration) {
660 // Do nothing: Patterns can come with cursor kinds!
661 break;
662 }
Adrian Prantlf3b3ccd2017-12-19 22:06:11 +0000663 LLVM_FALLTHROUGH;
Fangrui Song6907ce22018-07-30 19:24:48 +0000664
Douglas Gregor7b316822012-03-17 06:39:06 +0000665 case RK_Declaration: {
Douglas Gregorf757a122010-08-23 23:00:57 +0000666 // Set the availability based on attributes.
Douglas Gregor7b316822012-03-17 06:39:06 +0000667 switch (getDeclAvailability(Declaration)) {
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000668 case AR_Available:
669 case AR_NotYetIntroduced:
Fangrui Song6907ce22018-07-30 19:24:48 +0000670 Availability = CXAvailability_Available;
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000671 break;
Fangrui Song6907ce22018-07-30 19:24:48 +0000672
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000673 case AR_Deprecated:
674 Availability = CXAvailability_Deprecated;
675 break;
Fangrui Song6907ce22018-07-30 19:24:48 +0000676
Douglas Gregor20b2ebd2011-03-23 00:50:03 +0000677 case AR_Unavailable:
678 Availability = CXAvailability_NotAvailable;
679 break;
680 }
681
Eugene Zelenko1e95bc02018-04-05 22:15:42 +0000682 if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Declaration))
Douglas Gregor09c0eb12010-09-03 23:30:36 +0000683 if (Function->isDeleted())
Douglas Gregorf757a122010-08-23 23:00:57 +0000684 Availability = CXAvailability_NotAvailable;
Fangrui Song6907ce22018-07-30 19:24:48 +0000685
Douglas Gregor09c0eb12010-09-03 23:30:36 +0000686 CursorKind = getCursorKindForDecl(Declaration);
Douglas Gregordeafd0b2011-12-27 22:43:10 +0000687 if (CursorKind == CXCursor_UnexposedDecl) {
Fangrui Song6907ce22018-07-30 19:24:48 +0000688 // FIXME: Forward declarations of Objective-C classes and protocols
689 // are not directly exposed, but we want code completion to treat them
Douglas Gregorf6102672012-01-01 21:23:57 +0000690 // like a definition.
Douglas Gregordeafd0b2011-12-27 22:43:10 +0000691 if (isa<ObjCInterfaceDecl>(Declaration))
692 CursorKind = CXCursor_ObjCInterfaceDecl;
Douglas Gregorf6102672012-01-01 21:23:57 +0000693 else if (isa<ObjCProtocolDecl>(Declaration))
694 CursorKind = CXCursor_ObjCProtocolDecl;
Douglas Gregordeafd0b2011-12-27 22:43:10 +0000695 else
696 CursorKind = CXCursor_NotImplemented;
697 }
Douglas Gregorb14904c2010-08-13 22:48:40 +0000698 break;
Douglas Gregor7b316822012-03-17 06:39:06 +0000699 }
Douglas Gregorb14904c2010-08-13 22:48:40 +0000700
John McCall276321a2010-08-25 06:19:51 +0000701 case RK_Macro:
John McCall276321a2010-08-25 06:19:51 +0000702 case RK_Keyword:
Benjamin Kramerc25c0b92012-05-20 14:19:46 +0000703 llvm_unreachable("Macro and keyword kinds are handled by the constructors");
Douglas Gregor8e984da2010-08-04 16:47:14 +0000704 }
Erik Verbruggen2e657ff2011-10-06 07:27:49 +0000705
706 if (!Accessible)
707 Availability = CXAvailability_NotAccessible;
Douglas Gregor8e984da2010-08-04 16:47:14 +0000708}
Douglas Gregorf09935f2009-12-01 05:55:20 +0000709
Adrian Prantl9fc8faf2018-05-09 01:00:01 +0000710/// Retrieve the name that should be used to order a result.
Douglas Gregor0de55ce2010-08-25 18:41:16 +0000711///
712/// If the name needs to be constructed as a string, that string will be
713/// saved into Saved and the returned StringRef will refer to it.
Sam McCall1102a862017-11-15 09:15:06 +0000714StringRef CodeCompletionResult::getOrderedName(std::string &Saved) const {
715 switch (Kind) {
716 case RK_Keyword:
717 return Keyword;
718 case RK_Pattern:
719 return Pattern->getTypedText();
720 case RK_Macro:
721 return Macro->getName();
722 case RK_Declaration:
Douglas Gregor0de55ce2010-08-25 18:41:16 +0000723 // Handle declarations below.
724 break;
725 }
Fangrui Song6907ce22018-07-30 19:24:48 +0000726
Sam McCall1102a862017-11-15 09:15:06 +0000727 DeclarationName Name = Declaration->getDeclName();
Fangrui Song6907ce22018-07-30 19:24:48 +0000728
Douglas Gregor0de55ce2010-08-25 18:41:16 +0000729 // If the name is a simple identifier (by far the common case), or a
730 // zero-argument selector, just return a reference to that identifier.
731 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
732 return Id->getName();
733 if (Name.isObjCZeroArgSelector())
734 if (IdentifierInfo *Id
735 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
736 return Id->getName();
Fangrui Song6907ce22018-07-30 19:24:48 +0000737
Douglas Gregor0de55ce2010-08-25 18:41:16 +0000738 Saved = Name.getAsString();
739 return Saved;
740}
Fangrui Song6907ce22018-07-30 19:24:48 +0000741
742bool clang::operator<(const CodeCompletionResult &X,
Douglas Gregor0de55ce2010-08-25 18:41:16 +0000743 const CodeCompletionResult &Y) {
744 std::string XSaved, YSaved;
Sam McCall1102a862017-11-15 09:15:06 +0000745 StringRef XStr = X.getOrderedName(XSaved);
746 StringRef YStr = Y.getOrderedName(YSaved);
Douglas Gregor0de55ce2010-08-25 18:41:16 +0000747 int cmp = XStr.compare_lower(YStr);
748 if (cmp)
749 return cmp < 0;
Fangrui Song6907ce22018-07-30 19:24:48 +0000750
Douglas Gregor49f67ce2010-08-26 13:48:20 +0000751 // If case-insensitive comparison fails, try case-sensitive comparison.
752 cmp = XStr.compare(YStr);
753 if (cmp)
754 return cmp < 0;
Fangrui Song6907ce22018-07-30 19:24:48 +0000755
Douglas Gregor0de55ce2010-08-25 18:41:16 +0000756 return false;
757}