1f4a2713aSLionel Sambuc //===--- CodeCompleteConsumer.cpp - Code Completion Interface ---*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc // The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc // This file implements the CodeCompleteConsumer class.
11f4a2713aSLionel Sambuc //
12f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
13f4a2713aSLionel Sambuc #include "clang/Sema/CodeCompleteConsumer.h"
14f4a2713aSLionel Sambuc #include "clang-c/Index.h"
15f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
16f4a2713aSLionel Sambuc #include "clang/AST/DeclObjC.h"
17f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h"
18f4a2713aSLionel Sambuc #include "clang/Sema/Scope.h"
19f4a2713aSLionel Sambuc #include "clang/Sema/Sema.h"
20f4a2713aSLionel Sambuc #include "llvm/ADT/STLExtras.h"
21f4a2713aSLionel Sambuc #include "llvm/ADT/SmallString.h"
22f4a2713aSLionel Sambuc #include "llvm/ADT/Twine.h"
23f4a2713aSLionel Sambuc #include "llvm/Support/raw_ostream.h"
24f4a2713aSLionel Sambuc #include <algorithm>
25f4a2713aSLionel Sambuc #include <cstring>
26f4a2713aSLionel Sambuc #include <functional>
27f4a2713aSLionel Sambuc
28f4a2713aSLionel Sambuc using namespace clang;
29f4a2713aSLionel Sambuc
30f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
31f4a2713aSLionel Sambuc // Code completion context implementation
32f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
33f4a2713aSLionel Sambuc
wantConstructorResults() const34f4a2713aSLionel Sambuc bool CodeCompletionContext::wantConstructorResults() const {
35f4a2713aSLionel Sambuc switch (Kind) {
36f4a2713aSLionel Sambuc case CCC_Recovery:
37f4a2713aSLionel Sambuc case CCC_Statement:
38f4a2713aSLionel Sambuc case CCC_Expression:
39f4a2713aSLionel Sambuc case CCC_ObjCMessageReceiver:
40f4a2713aSLionel Sambuc case CCC_ParenthesizedExpression:
41f4a2713aSLionel Sambuc return true;
42f4a2713aSLionel Sambuc
43f4a2713aSLionel Sambuc case CCC_TopLevel:
44f4a2713aSLionel Sambuc case CCC_ObjCInterface:
45f4a2713aSLionel Sambuc case CCC_ObjCImplementation:
46f4a2713aSLionel Sambuc case CCC_ObjCIvarList:
47f4a2713aSLionel Sambuc case CCC_ClassStructUnion:
48f4a2713aSLionel Sambuc case CCC_DotMemberAccess:
49f4a2713aSLionel Sambuc case CCC_ArrowMemberAccess:
50f4a2713aSLionel Sambuc case CCC_ObjCPropertyAccess:
51f4a2713aSLionel Sambuc case CCC_EnumTag:
52f4a2713aSLionel Sambuc case CCC_UnionTag:
53f4a2713aSLionel Sambuc case CCC_ClassOrStructTag:
54f4a2713aSLionel Sambuc case CCC_ObjCProtocolName:
55f4a2713aSLionel Sambuc case CCC_Namespace:
56f4a2713aSLionel Sambuc case CCC_Type:
57f4a2713aSLionel Sambuc case CCC_Name:
58f4a2713aSLionel Sambuc case CCC_PotentiallyQualifiedName:
59f4a2713aSLionel Sambuc case CCC_MacroName:
60f4a2713aSLionel Sambuc case CCC_MacroNameUse:
61f4a2713aSLionel Sambuc case CCC_PreprocessorExpression:
62f4a2713aSLionel Sambuc case CCC_PreprocessorDirective:
63f4a2713aSLionel Sambuc case CCC_NaturalLanguage:
64f4a2713aSLionel Sambuc case CCC_SelectorName:
65f4a2713aSLionel Sambuc case CCC_TypeQualifiers:
66f4a2713aSLionel Sambuc case CCC_Other:
67f4a2713aSLionel Sambuc case CCC_OtherWithMacros:
68f4a2713aSLionel Sambuc case CCC_ObjCInstanceMessage:
69f4a2713aSLionel Sambuc case CCC_ObjCClassMessage:
70f4a2713aSLionel Sambuc case CCC_ObjCInterfaceName:
71f4a2713aSLionel Sambuc case CCC_ObjCCategoryName:
72f4a2713aSLionel Sambuc return false;
73f4a2713aSLionel Sambuc }
74f4a2713aSLionel Sambuc
75f4a2713aSLionel Sambuc llvm_unreachable("Invalid CodeCompletionContext::Kind!");
76f4a2713aSLionel Sambuc }
77f4a2713aSLionel Sambuc
78f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
79f4a2713aSLionel Sambuc // Code completion string implementation
80f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
Chunk(ChunkKind Kind,const char * Text)81f4a2713aSLionel Sambuc CodeCompletionString::Chunk::Chunk(ChunkKind Kind, const char *Text)
82f4a2713aSLionel Sambuc : Kind(Kind), Text("")
83f4a2713aSLionel Sambuc {
84f4a2713aSLionel Sambuc switch (Kind) {
85f4a2713aSLionel Sambuc case CK_TypedText:
86f4a2713aSLionel Sambuc case CK_Text:
87f4a2713aSLionel Sambuc case CK_Placeholder:
88f4a2713aSLionel Sambuc case CK_Informative:
89f4a2713aSLionel Sambuc case CK_ResultType:
90f4a2713aSLionel Sambuc case CK_CurrentParameter:
91f4a2713aSLionel Sambuc this->Text = Text;
92f4a2713aSLionel Sambuc break;
93f4a2713aSLionel Sambuc
94f4a2713aSLionel Sambuc case CK_Optional:
95f4a2713aSLionel Sambuc llvm_unreachable("Optional strings cannot be created from text");
96f4a2713aSLionel Sambuc
97f4a2713aSLionel Sambuc case CK_LeftParen:
98f4a2713aSLionel Sambuc this->Text = "(";
99f4a2713aSLionel Sambuc break;
100f4a2713aSLionel Sambuc
101f4a2713aSLionel Sambuc case CK_RightParen:
102f4a2713aSLionel Sambuc this->Text = ")";
103f4a2713aSLionel Sambuc break;
104f4a2713aSLionel Sambuc
105f4a2713aSLionel Sambuc case CK_LeftBracket:
106f4a2713aSLionel Sambuc this->Text = "[";
107f4a2713aSLionel Sambuc break;
108f4a2713aSLionel Sambuc
109f4a2713aSLionel Sambuc case CK_RightBracket:
110f4a2713aSLionel Sambuc this->Text = "]";
111f4a2713aSLionel Sambuc break;
112f4a2713aSLionel Sambuc
113f4a2713aSLionel Sambuc case CK_LeftBrace:
114f4a2713aSLionel Sambuc this->Text = "{";
115f4a2713aSLionel Sambuc break;
116f4a2713aSLionel Sambuc
117f4a2713aSLionel Sambuc case CK_RightBrace:
118f4a2713aSLionel Sambuc this->Text = "}";
119f4a2713aSLionel Sambuc break;
120f4a2713aSLionel Sambuc
121f4a2713aSLionel Sambuc case CK_LeftAngle:
122f4a2713aSLionel Sambuc this->Text = "<";
123f4a2713aSLionel Sambuc break;
124f4a2713aSLionel Sambuc
125f4a2713aSLionel Sambuc case CK_RightAngle:
126f4a2713aSLionel Sambuc this->Text = ">";
127f4a2713aSLionel Sambuc break;
128f4a2713aSLionel Sambuc
129f4a2713aSLionel Sambuc case CK_Comma:
130f4a2713aSLionel Sambuc this->Text = ", ";
131f4a2713aSLionel Sambuc break;
132f4a2713aSLionel Sambuc
133f4a2713aSLionel Sambuc case CK_Colon:
134f4a2713aSLionel Sambuc this->Text = ":";
135f4a2713aSLionel Sambuc break;
136f4a2713aSLionel Sambuc
137f4a2713aSLionel Sambuc case CK_SemiColon:
138f4a2713aSLionel Sambuc this->Text = ";";
139f4a2713aSLionel Sambuc break;
140f4a2713aSLionel Sambuc
141f4a2713aSLionel Sambuc case CK_Equal:
142f4a2713aSLionel Sambuc this->Text = " = ";
143f4a2713aSLionel Sambuc break;
144f4a2713aSLionel Sambuc
145f4a2713aSLionel Sambuc case CK_HorizontalSpace:
146f4a2713aSLionel Sambuc this->Text = " ";
147f4a2713aSLionel Sambuc break;
148f4a2713aSLionel Sambuc
149f4a2713aSLionel Sambuc case CK_VerticalSpace:
150f4a2713aSLionel Sambuc this->Text = "\n";
151f4a2713aSLionel Sambuc break;
152f4a2713aSLionel Sambuc }
153f4a2713aSLionel Sambuc }
154f4a2713aSLionel Sambuc
155f4a2713aSLionel Sambuc CodeCompletionString::Chunk
CreateText(const char * Text)156f4a2713aSLionel Sambuc CodeCompletionString::Chunk::CreateText(const char *Text) {
157f4a2713aSLionel Sambuc return Chunk(CK_Text, Text);
158f4a2713aSLionel Sambuc }
159f4a2713aSLionel Sambuc
160f4a2713aSLionel Sambuc CodeCompletionString::Chunk
CreateOptional(CodeCompletionString * Optional)161f4a2713aSLionel Sambuc CodeCompletionString::Chunk::CreateOptional(CodeCompletionString *Optional) {
162f4a2713aSLionel Sambuc Chunk Result;
163f4a2713aSLionel Sambuc Result.Kind = CK_Optional;
164f4a2713aSLionel Sambuc Result.Optional = Optional;
165f4a2713aSLionel Sambuc return Result;
166f4a2713aSLionel Sambuc }
167f4a2713aSLionel Sambuc
168f4a2713aSLionel Sambuc CodeCompletionString::Chunk
CreatePlaceholder(const char * Placeholder)169f4a2713aSLionel Sambuc CodeCompletionString::Chunk::CreatePlaceholder(const char *Placeholder) {
170f4a2713aSLionel Sambuc return Chunk(CK_Placeholder, Placeholder);
171f4a2713aSLionel Sambuc }
172f4a2713aSLionel Sambuc
173f4a2713aSLionel Sambuc CodeCompletionString::Chunk
CreateInformative(const char * Informative)174f4a2713aSLionel Sambuc CodeCompletionString::Chunk::CreateInformative(const char *Informative) {
175f4a2713aSLionel Sambuc return Chunk(CK_Informative, Informative);
176f4a2713aSLionel Sambuc }
177f4a2713aSLionel Sambuc
178f4a2713aSLionel Sambuc CodeCompletionString::Chunk
CreateResultType(const char * ResultType)179f4a2713aSLionel Sambuc CodeCompletionString::Chunk::CreateResultType(const char *ResultType) {
180f4a2713aSLionel Sambuc return Chunk(CK_ResultType, ResultType);
181f4a2713aSLionel Sambuc }
182f4a2713aSLionel Sambuc
183f4a2713aSLionel Sambuc CodeCompletionString::Chunk
CreateCurrentParameter(const char * CurrentParameter)184f4a2713aSLionel Sambuc CodeCompletionString::Chunk::CreateCurrentParameter(
185f4a2713aSLionel Sambuc const char *CurrentParameter) {
186f4a2713aSLionel Sambuc return Chunk(CK_CurrentParameter, CurrentParameter);
187f4a2713aSLionel Sambuc }
188f4a2713aSLionel Sambuc
CodeCompletionString(const Chunk * Chunks,unsigned NumChunks,unsigned Priority,CXAvailabilityKind Availability,const char ** Annotations,unsigned NumAnnotations,StringRef ParentName,const char * BriefComment)189f4a2713aSLionel Sambuc CodeCompletionString::CodeCompletionString(const Chunk *Chunks,
190f4a2713aSLionel Sambuc unsigned NumChunks,
191f4a2713aSLionel Sambuc unsigned Priority,
192f4a2713aSLionel Sambuc CXAvailabilityKind Availability,
193f4a2713aSLionel Sambuc const char **Annotations,
194f4a2713aSLionel Sambuc unsigned NumAnnotations,
195f4a2713aSLionel Sambuc StringRef ParentName,
196f4a2713aSLionel Sambuc const char *BriefComment)
197f4a2713aSLionel Sambuc : NumChunks(NumChunks), NumAnnotations(NumAnnotations),
198f4a2713aSLionel Sambuc Priority(Priority), Availability(Availability),
199f4a2713aSLionel Sambuc ParentName(ParentName), BriefComment(BriefComment)
200f4a2713aSLionel Sambuc {
201f4a2713aSLionel Sambuc assert(NumChunks <= 0xffff);
202f4a2713aSLionel Sambuc assert(NumAnnotations <= 0xffff);
203f4a2713aSLionel Sambuc
204f4a2713aSLionel Sambuc Chunk *StoredChunks = reinterpret_cast<Chunk *>(this + 1);
205f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumChunks; ++I)
206f4a2713aSLionel Sambuc StoredChunks[I] = Chunks[I];
207f4a2713aSLionel Sambuc
208f4a2713aSLionel Sambuc const char **StoredAnnotations = reinterpret_cast<const char **>(StoredChunks + NumChunks);
209f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumAnnotations; ++I)
210f4a2713aSLionel Sambuc StoredAnnotations[I] = Annotations[I];
211f4a2713aSLionel Sambuc }
212f4a2713aSLionel Sambuc
getAnnotationCount() const213f4a2713aSLionel Sambuc unsigned CodeCompletionString::getAnnotationCount() const {
214f4a2713aSLionel Sambuc return NumAnnotations;
215f4a2713aSLionel Sambuc }
216f4a2713aSLionel Sambuc
getAnnotation(unsigned AnnotationNr) const217f4a2713aSLionel Sambuc const char *CodeCompletionString::getAnnotation(unsigned AnnotationNr) const {
218f4a2713aSLionel Sambuc if (AnnotationNr < NumAnnotations)
219f4a2713aSLionel Sambuc return reinterpret_cast<const char * const*>(end())[AnnotationNr];
220f4a2713aSLionel Sambuc else
221*0a6a1f1dSLionel Sambuc return nullptr;
222f4a2713aSLionel Sambuc }
223f4a2713aSLionel Sambuc
224f4a2713aSLionel Sambuc
getAsString() const225f4a2713aSLionel Sambuc std::string CodeCompletionString::getAsString() const {
226f4a2713aSLionel Sambuc std::string Result;
227f4a2713aSLionel Sambuc llvm::raw_string_ostream OS(Result);
228f4a2713aSLionel Sambuc
229f4a2713aSLionel Sambuc for (iterator C = begin(), CEnd = end(); C != CEnd; ++C) {
230f4a2713aSLionel Sambuc switch (C->Kind) {
231f4a2713aSLionel Sambuc case CK_Optional: OS << "{#" << C->Optional->getAsString() << "#}"; break;
232f4a2713aSLionel Sambuc case CK_Placeholder: OS << "<#" << C->Text << "#>"; break;
233f4a2713aSLionel Sambuc
234f4a2713aSLionel Sambuc case CK_Informative:
235f4a2713aSLionel Sambuc case CK_ResultType:
236f4a2713aSLionel Sambuc OS << "[#" << C->Text << "#]";
237f4a2713aSLionel Sambuc break;
238f4a2713aSLionel Sambuc
239f4a2713aSLionel Sambuc case CK_CurrentParameter: OS << "<#" << C->Text << "#>"; break;
240f4a2713aSLionel Sambuc default: OS << C->Text; break;
241f4a2713aSLionel Sambuc }
242f4a2713aSLionel Sambuc }
243f4a2713aSLionel Sambuc return OS.str();
244f4a2713aSLionel Sambuc }
245f4a2713aSLionel Sambuc
getTypedText() const246f4a2713aSLionel Sambuc const char *CodeCompletionString::getTypedText() const {
247f4a2713aSLionel Sambuc for (iterator C = begin(), CEnd = end(); C != CEnd; ++C)
248f4a2713aSLionel Sambuc if (C->Kind == CK_TypedText)
249f4a2713aSLionel Sambuc return C->Text;
250f4a2713aSLionel Sambuc
251*0a6a1f1dSLionel Sambuc return nullptr;
252f4a2713aSLionel Sambuc }
253f4a2713aSLionel Sambuc
CopyString(StringRef String)254f4a2713aSLionel Sambuc const char *CodeCompletionAllocator::CopyString(StringRef String) {
255f4a2713aSLionel Sambuc char *Mem = (char *)Allocate(String.size() + 1, 1);
256f4a2713aSLionel Sambuc std::copy(String.begin(), String.end(), Mem);
257f4a2713aSLionel Sambuc Mem[String.size()] = 0;
258f4a2713aSLionel Sambuc return Mem;
259f4a2713aSLionel Sambuc }
260f4a2713aSLionel Sambuc
CopyString(Twine String)261f4a2713aSLionel Sambuc const char *CodeCompletionAllocator::CopyString(Twine String) {
262f4a2713aSLionel Sambuc // FIXME: It would be more efficient to teach Twine to tell us its size and
263f4a2713aSLionel Sambuc // then add a routine there to fill in an allocated char* with the contents
264f4a2713aSLionel Sambuc // of the string.
265f4a2713aSLionel Sambuc SmallString<128> Data;
266f4a2713aSLionel Sambuc return CopyString(String.toStringRef(Data));
267f4a2713aSLionel Sambuc }
268f4a2713aSLionel Sambuc
getParentName(const DeclContext * DC)269f4a2713aSLionel Sambuc StringRef CodeCompletionTUInfo::getParentName(const DeclContext *DC) {
270f4a2713aSLionel Sambuc const NamedDecl *ND = dyn_cast<NamedDecl>(DC);
271f4a2713aSLionel Sambuc if (!ND)
272f4a2713aSLionel Sambuc return StringRef();
273f4a2713aSLionel Sambuc
274f4a2713aSLionel Sambuc // Check whether we've already cached the parent name.
275f4a2713aSLionel Sambuc StringRef &CachedParentName = ParentNames[DC];
276f4a2713aSLionel Sambuc if (!CachedParentName.empty())
277f4a2713aSLionel Sambuc return CachedParentName;
278f4a2713aSLionel Sambuc
279f4a2713aSLionel Sambuc // If we already processed this DeclContext and assigned empty to it, the
280f4a2713aSLionel Sambuc // data pointer will be non-null.
281*0a6a1f1dSLionel Sambuc if (CachedParentName.data() != nullptr)
282f4a2713aSLionel Sambuc return StringRef();
283f4a2713aSLionel Sambuc
284f4a2713aSLionel Sambuc // Find the interesting names.
285f4a2713aSLionel Sambuc SmallVector<const DeclContext *, 2> Contexts;
286f4a2713aSLionel Sambuc while (DC && !DC->isFunctionOrMethod()) {
287f4a2713aSLionel Sambuc if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC)) {
288f4a2713aSLionel Sambuc if (ND->getIdentifier())
289f4a2713aSLionel Sambuc Contexts.push_back(DC);
290f4a2713aSLionel Sambuc }
291f4a2713aSLionel Sambuc
292f4a2713aSLionel Sambuc DC = DC->getParent();
293f4a2713aSLionel Sambuc }
294f4a2713aSLionel Sambuc
295f4a2713aSLionel Sambuc {
296f4a2713aSLionel Sambuc SmallString<128> S;
297f4a2713aSLionel Sambuc llvm::raw_svector_ostream OS(S);
298f4a2713aSLionel Sambuc bool First = true;
299f4a2713aSLionel Sambuc for (unsigned I = Contexts.size(); I != 0; --I) {
300f4a2713aSLionel Sambuc if (First)
301f4a2713aSLionel Sambuc First = false;
302f4a2713aSLionel Sambuc else {
303f4a2713aSLionel Sambuc OS << "::";
304f4a2713aSLionel Sambuc }
305f4a2713aSLionel Sambuc
306f4a2713aSLionel Sambuc const DeclContext *CurDC = Contexts[I-1];
307f4a2713aSLionel Sambuc if (const ObjCCategoryImplDecl *CatImpl = dyn_cast<ObjCCategoryImplDecl>(CurDC))
308f4a2713aSLionel Sambuc CurDC = CatImpl->getCategoryDecl();
309f4a2713aSLionel Sambuc
310f4a2713aSLionel Sambuc if (const ObjCCategoryDecl *Cat = dyn_cast<ObjCCategoryDecl>(CurDC)) {
311f4a2713aSLionel Sambuc const ObjCInterfaceDecl *Interface = Cat->getClassInterface();
312f4a2713aSLionel Sambuc if (!Interface) {
313f4a2713aSLionel Sambuc // Assign an empty StringRef but with non-null data to distinguish
314f4a2713aSLionel Sambuc // between empty because we didn't process the DeclContext yet.
315f4a2713aSLionel Sambuc CachedParentName = StringRef((const char *)~0U, 0);
316f4a2713aSLionel Sambuc return StringRef();
317f4a2713aSLionel Sambuc }
318f4a2713aSLionel Sambuc
319f4a2713aSLionel Sambuc OS << Interface->getName() << '(' << Cat->getName() << ')';
320f4a2713aSLionel Sambuc } else {
321f4a2713aSLionel Sambuc OS << cast<NamedDecl>(CurDC)->getName();
322f4a2713aSLionel Sambuc }
323f4a2713aSLionel Sambuc }
324f4a2713aSLionel Sambuc
325f4a2713aSLionel Sambuc CachedParentName = AllocatorRef->CopyString(OS.str());
326f4a2713aSLionel Sambuc }
327f4a2713aSLionel Sambuc
328f4a2713aSLionel Sambuc return CachedParentName;
329f4a2713aSLionel Sambuc }
330f4a2713aSLionel Sambuc
TakeString()331f4a2713aSLionel Sambuc CodeCompletionString *CodeCompletionBuilder::TakeString() {
332f4a2713aSLionel Sambuc void *Mem = getAllocator().Allocate(
333f4a2713aSLionel Sambuc sizeof(CodeCompletionString) + sizeof(Chunk) * Chunks.size()
334f4a2713aSLionel Sambuc + sizeof(const char *) * Annotations.size(),
335f4a2713aSLionel Sambuc llvm::alignOf<CodeCompletionString>());
336f4a2713aSLionel Sambuc CodeCompletionString *Result
337f4a2713aSLionel Sambuc = new (Mem) CodeCompletionString(Chunks.data(), Chunks.size(),
338f4a2713aSLionel Sambuc Priority, Availability,
339f4a2713aSLionel Sambuc Annotations.data(), Annotations.size(),
340f4a2713aSLionel Sambuc ParentName, BriefComment);
341f4a2713aSLionel Sambuc Chunks.clear();
342f4a2713aSLionel Sambuc return Result;
343f4a2713aSLionel Sambuc }
344f4a2713aSLionel Sambuc
AddTypedTextChunk(const char * Text)345f4a2713aSLionel Sambuc void CodeCompletionBuilder::AddTypedTextChunk(const char *Text) {
346f4a2713aSLionel Sambuc Chunks.push_back(Chunk(CodeCompletionString::CK_TypedText, Text));
347f4a2713aSLionel Sambuc }
348f4a2713aSLionel Sambuc
AddTextChunk(const char * Text)349f4a2713aSLionel Sambuc void CodeCompletionBuilder::AddTextChunk(const char *Text) {
350f4a2713aSLionel Sambuc Chunks.push_back(Chunk::CreateText(Text));
351f4a2713aSLionel Sambuc }
352f4a2713aSLionel Sambuc
AddOptionalChunk(CodeCompletionString * Optional)353f4a2713aSLionel Sambuc void CodeCompletionBuilder::AddOptionalChunk(CodeCompletionString *Optional) {
354f4a2713aSLionel Sambuc Chunks.push_back(Chunk::CreateOptional(Optional));
355f4a2713aSLionel Sambuc }
356f4a2713aSLionel Sambuc
AddPlaceholderChunk(const char * Placeholder)357f4a2713aSLionel Sambuc void CodeCompletionBuilder::AddPlaceholderChunk(const char *Placeholder) {
358f4a2713aSLionel Sambuc Chunks.push_back(Chunk::CreatePlaceholder(Placeholder));
359f4a2713aSLionel Sambuc }
360f4a2713aSLionel Sambuc
AddInformativeChunk(const char * Text)361f4a2713aSLionel Sambuc void CodeCompletionBuilder::AddInformativeChunk(const char *Text) {
362f4a2713aSLionel Sambuc Chunks.push_back(Chunk::CreateInformative(Text));
363f4a2713aSLionel Sambuc }
364f4a2713aSLionel Sambuc
AddResultTypeChunk(const char * ResultType)365f4a2713aSLionel Sambuc void CodeCompletionBuilder::AddResultTypeChunk(const char *ResultType) {
366f4a2713aSLionel Sambuc Chunks.push_back(Chunk::CreateResultType(ResultType));
367f4a2713aSLionel Sambuc }
368f4a2713aSLionel Sambuc
369f4a2713aSLionel Sambuc void
AddCurrentParameterChunk(const char * CurrentParameter)370f4a2713aSLionel Sambuc CodeCompletionBuilder::AddCurrentParameterChunk(const char *CurrentParameter) {
371f4a2713aSLionel Sambuc Chunks.push_back(Chunk::CreateCurrentParameter(CurrentParameter));
372f4a2713aSLionel Sambuc }
373f4a2713aSLionel Sambuc
AddChunk(CodeCompletionString::ChunkKind CK,const char * Text)374f4a2713aSLionel Sambuc void CodeCompletionBuilder::AddChunk(CodeCompletionString::ChunkKind CK,
375f4a2713aSLionel Sambuc const char *Text) {
376f4a2713aSLionel Sambuc Chunks.push_back(Chunk(CK, Text));
377f4a2713aSLionel Sambuc }
378f4a2713aSLionel Sambuc
addParentContext(const DeclContext * DC)379f4a2713aSLionel Sambuc void CodeCompletionBuilder::addParentContext(const DeclContext *DC) {
380f4a2713aSLionel Sambuc if (DC->isTranslationUnit()) {
381f4a2713aSLionel Sambuc return;
382f4a2713aSLionel Sambuc }
383f4a2713aSLionel Sambuc
384f4a2713aSLionel Sambuc if (DC->isFunctionOrMethod())
385f4a2713aSLionel Sambuc return;
386f4a2713aSLionel Sambuc
387f4a2713aSLionel Sambuc const NamedDecl *ND = dyn_cast<NamedDecl>(DC);
388f4a2713aSLionel Sambuc if (!ND)
389f4a2713aSLionel Sambuc return;
390f4a2713aSLionel Sambuc
391f4a2713aSLionel Sambuc ParentName = getCodeCompletionTUInfo().getParentName(DC);
392f4a2713aSLionel Sambuc }
393f4a2713aSLionel Sambuc
addBriefComment(StringRef Comment)394f4a2713aSLionel Sambuc void CodeCompletionBuilder::addBriefComment(StringRef Comment) {
395f4a2713aSLionel Sambuc BriefComment = Allocator.CopyString(Comment);
396f4a2713aSLionel Sambuc }
397f4a2713aSLionel Sambuc
398f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
399f4a2713aSLionel Sambuc // Code completion overload candidate implementation
400f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
401f4a2713aSLionel Sambuc FunctionDecl *
getFunction() const402f4a2713aSLionel Sambuc CodeCompleteConsumer::OverloadCandidate::getFunction() const {
403f4a2713aSLionel Sambuc if (getKind() == CK_Function)
404f4a2713aSLionel Sambuc return Function;
405f4a2713aSLionel Sambuc else if (getKind() == CK_FunctionTemplate)
406f4a2713aSLionel Sambuc return FunctionTemplate->getTemplatedDecl();
407f4a2713aSLionel Sambuc else
408*0a6a1f1dSLionel Sambuc return nullptr;
409f4a2713aSLionel Sambuc }
410f4a2713aSLionel Sambuc
411f4a2713aSLionel Sambuc const FunctionType *
getFunctionType() const412f4a2713aSLionel Sambuc CodeCompleteConsumer::OverloadCandidate::getFunctionType() const {
413f4a2713aSLionel Sambuc switch (Kind) {
414f4a2713aSLionel Sambuc case CK_Function:
415f4a2713aSLionel Sambuc return Function->getType()->getAs<FunctionType>();
416f4a2713aSLionel Sambuc
417f4a2713aSLionel Sambuc case CK_FunctionTemplate:
418f4a2713aSLionel Sambuc return FunctionTemplate->getTemplatedDecl()->getType()
419f4a2713aSLionel Sambuc ->getAs<FunctionType>();
420f4a2713aSLionel Sambuc
421f4a2713aSLionel Sambuc case CK_FunctionType:
422f4a2713aSLionel Sambuc return Type;
423f4a2713aSLionel Sambuc }
424f4a2713aSLionel Sambuc
425f4a2713aSLionel Sambuc llvm_unreachable("Invalid CandidateKind!");
426f4a2713aSLionel Sambuc }
427f4a2713aSLionel Sambuc
428f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
429f4a2713aSLionel Sambuc // Code completion consumer implementation
430f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
431f4a2713aSLionel Sambuc
~CodeCompleteConsumer()432f4a2713aSLionel Sambuc CodeCompleteConsumer::~CodeCompleteConsumer() { }
433f4a2713aSLionel Sambuc
434f4a2713aSLionel Sambuc void
ProcessCodeCompleteResults(Sema & SemaRef,CodeCompletionContext Context,CodeCompletionResult * Results,unsigned NumResults)435f4a2713aSLionel Sambuc PrintingCodeCompleteConsumer::ProcessCodeCompleteResults(Sema &SemaRef,
436f4a2713aSLionel Sambuc CodeCompletionContext Context,
437f4a2713aSLionel Sambuc CodeCompletionResult *Results,
438f4a2713aSLionel Sambuc unsigned NumResults) {
439f4a2713aSLionel Sambuc std::stable_sort(Results, Results + NumResults);
440f4a2713aSLionel Sambuc
441f4a2713aSLionel Sambuc // Print the results.
442f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumResults; ++I) {
443f4a2713aSLionel Sambuc OS << "COMPLETION: ";
444f4a2713aSLionel Sambuc switch (Results[I].Kind) {
445f4a2713aSLionel Sambuc case CodeCompletionResult::RK_Declaration:
446f4a2713aSLionel Sambuc OS << *Results[I].Declaration;
447f4a2713aSLionel Sambuc if (Results[I].Hidden)
448f4a2713aSLionel Sambuc OS << " (Hidden)";
449f4a2713aSLionel Sambuc if (CodeCompletionString *CCS
450f4a2713aSLionel Sambuc = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
451f4a2713aSLionel Sambuc CCTUInfo,
452f4a2713aSLionel Sambuc includeBriefComments())) {
453f4a2713aSLionel Sambuc OS << " : " << CCS->getAsString();
454f4a2713aSLionel Sambuc if (const char *BriefComment = CCS->getBriefComment())
455f4a2713aSLionel Sambuc OS << " : " << BriefComment;
456f4a2713aSLionel Sambuc }
457f4a2713aSLionel Sambuc
458f4a2713aSLionel Sambuc OS << '\n';
459f4a2713aSLionel Sambuc break;
460f4a2713aSLionel Sambuc
461f4a2713aSLionel Sambuc case CodeCompletionResult::RK_Keyword:
462f4a2713aSLionel Sambuc OS << Results[I].Keyword << '\n';
463f4a2713aSLionel Sambuc break;
464f4a2713aSLionel Sambuc
465f4a2713aSLionel Sambuc case CodeCompletionResult::RK_Macro: {
466f4a2713aSLionel Sambuc OS << Results[I].Macro->getName();
467f4a2713aSLionel Sambuc if (CodeCompletionString *CCS
468f4a2713aSLionel Sambuc = Results[I].CreateCodeCompletionString(SemaRef, getAllocator(),
469f4a2713aSLionel Sambuc CCTUInfo,
470f4a2713aSLionel Sambuc includeBriefComments())) {
471f4a2713aSLionel Sambuc OS << " : " << CCS->getAsString();
472f4a2713aSLionel Sambuc }
473f4a2713aSLionel Sambuc OS << '\n';
474f4a2713aSLionel Sambuc break;
475f4a2713aSLionel Sambuc }
476f4a2713aSLionel Sambuc
477f4a2713aSLionel Sambuc case CodeCompletionResult::RK_Pattern: {
478f4a2713aSLionel Sambuc OS << "Pattern : "
479f4a2713aSLionel Sambuc << Results[I].Pattern->getAsString() << '\n';
480f4a2713aSLionel Sambuc break;
481f4a2713aSLionel Sambuc }
482f4a2713aSLionel Sambuc }
483f4a2713aSLionel Sambuc }
484f4a2713aSLionel Sambuc }
485f4a2713aSLionel Sambuc
486f4a2713aSLionel Sambuc void
ProcessOverloadCandidates(Sema & SemaRef,unsigned CurrentArg,OverloadCandidate * Candidates,unsigned NumCandidates)487f4a2713aSLionel Sambuc PrintingCodeCompleteConsumer::ProcessOverloadCandidates(Sema &SemaRef,
488f4a2713aSLionel Sambuc unsigned CurrentArg,
489f4a2713aSLionel Sambuc OverloadCandidate *Candidates,
490f4a2713aSLionel Sambuc unsigned NumCandidates) {
491f4a2713aSLionel Sambuc for (unsigned I = 0; I != NumCandidates; ++I) {
492f4a2713aSLionel Sambuc if (CodeCompletionString *CCS
493f4a2713aSLionel Sambuc = Candidates[I].CreateSignatureString(CurrentArg, SemaRef,
494f4a2713aSLionel Sambuc getAllocator(), CCTUInfo)) {
495f4a2713aSLionel Sambuc OS << "OVERLOAD: " << CCS->getAsString() << "\n";
496f4a2713aSLionel Sambuc }
497f4a2713aSLionel Sambuc }
498f4a2713aSLionel Sambuc }
499f4a2713aSLionel Sambuc
500f4a2713aSLionel Sambuc /// \brief Retrieve the effective availability of the given declaration.
getDeclAvailability(const Decl * D)501f4a2713aSLionel Sambuc static AvailabilityResult getDeclAvailability(const Decl *D) {
502f4a2713aSLionel Sambuc AvailabilityResult AR = D->getAvailability();
503f4a2713aSLionel Sambuc if (isa<EnumConstantDecl>(D))
504f4a2713aSLionel Sambuc AR = std::max(AR, cast<Decl>(D->getDeclContext())->getAvailability());
505f4a2713aSLionel Sambuc return AR;
506f4a2713aSLionel Sambuc }
507f4a2713aSLionel Sambuc
computeCursorKindAndAvailability(bool Accessible)508f4a2713aSLionel Sambuc void CodeCompletionResult::computeCursorKindAndAvailability(bool Accessible) {
509f4a2713aSLionel Sambuc switch (Kind) {
510f4a2713aSLionel Sambuc case RK_Pattern:
511f4a2713aSLionel Sambuc if (!Declaration) {
512f4a2713aSLionel Sambuc // Do nothing: Patterns can come with cursor kinds!
513f4a2713aSLionel Sambuc break;
514f4a2713aSLionel Sambuc }
515f4a2713aSLionel Sambuc // Fall through
516f4a2713aSLionel Sambuc
517f4a2713aSLionel Sambuc case RK_Declaration: {
518f4a2713aSLionel Sambuc // Set the availability based on attributes.
519f4a2713aSLionel Sambuc switch (getDeclAvailability(Declaration)) {
520f4a2713aSLionel Sambuc case AR_Available:
521f4a2713aSLionel Sambuc case AR_NotYetIntroduced:
522f4a2713aSLionel Sambuc Availability = CXAvailability_Available;
523f4a2713aSLionel Sambuc break;
524f4a2713aSLionel Sambuc
525f4a2713aSLionel Sambuc case AR_Deprecated:
526f4a2713aSLionel Sambuc Availability = CXAvailability_Deprecated;
527f4a2713aSLionel Sambuc break;
528f4a2713aSLionel Sambuc
529f4a2713aSLionel Sambuc case AR_Unavailable:
530f4a2713aSLionel Sambuc Availability = CXAvailability_NotAvailable;
531f4a2713aSLionel Sambuc break;
532f4a2713aSLionel Sambuc }
533f4a2713aSLionel Sambuc
534f4a2713aSLionel Sambuc if (const FunctionDecl *Function = dyn_cast<FunctionDecl>(Declaration))
535f4a2713aSLionel Sambuc if (Function->isDeleted())
536f4a2713aSLionel Sambuc Availability = CXAvailability_NotAvailable;
537f4a2713aSLionel Sambuc
538f4a2713aSLionel Sambuc CursorKind = getCursorKindForDecl(Declaration);
539f4a2713aSLionel Sambuc if (CursorKind == CXCursor_UnexposedDecl) {
540f4a2713aSLionel Sambuc // FIXME: Forward declarations of Objective-C classes and protocols
541f4a2713aSLionel Sambuc // are not directly exposed, but we want code completion to treat them
542f4a2713aSLionel Sambuc // like a definition.
543f4a2713aSLionel Sambuc if (isa<ObjCInterfaceDecl>(Declaration))
544f4a2713aSLionel Sambuc CursorKind = CXCursor_ObjCInterfaceDecl;
545f4a2713aSLionel Sambuc else if (isa<ObjCProtocolDecl>(Declaration))
546f4a2713aSLionel Sambuc CursorKind = CXCursor_ObjCProtocolDecl;
547f4a2713aSLionel Sambuc else
548f4a2713aSLionel Sambuc CursorKind = CXCursor_NotImplemented;
549f4a2713aSLionel Sambuc }
550f4a2713aSLionel Sambuc break;
551f4a2713aSLionel Sambuc }
552f4a2713aSLionel Sambuc
553f4a2713aSLionel Sambuc case RK_Macro:
554f4a2713aSLionel Sambuc case RK_Keyword:
555f4a2713aSLionel Sambuc llvm_unreachable("Macro and keyword kinds are handled by the constructors");
556f4a2713aSLionel Sambuc }
557f4a2713aSLionel Sambuc
558f4a2713aSLionel Sambuc if (!Accessible)
559f4a2713aSLionel Sambuc Availability = CXAvailability_NotAccessible;
560f4a2713aSLionel Sambuc }
561f4a2713aSLionel Sambuc
562f4a2713aSLionel Sambuc /// \brief Retrieve the name that should be used to order a result.
563f4a2713aSLionel Sambuc ///
564f4a2713aSLionel Sambuc /// If the name needs to be constructed as a string, that string will be
565f4a2713aSLionel Sambuc /// saved into Saved and the returned StringRef will refer to it.
getOrderedName(const CodeCompletionResult & R,std::string & Saved)566f4a2713aSLionel Sambuc static StringRef getOrderedName(const CodeCompletionResult &R,
567f4a2713aSLionel Sambuc std::string &Saved) {
568f4a2713aSLionel Sambuc switch (R.Kind) {
569f4a2713aSLionel Sambuc case CodeCompletionResult::RK_Keyword:
570f4a2713aSLionel Sambuc return R.Keyword;
571f4a2713aSLionel Sambuc
572f4a2713aSLionel Sambuc case CodeCompletionResult::RK_Pattern:
573f4a2713aSLionel Sambuc return R.Pattern->getTypedText();
574f4a2713aSLionel Sambuc
575f4a2713aSLionel Sambuc case CodeCompletionResult::RK_Macro:
576f4a2713aSLionel Sambuc return R.Macro->getName();
577f4a2713aSLionel Sambuc
578f4a2713aSLionel Sambuc case CodeCompletionResult::RK_Declaration:
579f4a2713aSLionel Sambuc // Handle declarations below.
580f4a2713aSLionel Sambuc break;
581f4a2713aSLionel Sambuc }
582f4a2713aSLionel Sambuc
583f4a2713aSLionel Sambuc DeclarationName Name = R.Declaration->getDeclName();
584f4a2713aSLionel Sambuc
585f4a2713aSLionel Sambuc // If the name is a simple identifier (by far the common case), or a
586f4a2713aSLionel Sambuc // zero-argument selector, just return a reference to that identifier.
587f4a2713aSLionel Sambuc if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
588f4a2713aSLionel Sambuc return Id->getName();
589f4a2713aSLionel Sambuc if (Name.isObjCZeroArgSelector())
590f4a2713aSLionel Sambuc if (IdentifierInfo *Id
591f4a2713aSLionel Sambuc = Name.getObjCSelector().getIdentifierInfoForSlot(0))
592f4a2713aSLionel Sambuc return Id->getName();
593f4a2713aSLionel Sambuc
594f4a2713aSLionel Sambuc Saved = Name.getAsString();
595f4a2713aSLionel Sambuc return Saved;
596f4a2713aSLionel Sambuc }
597f4a2713aSLionel Sambuc
operator <(const CodeCompletionResult & X,const CodeCompletionResult & Y)598f4a2713aSLionel Sambuc bool clang::operator<(const CodeCompletionResult &X,
599f4a2713aSLionel Sambuc const CodeCompletionResult &Y) {
600f4a2713aSLionel Sambuc std::string XSaved, YSaved;
601f4a2713aSLionel Sambuc StringRef XStr = getOrderedName(X, XSaved);
602f4a2713aSLionel Sambuc StringRef YStr = getOrderedName(Y, YSaved);
603f4a2713aSLionel Sambuc int cmp = XStr.compare_lower(YStr);
604f4a2713aSLionel Sambuc if (cmp)
605f4a2713aSLionel Sambuc return cmp < 0;
606f4a2713aSLionel Sambuc
607f4a2713aSLionel Sambuc // If case-insensitive comparison fails, try case-sensitive comparison.
608f4a2713aSLionel Sambuc cmp = XStr.compare(YStr);
609f4a2713aSLionel Sambuc if (cmp)
610f4a2713aSLionel Sambuc return cmp < 0;
611f4a2713aSLionel Sambuc
612f4a2713aSLionel Sambuc return false;
613f4a2713aSLionel Sambuc }
614