xref: /minix3/external/bsd/llvm/dist/clang/lib/Sema/CodeCompleteConsumer.cpp (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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