blob: 036ae7e8690b9e2531ff13b2c6e6d0684063fdb0 [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
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 defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
13#include "Sema.h"
Douglas Gregor1ca6ae82010-01-14 01:09:38 +000014#include "Lookup.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000016#include "clang/Sema/ExternalSemaSource.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000018#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000019#include "clang/Lex/MacroInfo.h"
20#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000021#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000022#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000023#include "llvm/ADT/StringSwitch.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000024#include <list>
25#include <map>
26#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000027
28using namespace clang;
29
Douglas Gregor86d9a522009-09-21 16:56:56 +000030namespace {
31 /// \brief A container of code-completion results.
32 class ResultBuilder {
33 public:
34 /// \brief The type of a name-lookup filter, which can be provided to the
35 /// name-lookup routines to specify which declarations should be included in
36 /// the result set (when it returns true) and which declarations should be
37 /// filtered out (returns false).
38 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
39
40 typedef CodeCompleteConsumer::Result Result;
41
42 private:
43 /// \brief The actual results we have found.
44 std::vector<Result> Results;
45
46 /// \brief A record of all of the declarations we have found and placed
47 /// into the result set, used to ensure that no declaration ever gets into
48 /// the result set twice.
49 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
50
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000051 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
52
53 /// \brief An entry in the shadow map, which is optimized to store
54 /// a single (declaration, index) mapping (the common case) but
55 /// can also store a list of (declaration, index) mappings.
56 class ShadowMapEntry {
57 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
58
59 /// \brief Contains either the solitary NamedDecl * or a vector
60 /// of (declaration, index) pairs.
61 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
62
63 /// \brief When the entry contains a single declaration, this is
64 /// the index associated with that entry.
65 unsigned SingleDeclIndex;
66
67 public:
68 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
69
70 void Add(NamedDecl *ND, unsigned Index) {
71 if (DeclOrVector.isNull()) {
72 // 0 - > 1 elements: just set the single element information.
73 DeclOrVector = ND;
74 SingleDeclIndex = Index;
75 return;
76 }
77
78 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
79 // 1 -> 2 elements: create the vector of results and push in the
80 // existing declaration.
81 DeclIndexPairVector *Vec = new DeclIndexPairVector;
82 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
83 DeclOrVector = Vec;
84 }
85
86 // Add the new element to the end of the vector.
87 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
88 DeclIndexPair(ND, Index));
89 }
90
91 void Destroy() {
92 if (DeclIndexPairVector *Vec
93 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
94 delete Vec;
95 DeclOrVector = ((NamedDecl *)0);
96 }
97 }
98
99 // Iteration.
100 class iterator;
101 iterator begin() const;
102 iterator end() const;
103 };
104
Douglas Gregor86d9a522009-09-21 16:56:56 +0000105 /// \brief A mapping from declaration names to the declarations that have
106 /// this name within a particular scope and their index within the list of
107 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000108 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000109
110 /// \brief The semantic analysis object for which results are being
111 /// produced.
112 Sema &SemaRef;
113
114 /// \brief If non-NULL, a filter function used to remove any code-completion
115 /// results that are not desirable.
116 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000117
118 /// \brief Whether we should allow declarations as
119 /// nested-name-specifiers that would otherwise be filtered out.
120 bool AllowNestedNameSpecifiers;
121
Douglas Gregor86d9a522009-09-21 16:56:56 +0000122 /// \brief A list of shadow maps, which is used to model name hiding at
123 /// different levels of, e.g., the inheritance hierarchy.
124 std::list<ShadowMap> ShadowMaps;
125
126 public:
127 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor45bcd432010-01-14 03:21:49 +0000128 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000129
130 /// \brief Set the filter used for code-completion results.
131 void setFilter(LookupFilter Filter) {
132 this->Filter = Filter;
133 }
134
135 typedef std::vector<Result>::iterator iterator;
136 iterator begin() { return Results.begin(); }
137 iterator end() { return Results.end(); }
138
139 Result *data() { return Results.empty()? 0 : &Results.front(); }
140 unsigned size() const { return Results.size(); }
141 bool empty() const { return Results.empty(); }
142
Douglas Gregor45bcd432010-01-14 03:21:49 +0000143 /// \brief Specify whether nested-name-specifiers are allowed.
144 void allowNestedNameSpecifiers(bool Allow = true) {
145 AllowNestedNameSpecifiers = Allow;
146 }
147
Douglas Gregore495b7f2010-01-14 00:20:49 +0000148 /// \brief Determine whether the given declaration is at all interesting
149 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000150 ///
151 /// \param ND the declaration that we are inspecting.
152 ///
153 /// \param AsNestedNameSpecifier will be set true if this declaration is
154 /// only interesting when it is a nested-name-specifier.
155 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000156
157 /// \brief Check whether the result is hidden by the Hiding declaration.
158 ///
159 /// \returns true if the result is hidden and cannot be found, false if
160 /// the hidden result could still be found. When false, \p R may be
161 /// modified to describe how the result can be found (e.g., via extra
162 /// qualification).
163 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
164 NamedDecl *Hiding);
165
Douglas Gregor86d9a522009-09-21 16:56:56 +0000166 /// \brief Add a new result to this result set (if it isn't already in one
167 /// of the shadow maps), or replace an existing result (for, e.g., a
168 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000169 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000170 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000171 ///
172 /// \param R the context in which this result will be named.
173 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000174
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000175 /// \brief Add a new result to this result set, where we already know
176 /// the hiding declation (if any).
177 ///
178 /// \param R the result to add (if it is unique).
179 ///
180 /// \param CurContext the context in which this result will be named.
181 ///
182 /// \param Hiding the declaration that hides the result.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000183 ///
184 /// \param InBaseClass whether the result was found in a base
185 /// class of the searched context.
186 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
187 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000188
Douglas Gregora4477812010-01-14 16:01:26 +0000189 /// \brief Add a new non-declaration result to this result set.
190 void AddResult(Result R);
191
Douglas Gregor86d9a522009-09-21 16:56:56 +0000192 /// \brief Enter into a new scope.
193 void EnterNewScope();
194
195 /// \brief Exit from the current scope.
196 void ExitScope();
197
Douglas Gregor55385fe2009-11-18 04:19:12 +0000198 /// \brief Ignore this declaration, if it is seen again.
199 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
200
Douglas Gregor86d9a522009-09-21 16:56:56 +0000201 /// \name Name lookup predicates
202 ///
203 /// These predicates can be passed to the name lookup functions to filter the
204 /// results of name lookup. All of the predicates have the same type, so that
205 ///
206 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000207 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000208 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000209 bool IsNestedNameSpecifier(NamedDecl *ND) const;
210 bool IsEnum(NamedDecl *ND) const;
211 bool IsClassOrStruct(NamedDecl *ND) const;
212 bool IsUnion(NamedDecl *ND) const;
213 bool IsNamespace(NamedDecl *ND) const;
214 bool IsNamespaceOrAlias(NamedDecl *ND) const;
215 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000216 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000217 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000218 //@}
219 };
220}
221
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000222class ResultBuilder::ShadowMapEntry::iterator {
223 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
224 unsigned SingleDeclIndex;
225
226public:
227 typedef DeclIndexPair value_type;
228 typedef value_type reference;
229 typedef std::ptrdiff_t difference_type;
230 typedef std::input_iterator_tag iterator_category;
231
232 class pointer {
233 DeclIndexPair Value;
234
235 public:
236 pointer(const DeclIndexPair &Value) : Value(Value) { }
237
238 const DeclIndexPair *operator->() const {
239 return &Value;
240 }
241 };
242
243 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
244
245 iterator(NamedDecl *SingleDecl, unsigned Index)
246 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
247
248 iterator(const DeclIndexPair *Iterator)
249 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
250
251 iterator &operator++() {
252 if (DeclOrIterator.is<NamedDecl *>()) {
253 DeclOrIterator = (NamedDecl *)0;
254 SingleDeclIndex = 0;
255 return *this;
256 }
257
258 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
259 ++I;
260 DeclOrIterator = I;
261 return *this;
262 }
263
264 iterator operator++(int) {
265 iterator tmp(*this);
266 ++(*this);
267 return tmp;
268 }
269
270 reference operator*() const {
271 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
272 return reference(ND, SingleDeclIndex);
273
Douglas Gregord490f952009-12-06 21:27:58 +0000274 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000275 }
276
277 pointer operator->() const {
278 return pointer(**this);
279 }
280
281 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000282 return X.DeclOrIterator.getOpaqueValue()
283 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000284 X.SingleDeclIndex == Y.SingleDeclIndex;
285 }
286
287 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000288 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000289 }
290};
291
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000292ResultBuilder::ShadowMapEntry::iterator
293ResultBuilder::ShadowMapEntry::begin() const {
294 if (DeclOrVector.isNull())
295 return iterator();
296
297 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
298 return iterator(ND, SingleDeclIndex);
299
300 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
301}
302
303ResultBuilder::ShadowMapEntry::iterator
304ResultBuilder::ShadowMapEntry::end() const {
305 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
306 return iterator();
307
308 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
309}
310
Douglas Gregor456c4a12009-09-21 20:12:40 +0000311/// \brief Compute the qualification required to get from the current context
312/// (\p CurContext) to the target context (\p TargetContext).
313///
314/// \param Context the AST context in which the qualification will be used.
315///
316/// \param CurContext the context where an entity is being named, which is
317/// typically based on the current scope.
318///
319/// \param TargetContext the context in which the named entity actually
320/// resides.
321///
322/// \returns a nested name specifier that refers into the target context, or
323/// NULL if no qualification is needed.
324static NestedNameSpecifier *
325getRequiredQualification(ASTContext &Context,
326 DeclContext *CurContext,
327 DeclContext *TargetContext) {
328 llvm::SmallVector<DeclContext *, 4> TargetParents;
329
330 for (DeclContext *CommonAncestor = TargetContext;
331 CommonAncestor && !CommonAncestor->Encloses(CurContext);
332 CommonAncestor = CommonAncestor->getLookupParent()) {
333 if (CommonAncestor->isTransparentContext() ||
334 CommonAncestor->isFunctionOrMethod())
335 continue;
336
337 TargetParents.push_back(CommonAncestor);
338 }
339
340 NestedNameSpecifier *Result = 0;
341 while (!TargetParents.empty()) {
342 DeclContext *Parent = TargetParents.back();
343 TargetParents.pop_back();
344
345 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
346 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
347 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
348 Result = NestedNameSpecifier::Create(Context, Result,
349 false,
350 Context.getTypeDeclType(TD).getTypePtr());
351 else
352 assert(Parent->isTranslationUnit());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000353 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000354 return Result;
355}
356
Douglas Gregor45bcd432010-01-14 03:21:49 +0000357bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
358 bool &AsNestedNameSpecifier) const {
359 AsNestedNameSpecifier = false;
360
Douglas Gregore495b7f2010-01-14 00:20:49 +0000361 ND = ND->getUnderlyingDecl();
362 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000363
364 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000365 if (!ND->getDeclName())
366 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000367
368 // Friend declarations and declarations introduced due to friends are never
369 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000370 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000371 return false;
372
Douglas Gregor76282942009-12-11 17:31:05 +0000373 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000374 if (isa<ClassTemplateSpecializationDecl>(ND) ||
375 isa<ClassTemplatePartialSpecializationDecl>(ND))
376 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000377
Douglas Gregor76282942009-12-11 17:31:05 +0000378 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000379 if (isa<UsingDecl>(ND))
380 return false;
381
382 // Some declarations have reserved names that we don't want to ever show.
383 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000384 // __va_list_tag is a freak of nature. Find it and skip it.
385 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000386 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000387
Douglas Gregorf52cede2009-10-09 22:16:47 +0000388 // Filter out names reserved for the implementation (C99 7.1.3,
389 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbare013d682009-10-18 20:26:12 +0000390 //
391 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000392 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000393 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000394 if (Name[0] == '_' &&
395 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000396 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000397 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000398 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000399
Douglas Gregor86d9a522009-09-21 16:56:56 +0000400 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000401 if (isa<CXXConstructorDecl>(ND))
402 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000403
404 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000405 if (Filter && !(this->*Filter)(ND)) {
406 // Check whether it is interesting as a nested-name-specifier.
407 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
408 IsNestedNameSpecifier(ND) &&
409 (Filter != &ResultBuilder::IsMember ||
410 (isa<CXXRecordDecl>(ND) &&
411 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
412 AsNestedNameSpecifier = true;
413 return true;
414 }
415
Douglas Gregore495b7f2010-01-14 00:20:49 +0000416 return false;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000417 }
John McCall0d6b1642010-04-23 18:46:30 +0000418
419 if (Filter == &ResultBuilder::IsNestedNameSpecifier)
420 AsNestedNameSpecifier = true;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000421
Douglas Gregore495b7f2010-01-14 00:20:49 +0000422 // ... then it must be interesting!
423 return true;
424}
425
Douglas Gregor6660d842010-01-14 00:41:07 +0000426bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
427 NamedDecl *Hiding) {
428 // In C, there is no way to refer to a hidden name.
429 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
430 // name if we introduce the tag type.
431 if (!SemaRef.getLangOptions().CPlusPlus)
432 return true;
433
434 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
435
436 // There is no way to qualify a name declared in a function or method.
437 if (HiddenCtx->isFunctionOrMethod())
438 return true;
439
440 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
441 return true;
442
443 // We can refer to the result with the appropriate qualification. Do it.
444 R.Hidden = true;
445 R.QualifierIsInformative = false;
446
447 if (!R.Qualifier)
448 R.Qualifier = getRequiredQualification(SemaRef.Context,
449 CurContext,
450 R.Declaration->getDeclContext());
451 return false;
452}
453
Douglas Gregore495b7f2010-01-14 00:20:49 +0000454void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
455 assert(!ShadowMaps.empty() && "Must enter into a results scope");
456
457 if (R.Kind != Result::RK_Declaration) {
458 // For non-declaration results, just add the result.
459 Results.push_back(R);
460 return;
461 }
462
463 // Look through using declarations.
464 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
465 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
466 return;
467 }
468
469 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
470 unsigned IDNS = CanonDecl->getIdentifierNamespace();
471
Douglas Gregor45bcd432010-01-14 03:21:49 +0000472 bool AsNestedNameSpecifier = false;
473 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000474 return;
475
Douglas Gregor86d9a522009-09-21 16:56:56 +0000476 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000477 ShadowMapEntry::iterator I, IEnd;
478 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
479 if (NamePos != SMap.end()) {
480 I = NamePos->second.begin();
481 IEnd = NamePos->second.end();
482 }
483
484 for (; I != IEnd; ++I) {
485 NamedDecl *ND = I->first;
486 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000487 if (ND->getCanonicalDecl() == CanonDecl) {
488 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000489 Results[Index].Declaration = R.Declaration;
490
Douglas Gregor86d9a522009-09-21 16:56:56 +0000491 // We're done.
492 return;
493 }
494 }
495
496 // This is a new declaration in this scope. However, check whether this
497 // declaration name is hidden by a similarly-named declaration in an outer
498 // scope.
499 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
500 --SMEnd;
501 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000502 ShadowMapEntry::iterator I, IEnd;
503 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
504 if (NamePos != SM->end()) {
505 I = NamePos->second.begin();
506 IEnd = NamePos->second.end();
507 }
508 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000509 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000510 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000511 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
512 Decl::IDNS_ObjCProtocol)))
513 continue;
514
515 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000516 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000517 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000518 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000519 continue;
520
521 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000522 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000523 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000524
525 break;
526 }
527 }
528
529 // Make sure that any given declaration only shows up in the result set once.
530 if (!AllDeclsFound.insert(CanonDecl))
531 return;
532
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000533 // If the filter is for nested-name-specifiers, then this result starts a
534 // nested-name-specifier.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000535 if (AsNestedNameSpecifier)
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000536 R.StartsNestedNameSpecifier = true;
537
Douglas Gregor0563c262009-09-22 23:15:58 +0000538 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000539 if (R.QualifierIsInformative && !R.Qualifier &&
540 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000541 DeclContext *Ctx = R.Declaration->getDeclContext();
542 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
543 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
544 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
545 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
546 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
547 else
548 R.QualifierIsInformative = false;
549 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000550
Douglas Gregor86d9a522009-09-21 16:56:56 +0000551 // Insert this result into the set of results and into the current shadow
552 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000553 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000554 Results.push_back(R);
555}
556
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000557void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000558 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000559 if (R.Kind != Result::RK_Declaration) {
560 // For non-declaration results, just add the result.
561 Results.push_back(R);
562 return;
563 }
564
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000565 // Look through using declarations.
566 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
567 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
568 return;
569 }
570
Douglas Gregor45bcd432010-01-14 03:21:49 +0000571 bool AsNestedNameSpecifier = false;
572 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000573 return;
574
575 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
576 return;
577
578 // Make sure that any given declaration only shows up in the result set once.
579 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
580 return;
581
582 // If the filter is for nested-name-specifiers, then this result starts a
583 // nested-name-specifier.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000584 if (AsNestedNameSpecifier)
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000585 R.StartsNestedNameSpecifier = true;
Douglas Gregor0cc84042010-01-14 15:47:35 +0000586 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
587 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
588 ->getLookupContext()))
589 R.QualifierIsInformative = true;
590
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000591 // If this result is supposed to have an informative qualifier, add one.
592 if (R.QualifierIsInformative && !R.Qualifier &&
593 !R.StartsNestedNameSpecifier) {
594 DeclContext *Ctx = R.Declaration->getDeclContext();
595 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
596 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
597 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
598 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000599 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000600 else
601 R.QualifierIsInformative = false;
602 }
603
604 // Insert this result into the set of results.
605 Results.push_back(R);
606}
607
Douglas Gregora4477812010-01-14 16:01:26 +0000608void ResultBuilder::AddResult(Result R) {
609 assert(R.Kind != Result::RK_Declaration &&
610 "Declaration results need more context");
611 Results.push_back(R);
612}
613
Douglas Gregor86d9a522009-09-21 16:56:56 +0000614/// \brief Enter into a new scope.
615void ResultBuilder::EnterNewScope() {
616 ShadowMaps.push_back(ShadowMap());
617}
618
619/// \brief Exit from the current scope.
620void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000621 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
622 EEnd = ShadowMaps.back().end();
623 E != EEnd;
624 ++E)
625 E->second.Destroy();
626
Douglas Gregor86d9a522009-09-21 16:56:56 +0000627 ShadowMaps.pop_back();
628}
629
Douglas Gregor791215b2009-09-21 20:51:25 +0000630/// \brief Determines whether this given declaration will be found by
631/// ordinary name lookup.
632bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
633 unsigned IDNS = Decl::IDNS_Ordinary;
634 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000635 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000636 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
637 return true;
638
Douglas Gregor791215b2009-09-21 20:51:25 +0000639 return ND->getIdentifierNamespace() & IDNS;
640}
641
Douglas Gregor01dfea02010-01-10 23:08:15 +0000642/// \brief Determines whether this given declaration will be found by
643/// ordinary name lookup.
644bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
645 unsigned IDNS = Decl::IDNS_Ordinary;
646 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000647 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000648
649 return (ND->getIdentifierNamespace() & IDNS) &&
650 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
651}
652
Douglas Gregor86d9a522009-09-21 16:56:56 +0000653/// \brief Determines whether the given declaration is suitable as the
654/// start of a C++ nested-name-specifier, e.g., a class or namespace.
655bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
656 // Allow us to find class templates, too.
657 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
658 ND = ClassTemplate->getTemplatedDecl();
659
660 return SemaRef.isAcceptableNestedNameSpecifier(ND);
661}
662
663/// \brief Determines whether the given declaration is an enumeration.
664bool ResultBuilder::IsEnum(NamedDecl *ND) const {
665 return isa<EnumDecl>(ND);
666}
667
668/// \brief Determines whether the given declaration is a class or struct.
669bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
670 // Allow us to find class templates, too.
671 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
672 ND = ClassTemplate->getTemplatedDecl();
673
674 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000675 return RD->getTagKind() == TTK_Class ||
676 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000677
678 return false;
679}
680
681/// \brief Determines whether the given declaration is a union.
682bool ResultBuilder::IsUnion(NamedDecl *ND) const {
683 // Allow us to find class templates, too.
684 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
685 ND = ClassTemplate->getTemplatedDecl();
686
687 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000688 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000689
690 return false;
691}
692
693/// \brief Determines whether the given declaration is a namespace.
694bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
695 return isa<NamespaceDecl>(ND);
696}
697
698/// \brief Determines whether the given declaration is a namespace or
699/// namespace alias.
700bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
701 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
702}
703
Douglas Gregor76282942009-12-11 17:31:05 +0000704/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000705bool ResultBuilder::IsType(NamedDecl *ND) const {
706 return isa<TypeDecl>(ND);
707}
708
Douglas Gregor76282942009-12-11 17:31:05 +0000709/// \brief Determines which members of a class should be visible via
710/// "." or "->". Only value declarations, nested name specifiers, and
711/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000712bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000713 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
714 ND = Using->getTargetDecl();
715
Douglas Gregorce821962009-12-11 18:14:22 +0000716 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
717 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000718}
719
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000720/// \rief Determines whether the given declaration is an Objective-C
721/// instance variable.
722bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
723 return isa<ObjCIvarDecl>(ND);
724}
725
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000726namespace {
727 /// \brief Visible declaration consumer that adds a code-completion result
728 /// for each visible declaration.
729 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
730 ResultBuilder &Results;
731 DeclContext *CurContext;
732
733 public:
734 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
735 : Results(Results), CurContext(CurContext) { }
736
Douglas Gregor0cc84042010-01-14 15:47:35 +0000737 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
738 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000739 }
740 };
741}
742
Douglas Gregor86d9a522009-09-21 16:56:56 +0000743/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000744static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000745 ResultBuilder &Results) {
746 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +0000747 Results.AddResult(Result("short"));
748 Results.AddResult(Result("long"));
749 Results.AddResult(Result("signed"));
750 Results.AddResult(Result("unsigned"));
751 Results.AddResult(Result("void"));
752 Results.AddResult(Result("char"));
753 Results.AddResult(Result("int"));
754 Results.AddResult(Result("float"));
755 Results.AddResult(Result("double"));
756 Results.AddResult(Result("enum"));
757 Results.AddResult(Result("struct"));
758 Results.AddResult(Result("union"));
759 Results.AddResult(Result("const"));
760 Results.AddResult(Result("volatile"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000761
Douglas Gregor86d9a522009-09-21 16:56:56 +0000762 if (LangOpts.C99) {
763 // C99-specific
Douglas Gregora4477812010-01-14 16:01:26 +0000764 Results.AddResult(Result("_Complex"));
765 Results.AddResult(Result("_Imaginary"));
766 Results.AddResult(Result("_Bool"));
767 Results.AddResult(Result("restrict"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000768 }
769
770 if (LangOpts.CPlusPlus) {
771 // C++-specific
Douglas Gregora4477812010-01-14 16:01:26 +0000772 Results.AddResult(Result("bool"));
773 Results.AddResult(Result("class"));
774 Results.AddResult(Result("wchar_t"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000775
Douglas Gregor01dfea02010-01-10 23:08:15 +0000776 // typename qualified-id
777 CodeCompletionString *Pattern = new CodeCompletionString;
778 Pattern->AddTypedTextChunk("typename");
779 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
780 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregora4477812010-01-14 16:01:26 +0000781 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000782
Douglas Gregor86d9a522009-09-21 16:56:56 +0000783 if (LangOpts.CPlusPlus0x) {
Douglas Gregora4477812010-01-14 16:01:26 +0000784 Results.AddResult(Result("auto"));
785 Results.AddResult(Result("char16_t"));
786 Results.AddResult(Result("char32_t"));
787 Results.AddResult(Result("decltype"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000788 }
789 }
790
791 // GNU extensions
792 if (LangOpts.GNUMode) {
793 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +0000794 // Results.AddResult(Result("_Decimal32"));
795 // Results.AddResult(Result("_Decimal64"));
796 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000797
798 CodeCompletionString *Pattern = new CodeCompletionString;
799 Pattern->AddTypedTextChunk("typeof");
800 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
801 Pattern->AddPlaceholderChunk("expression-or-type");
802 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +0000803 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000804 }
805}
806
Douglas Gregor01dfea02010-01-10 23:08:15 +0000807static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
808 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000809 ResultBuilder &Results) {
810 typedef CodeCompleteConsumer::Result Result;
811 // Note: we don't suggest either "auto" or "register", because both
812 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
813 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +0000814 Results.AddResult(Result("extern"));
815 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000816}
817
818static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
819 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000820 ResultBuilder &Results) {
821 typedef CodeCompleteConsumer::Result Result;
822 switch (CCC) {
823 case Action::CCC_Class:
824 case Action::CCC_MemberTemplate:
825 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +0000826 Results.AddResult(Result("explicit"));
827 Results.AddResult(Result("friend"));
828 Results.AddResult(Result("mutable"));
829 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000830 }
831 // Fall through
832
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000833 case Action::CCC_ObjCInterface:
834 case Action::CCC_ObjCImplementation:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000835 case Action::CCC_Namespace:
836 case Action::CCC_Template:
837 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +0000838 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000839 break;
840
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000841 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000842 case Action::CCC_Expression:
843 case Action::CCC_Statement:
844 case Action::CCC_ForInit:
845 case Action::CCC_Condition:
846 break;
847 }
848}
849
Douglas Gregorbca403c2010-01-13 23:51:12 +0000850static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
851static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
852static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000853 ResultBuilder &Results,
854 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000855static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000856 ResultBuilder &Results,
857 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000858static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000859 ResultBuilder &Results,
860 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000861static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000862
Douglas Gregor01dfea02010-01-10 23:08:15 +0000863/// \brief Add language constructs that show up for "ordinary" names.
864static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
865 Scope *S,
866 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000867 ResultBuilder &Results) {
868 typedef CodeCompleteConsumer::Result Result;
869 switch (CCC) {
870 case Action::CCC_Namespace:
871 if (SemaRef.getLangOptions().CPlusPlus) {
872 // namespace <identifier> { }
873 CodeCompletionString *Pattern = new CodeCompletionString;
874 Pattern->AddTypedTextChunk("namespace");
875 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
876 Pattern->AddPlaceholderChunk("identifier");
877 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
878 Pattern->AddPlaceholderChunk("declarations");
879 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
880 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +0000881 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000882
883 // namespace identifier = identifier ;
884 Pattern = new CodeCompletionString;
885 Pattern->AddTypedTextChunk("namespace");
886 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
887 Pattern->AddPlaceholderChunk("identifier");
888 Pattern->AddChunk(CodeCompletionString::CK_Equal);
889 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +0000890 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000891
892 // Using directives
893 Pattern = new CodeCompletionString;
894 Pattern->AddTypedTextChunk("using");
895 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
896 Pattern->AddTextChunk("namespace");
897 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
898 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +0000899 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000900
901 // asm(string-literal)
902 Pattern = new CodeCompletionString;
903 Pattern->AddTypedTextChunk("asm");
904 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
905 Pattern->AddPlaceholderChunk("string-literal");
906 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +0000907 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000908
909 // Explicit template instantiation
910 Pattern = new CodeCompletionString;
911 Pattern->AddTypedTextChunk("template");
912 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
913 Pattern->AddPlaceholderChunk("declaration");
Douglas Gregora4477812010-01-14 16:01:26 +0000914 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000915 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000916
917 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +0000918 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000919
Douglas Gregor01dfea02010-01-10 23:08:15 +0000920 // Fall through
921
922 case Action::CCC_Class:
Douglas Gregora4477812010-01-14 16:01:26 +0000923 Results.AddResult(Result("typedef"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000924 if (SemaRef.getLangOptions().CPlusPlus) {
925 // Using declaration
926 CodeCompletionString *Pattern = new CodeCompletionString;
927 Pattern->AddTypedTextChunk("using");
928 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
929 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregora4477812010-01-14 16:01:26 +0000930 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000931
932 // using typename qualified-id; (only in a dependent context)
933 if (SemaRef.CurContext->isDependentContext()) {
934 Pattern = new CodeCompletionString;
935 Pattern->AddTypedTextChunk("using");
936 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
937 Pattern->AddTextChunk("typename");
938 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
939 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregora4477812010-01-14 16:01:26 +0000940 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000941 }
942
943 if (CCC == Action::CCC_Class) {
944 // public:
945 Pattern = new CodeCompletionString;
946 Pattern->AddTypedTextChunk("public");
947 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +0000948 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000949
950 // protected:
951 Pattern = new CodeCompletionString;
952 Pattern->AddTypedTextChunk("protected");
953 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +0000954 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000955
956 // private:
957 Pattern = new CodeCompletionString;
958 Pattern->AddTypedTextChunk("private");
959 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +0000960 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000961 }
962 }
963 // Fall through
964
965 case Action::CCC_Template:
966 case Action::CCC_MemberTemplate:
967 if (SemaRef.getLangOptions().CPlusPlus) {
968 // template < parameters >
969 CodeCompletionString *Pattern = new CodeCompletionString;
970 Pattern->AddTypedTextChunk("template");
971 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
972 Pattern->AddPlaceholderChunk("parameters");
973 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +0000974 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000975 }
976
Douglas Gregorbca403c2010-01-13 23:51:12 +0000977 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
978 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000979 break;
980
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000981 case Action::CCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +0000982 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
983 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
984 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000985 break;
986
987 case Action::CCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +0000988 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
989 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
990 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000991 break;
992
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000993 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +0000994 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000995 break;
996
Douglas Gregor01dfea02010-01-10 23:08:15 +0000997 case Action::CCC_Statement: {
Douglas Gregora4477812010-01-14 16:01:26 +0000998 Results.AddResult(Result("typedef"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000999
1000 CodeCompletionString *Pattern = 0;
1001 if (SemaRef.getLangOptions().CPlusPlus) {
1002 Pattern = new CodeCompletionString;
1003 Pattern->AddTypedTextChunk("try");
1004 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1005 Pattern->AddPlaceholderChunk("statements");
1006 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1007 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1008 Pattern->AddTextChunk("catch");
1009 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1010 Pattern->AddPlaceholderChunk("declaration");
1011 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1012 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1013 Pattern->AddPlaceholderChunk("statements");
1014 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1015 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001016 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001017 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001018 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001019 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001020
Douglas Gregor01dfea02010-01-10 23:08:15 +00001021 // if (condition) { statements }
1022 Pattern = new CodeCompletionString;
1023 Pattern->AddTypedTextChunk("if");
1024 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1025 if (SemaRef.getLangOptions().CPlusPlus)
1026 Pattern->AddPlaceholderChunk("condition");
1027 else
1028 Pattern->AddPlaceholderChunk("expression");
1029 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1030 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1031 Pattern->AddPlaceholderChunk("statements");
1032 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1033 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001034 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001035
1036 // switch (condition) { }
1037 Pattern = new CodeCompletionString;
1038 Pattern->AddTypedTextChunk("switch");
1039 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1040 if (SemaRef.getLangOptions().CPlusPlus)
1041 Pattern->AddPlaceholderChunk("condition");
1042 else
1043 Pattern->AddPlaceholderChunk("expression");
1044 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1045 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1046 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1047 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001048 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001049
1050 // Switch-specific statements.
1051 if (!SemaRef.getSwitchStack().empty()) {
1052 // case expression:
1053 Pattern = new CodeCompletionString;
1054 Pattern->AddTypedTextChunk("case");
1055 Pattern->AddPlaceholderChunk("expression");
1056 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001057 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001058
1059 // default:
1060 Pattern = new CodeCompletionString;
1061 Pattern->AddTypedTextChunk("default");
1062 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001063 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001064 }
1065
1066 /// while (condition) { statements }
1067 Pattern = new CodeCompletionString;
1068 Pattern->AddTypedTextChunk("while");
1069 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1070 if (SemaRef.getLangOptions().CPlusPlus)
1071 Pattern->AddPlaceholderChunk("condition");
1072 else
1073 Pattern->AddPlaceholderChunk("expression");
1074 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1075 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1076 Pattern->AddPlaceholderChunk("statements");
1077 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1078 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001079 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001080
1081 // do { statements } while ( expression );
1082 Pattern = new CodeCompletionString;
1083 Pattern->AddTypedTextChunk("do");
1084 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1085 Pattern->AddPlaceholderChunk("statements");
1086 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1087 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1088 Pattern->AddTextChunk("while");
1089 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1090 Pattern->AddPlaceholderChunk("expression");
1091 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001092 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001093
1094 // for ( for-init-statement ; condition ; expression ) { statements }
1095 Pattern = new CodeCompletionString;
1096 Pattern->AddTypedTextChunk("for");
1097 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1098 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1099 Pattern->AddPlaceholderChunk("init-statement");
1100 else
1101 Pattern->AddPlaceholderChunk("init-expression");
1102 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1103 Pattern->AddPlaceholderChunk("condition");
1104 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1105 Pattern->AddPlaceholderChunk("inc-expression");
1106 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1107 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1108 Pattern->AddPlaceholderChunk("statements");
1109 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1110 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001111 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001112
1113 if (S->getContinueParent()) {
1114 // continue ;
1115 Pattern = new CodeCompletionString;
1116 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001117 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001118 }
1119
1120 if (S->getBreakParent()) {
1121 // break ;
1122 Pattern = new CodeCompletionString;
1123 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001124 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001125 }
1126
1127 // "return expression ;" or "return ;", depending on whether we
1128 // know the function is void or not.
1129 bool isVoid = false;
1130 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1131 isVoid = Function->getResultType()->isVoidType();
1132 else if (ObjCMethodDecl *Method
1133 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1134 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001135 else if (SemaRef.getCurBlock() &&
1136 !SemaRef.getCurBlock()->ReturnType.isNull())
1137 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001138 Pattern = new CodeCompletionString;
1139 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001140 if (!isVoid) {
1141 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001142 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001143 }
Douglas Gregora4477812010-01-14 16:01:26 +00001144 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001145
1146 // goto identifier ;
1147 Pattern = new CodeCompletionString;
1148 Pattern->AddTypedTextChunk("goto");
1149 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1150 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001151 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001152
1153 // Using directives
1154 Pattern = new CodeCompletionString;
1155 Pattern->AddTypedTextChunk("using");
1156 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1157 Pattern->AddTextChunk("namespace");
1158 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1159 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00001160 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001161 }
1162
1163 // Fall through (for statement expressions).
1164 case Action::CCC_ForInit:
1165 case Action::CCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001166 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001167 // Fall through: conditions and statements can have expressions.
1168
1169 case Action::CCC_Expression: {
1170 CodeCompletionString *Pattern = 0;
1171 if (SemaRef.getLangOptions().CPlusPlus) {
1172 // 'this', if we're in a non-static member function.
1173 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1174 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001175 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001176
1177 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001178 Results.AddResult(Result("true"));
1179 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001180
1181 // dynamic_cast < type-id > ( expression )
1182 Pattern = new CodeCompletionString;
1183 Pattern->AddTypedTextChunk("dynamic_cast");
1184 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1185 Pattern->AddPlaceholderChunk("type-id");
1186 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1187 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1188 Pattern->AddPlaceholderChunk("expression");
1189 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001190 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001191
1192 // static_cast < type-id > ( expression )
1193 Pattern = new CodeCompletionString;
1194 Pattern->AddTypedTextChunk("static_cast");
1195 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1196 Pattern->AddPlaceholderChunk("type-id");
1197 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1198 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1199 Pattern->AddPlaceholderChunk("expression");
1200 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001201 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001202
1203 // reinterpret_cast < type-id > ( expression )
1204 Pattern = new CodeCompletionString;
1205 Pattern->AddTypedTextChunk("reinterpret_cast");
1206 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1207 Pattern->AddPlaceholderChunk("type-id");
1208 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1209 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1210 Pattern->AddPlaceholderChunk("expression");
1211 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001212 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001213
1214 // const_cast < type-id > ( expression )
1215 Pattern = new CodeCompletionString;
1216 Pattern->AddTypedTextChunk("const_cast");
1217 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1218 Pattern->AddPlaceholderChunk("type-id");
1219 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1220 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1221 Pattern->AddPlaceholderChunk("expression");
1222 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001223 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001224
1225 // typeid ( expression-or-type )
1226 Pattern = new CodeCompletionString;
1227 Pattern->AddTypedTextChunk("typeid");
1228 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1229 Pattern->AddPlaceholderChunk("expression-or-type");
1230 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001231 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001232
1233 // new T ( ... )
1234 Pattern = new CodeCompletionString;
1235 Pattern->AddTypedTextChunk("new");
1236 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1237 Pattern->AddPlaceholderChunk("type-id");
1238 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1239 Pattern->AddPlaceholderChunk("expressions");
1240 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001241 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001242
1243 // new T [ ] ( ... )
1244 Pattern = new CodeCompletionString;
1245 Pattern->AddTypedTextChunk("new");
1246 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1247 Pattern->AddPlaceholderChunk("type-id");
1248 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1249 Pattern->AddPlaceholderChunk("size");
1250 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1251 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1252 Pattern->AddPlaceholderChunk("expressions");
1253 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001254 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001255
1256 // delete expression
1257 Pattern = new CodeCompletionString;
1258 Pattern->AddTypedTextChunk("delete");
1259 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1260 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00001261 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001262
1263 // delete [] expression
1264 Pattern = new CodeCompletionString;
1265 Pattern->AddTypedTextChunk("delete");
1266 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1267 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1268 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1269 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00001270 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001271
1272 // throw expression
1273 Pattern = new CodeCompletionString;
1274 Pattern->AddTypedTextChunk("throw");
1275 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1276 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00001277 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001278 }
1279
1280 if (SemaRef.getLangOptions().ObjC1) {
1281 // Add "super", if we're in an Objective-C class with a superclass.
1282 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1283 if (Method->getClassInterface()->getSuperClass())
Douglas Gregora4477812010-01-14 16:01:26 +00001284 Results.AddResult(Result("super"));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001285
Douglas Gregorbca403c2010-01-13 23:51:12 +00001286 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001287 }
1288
1289 // sizeof expression
1290 Pattern = new CodeCompletionString;
1291 Pattern->AddTypedTextChunk("sizeof");
1292 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1293 Pattern->AddPlaceholderChunk("expression-or-type");
1294 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001295 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001296 break;
1297 }
1298 }
1299
Douglas Gregorbca403c2010-01-13 23:51:12 +00001300 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001301
1302 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregora4477812010-01-14 16:01:26 +00001303 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001304}
1305
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001306/// \brief If the given declaration has an associated type, add it as a result
1307/// type chunk.
1308static void AddResultTypeChunk(ASTContext &Context,
1309 NamedDecl *ND,
1310 CodeCompletionString *Result) {
1311 if (!ND)
1312 return;
1313
1314 // Determine the type of the declaration (if it has a type).
1315 QualType T;
1316 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1317 T = Function->getResultType();
1318 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1319 T = Method->getResultType();
1320 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1321 T = FunTmpl->getTemplatedDecl()->getResultType();
1322 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1323 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1324 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1325 /* Do nothing: ignore unresolved using declarations*/
1326 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1327 T = Value->getType();
1328 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1329 T = Property->getType();
1330
1331 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1332 return;
1333
Douglas Gregor84139d62010-04-05 21:25:31 +00001334 PrintingPolicy Policy(Context.PrintingPolicy);
1335 Policy.AnonymousTagLocations = false;
1336
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001337 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001338 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001339 Result->AddResultTypeChunk(TypeStr);
1340}
1341
Douglas Gregor86d9a522009-09-21 16:56:56 +00001342/// \brief Add function parameter chunks to the given code completion string.
1343static void AddFunctionParameterChunks(ASTContext &Context,
1344 FunctionDecl *Function,
1345 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001346 typedef CodeCompletionString::Chunk Chunk;
1347
Douglas Gregor86d9a522009-09-21 16:56:56 +00001348 CodeCompletionString *CCStr = Result;
1349
1350 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1351 ParmVarDecl *Param = Function->getParamDecl(P);
1352
1353 if (Param->hasDefaultArg()) {
1354 // When we see an optional default argument, put that argument and
1355 // the remaining default arguments into a new, optional string.
1356 CodeCompletionString *Opt = new CodeCompletionString;
1357 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1358 CCStr = Opt;
1359 }
1360
1361 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001362 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001363
1364 // Format the placeholder string.
1365 std::string PlaceholderStr;
1366 if (Param->getIdentifier())
1367 PlaceholderStr = Param->getIdentifier()->getName();
1368
1369 Param->getType().getAsStringInternal(PlaceholderStr,
1370 Context.PrintingPolicy);
1371
1372 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001373 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001374 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001375
1376 if (const FunctionProtoType *Proto
1377 = Function->getType()->getAs<FunctionProtoType>())
1378 if (Proto->isVariadic())
1379 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001380}
1381
1382/// \brief Add template parameter chunks to the given code completion string.
1383static void AddTemplateParameterChunks(ASTContext &Context,
1384 TemplateDecl *Template,
1385 CodeCompletionString *Result,
1386 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001387 typedef CodeCompletionString::Chunk Chunk;
1388
Douglas Gregor86d9a522009-09-21 16:56:56 +00001389 CodeCompletionString *CCStr = Result;
1390 bool FirstParameter = true;
1391
1392 TemplateParameterList *Params = Template->getTemplateParameters();
1393 TemplateParameterList::iterator PEnd = Params->end();
1394 if (MaxParameters)
1395 PEnd = Params->begin() + MaxParameters;
1396 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1397 bool HasDefaultArg = false;
1398 std::string PlaceholderStr;
1399 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1400 if (TTP->wasDeclaredWithTypename())
1401 PlaceholderStr = "typename";
1402 else
1403 PlaceholderStr = "class";
1404
1405 if (TTP->getIdentifier()) {
1406 PlaceholderStr += ' ';
1407 PlaceholderStr += TTP->getIdentifier()->getName();
1408 }
1409
1410 HasDefaultArg = TTP->hasDefaultArgument();
1411 } else if (NonTypeTemplateParmDecl *NTTP
1412 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1413 if (NTTP->getIdentifier())
1414 PlaceholderStr = NTTP->getIdentifier()->getName();
1415 NTTP->getType().getAsStringInternal(PlaceholderStr,
1416 Context.PrintingPolicy);
1417 HasDefaultArg = NTTP->hasDefaultArgument();
1418 } else {
1419 assert(isa<TemplateTemplateParmDecl>(*P));
1420 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1421
1422 // Since putting the template argument list into the placeholder would
1423 // be very, very long, we just use an abbreviation.
1424 PlaceholderStr = "template<...> class";
1425 if (TTP->getIdentifier()) {
1426 PlaceholderStr += ' ';
1427 PlaceholderStr += TTP->getIdentifier()->getName();
1428 }
1429
1430 HasDefaultArg = TTP->hasDefaultArgument();
1431 }
1432
1433 if (HasDefaultArg) {
1434 // When we see an optional default argument, put that argument and
1435 // the remaining default arguments into a new, optional string.
1436 CodeCompletionString *Opt = new CodeCompletionString;
1437 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1438 CCStr = Opt;
1439 }
1440
1441 if (FirstParameter)
1442 FirstParameter = false;
1443 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001444 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001445
1446 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001447 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001448 }
1449}
1450
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001451/// \brief Add a qualifier to the given code-completion string, if the
1452/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001453static void
1454AddQualifierToCompletionString(CodeCompletionString *Result,
1455 NestedNameSpecifier *Qualifier,
1456 bool QualifierIsInformative,
1457 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001458 if (!Qualifier)
1459 return;
1460
1461 std::string PrintedNNS;
1462 {
1463 llvm::raw_string_ostream OS(PrintedNNS);
1464 Qualifier->print(OS, Context.PrintingPolicy);
1465 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001466 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001467 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001468 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001469 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001470}
1471
Douglas Gregora61a8792009-12-11 18:44:16 +00001472static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1473 FunctionDecl *Function) {
1474 const FunctionProtoType *Proto
1475 = Function->getType()->getAs<FunctionProtoType>();
1476 if (!Proto || !Proto->getTypeQuals())
1477 return;
1478
1479 std::string QualsStr;
1480 if (Proto->getTypeQuals() & Qualifiers::Const)
1481 QualsStr += " const";
1482 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1483 QualsStr += " volatile";
1484 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1485 QualsStr += " restrict";
1486 Result->AddInformativeChunk(QualsStr);
1487}
1488
Douglas Gregor86d9a522009-09-21 16:56:56 +00001489/// \brief If possible, create a new code completion string for the given
1490/// result.
1491///
1492/// \returns Either a new, heap-allocated code completion string describing
1493/// how to use this result, or NULL to indicate that the string or name of the
1494/// result is all that is needed.
1495CodeCompletionString *
1496CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001497 typedef CodeCompletionString::Chunk Chunk;
1498
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001499 if (Kind == RK_Pattern)
1500 return Pattern->Clone();
1501
1502 CodeCompletionString *Result = new CodeCompletionString;
1503
1504 if (Kind == RK_Keyword) {
1505 Result->AddTypedTextChunk(Keyword);
1506 return Result;
1507 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001508
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001509 if (Kind == RK_Macro) {
1510 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001511 assert(MI && "Not a macro?");
1512
1513 Result->AddTypedTextChunk(Macro->getName());
1514
1515 if (!MI->isFunctionLike())
1516 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001517
1518 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001519 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001520 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1521 A != AEnd; ++A) {
1522 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001523 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001524
1525 if (!MI->isVariadic() || A != AEnd - 1) {
1526 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001527 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001528 continue;
1529 }
1530
1531 // Variadic argument; cope with the different between GNU and C99
1532 // variadic macros, providing a single placeholder for the rest of the
1533 // arguments.
1534 if ((*A)->isStr("__VA_ARGS__"))
1535 Result->AddPlaceholderChunk("...");
1536 else {
1537 std::string Arg = (*A)->getName();
1538 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001539 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001540 }
1541 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001542 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001543 return Result;
1544 }
1545
1546 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001547 NamedDecl *ND = Declaration;
1548
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001549 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001550 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001551 Result->AddTextChunk("::");
1552 return Result;
1553 }
1554
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001555 AddResultTypeChunk(S.Context, ND, Result);
1556
Douglas Gregor86d9a522009-09-21 16:56:56 +00001557 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001558 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1559 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001560 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001561 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001562 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001563 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001564 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001565 return Result;
1566 }
1567
1568 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001569 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1570 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001571 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001572 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001573
1574 // Figure out which template parameters are deduced (or have default
1575 // arguments).
1576 llvm::SmallVector<bool, 16> Deduced;
1577 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1578 unsigned LastDeducibleArgument;
1579 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1580 --LastDeducibleArgument) {
1581 if (!Deduced[LastDeducibleArgument - 1]) {
1582 // C++0x: Figure out if the template argument has a default. If so,
1583 // the user doesn't need to type this argument.
1584 // FIXME: We need to abstract template parameters better!
1585 bool HasDefaultArg = false;
1586 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1587 LastDeducibleArgument - 1);
1588 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1589 HasDefaultArg = TTP->hasDefaultArgument();
1590 else if (NonTypeTemplateParmDecl *NTTP
1591 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1592 HasDefaultArg = NTTP->hasDefaultArgument();
1593 else {
1594 assert(isa<TemplateTemplateParmDecl>(Param));
1595 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001596 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001597 }
1598
1599 if (!HasDefaultArg)
1600 break;
1601 }
1602 }
1603
1604 if (LastDeducibleArgument) {
1605 // Some of the function template arguments cannot be deduced from a
1606 // function call, so we introduce an explicit template argument list
1607 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001608 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001609 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1610 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001611 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001612 }
1613
1614 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001615 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001616 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001617 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001618 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001619 return Result;
1620 }
1621
1622 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001623 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1624 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001625 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001626 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001627 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001628 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001629 return Result;
1630 }
1631
Douglas Gregor9630eb62009-11-17 16:44:22 +00001632 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001633 Selector Sel = Method->getSelector();
1634 if (Sel.isUnarySelector()) {
1635 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1636 return Result;
1637 }
1638
Douglas Gregord3c68542009-11-19 01:08:35 +00001639 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1640 SelName += ':';
1641 if (StartParameter == 0)
1642 Result->AddTypedTextChunk(SelName);
1643 else {
1644 Result->AddInformativeChunk(SelName);
1645
1646 // If there is only one parameter, and we're past it, add an empty
1647 // typed-text chunk since there is nothing to type.
1648 if (Method->param_size() == 1)
1649 Result->AddTypedTextChunk("");
1650 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001651 unsigned Idx = 0;
1652 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1653 PEnd = Method->param_end();
1654 P != PEnd; (void)++P, ++Idx) {
1655 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001656 std::string Keyword;
1657 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00001658 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001659 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1660 Keyword += II->getName().str();
1661 Keyword += ":";
Douglas Gregor4ad96852009-11-19 07:41:15 +00001662 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001663 Result->AddInformativeChunk(Keyword);
1664 } else if (Idx == StartParameter)
1665 Result->AddTypedTextChunk(Keyword);
1666 else
1667 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001668 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001669
1670 // If we're before the starting parameter, skip the placeholder.
1671 if (Idx < StartParameter)
1672 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001673
1674 std::string Arg;
1675 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1676 Arg = "(" + Arg + ")";
1677 if (IdentifierInfo *II = (*P)->getIdentifier())
1678 Arg += II->getName().str();
Douglas Gregor4ad96852009-11-19 07:41:15 +00001679 if (AllParametersAreInformative)
1680 Result->AddInformativeChunk(Arg);
1681 else
1682 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001683 }
1684
Douglas Gregor2a17af02009-12-23 00:21:46 +00001685 if (Method->isVariadic()) {
1686 if (AllParametersAreInformative)
1687 Result->AddInformativeChunk(", ...");
1688 else
1689 Result->AddPlaceholderChunk(", ...");
1690 }
1691
Douglas Gregor9630eb62009-11-17 16:44:22 +00001692 return Result;
1693 }
1694
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001695 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00001696 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1697 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001698
1699 Result->AddTypedTextChunk(ND->getNameAsString());
1700 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001701}
1702
Douglas Gregor86d802e2009-09-23 00:34:09 +00001703CodeCompletionString *
1704CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1705 unsigned CurrentArg,
1706 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001707 typedef CodeCompletionString::Chunk Chunk;
1708
Douglas Gregor86d802e2009-09-23 00:34:09 +00001709 CodeCompletionString *Result = new CodeCompletionString;
1710 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001711 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001712 const FunctionProtoType *Proto
1713 = dyn_cast<FunctionProtoType>(getFunctionType());
1714 if (!FDecl && !Proto) {
1715 // Function without a prototype. Just give the return type and a
1716 // highlighted ellipsis.
1717 const FunctionType *FT = getFunctionType();
1718 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001719 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001720 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1721 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1722 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001723 return Result;
1724 }
1725
1726 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001727 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00001728 else
1729 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001730 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001731
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001732 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001733 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1734 for (unsigned I = 0; I != NumParams; ++I) {
1735 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001736 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001737
1738 std::string ArgString;
1739 QualType ArgType;
1740
1741 if (FDecl) {
1742 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1743 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1744 } else {
1745 ArgType = Proto->getArgType(I);
1746 }
1747
1748 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1749
1750 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001751 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00001752 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001753 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001754 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001755 }
1756
1757 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001758 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001759 if (CurrentArg < NumParams)
1760 Result->AddTextChunk("...");
1761 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001762 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001763 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001764 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001765
1766 return Result;
1767}
1768
Douglas Gregor86d9a522009-09-21 16:56:56 +00001769namespace {
1770 struct SortCodeCompleteResult {
1771 typedef CodeCompleteConsumer::Result Result;
1772
Douglas Gregor6a684032009-09-28 03:51:44 +00001773 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001774 Selector XSel = X.getObjCSelector();
1775 Selector YSel = Y.getObjCSelector();
1776 if (!XSel.isNull() && !YSel.isNull()) {
1777 // We are comparing two selectors.
1778 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1779 if (N == 0)
1780 ++N;
1781 for (unsigned I = 0; I != N; ++I) {
1782 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1783 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1784 if (!XId || !YId)
1785 return XId && !YId;
1786
1787 switch (XId->getName().compare_lower(YId->getName())) {
1788 case -1: return true;
1789 case 1: return false;
1790 default: break;
1791 }
1792 }
1793
1794 return XSel.getNumArgs() < YSel.getNumArgs();
1795 }
1796
1797 // For non-selectors, order by kind.
1798 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00001799 return X.getNameKind() < Y.getNameKind();
1800
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001801 // Order identifiers by comparison of their lowercased names.
1802 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1803 return XId->getName().compare_lower(
1804 Y.getAsIdentifierInfo()->getName()) < 0;
1805
1806 // Order overloaded operators by the order in which they appear
1807 // in our list of operators.
1808 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1809 return XOp < Y.getCXXOverloadedOperator();
1810
1811 // Order C++0x user-defined literal operators lexically by their
1812 // lowercased suffixes.
1813 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1814 return XLit->getName().compare_lower(
1815 Y.getCXXLiteralIdentifier()->getName()) < 0;
1816
1817 // The only stable ordering we have is to turn the name into a
1818 // string and then compare the lower-case strings. This is
1819 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00001820 return llvm::StringRef(X.getAsString()).compare_lower(
1821 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00001822 }
1823
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001824 /// \brief Retrieve the name that should be used to order a result.
1825 ///
1826 /// If the name needs to be constructed as a string, that string will be
1827 /// saved into Saved and the returned StringRef will refer to it.
1828 static llvm::StringRef getOrderedName(const Result &R,
1829 std::string &Saved) {
1830 switch (R.Kind) {
1831 case Result::RK_Keyword:
1832 return R.Keyword;
1833
1834 case Result::RK_Pattern:
1835 return R.Pattern->getTypedText();
1836
1837 case Result::RK_Macro:
1838 return R.Macro->getName();
1839
1840 case Result::RK_Declaration:
1841 // Handle declarations below.
1842 break;
Douglas Gregor54f01612009-11-19 00:01:57 +00001843 }
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001844
1845 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor54f01612009-11-19 00:01:57 +00001846
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001847 // If the name is a simple identifier (by far the common case), or a
1848 // zero-argument selector, just return a reference to that identifier.
1849 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
1850 return Id->getName();
1851 if (Name.isObjCZeroArgSelector())
1852 if (IdentifierInfo *Id
1853 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
1854 return Id->getName();
1855
1856 Saved = Name.getAsString();
1857 return Saved;
1858 }
1859
1860 bool operator()(const Result &X, const Result &Y) const {
1861 std::string XSaved, YSaved;
1862 llvm::StringRef XStr = getOrderedName(X, XSaved);
1863 llvm::StringRef YStr = getOrderedName(Y, YSaved);
1864 int cmp = XStr.compare_lower(YStr);
1865 if (cmp)
1866 return cmp < 0;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001867
1868 // Non-hidden names precede hidden names.
1869 if (X.Hidden != Y.Hidden)
1870 return !X.Hidden;
1871
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001872 // Non-nested-name-specifiers precede nested-name-specifiers.
1873 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1874 return !X.StartsNestedNameSpecifier;
1875
Douglas Gregor86d9a522009-09-21 16:56:56 +00001876 return false;
1877 }
1878 };
1879}
1880
Douglas Gregorbca403c2010-01-13 23:51:12 +00001881static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001882 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001883 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1884 MEnd = PP.macro_end();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001885 M != MEnd; ++M)
Douglas Gregora4477812010-01-14 16:01:26 +00001886 Results.AddResult(M->first);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001887 Results.ExitScope();
1888}
1889
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001890static void HandleCodeCompleteResults(Sema *S,
1891 CodeCompleteConsumer *CodeCompleter,
1892 CodeCompleteConsumer::Result *Results,
1893 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001894 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1895
1896 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001897 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00001898
1899 for (unsigned I = 0; I != NumResults; ++I)
1900 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001901}
1902
Douglas Gregor01dfea02010-01-10 23:08:15 +00001903void Sema::CodeCompleteOrdinaryName(Scope *S,
1904 CodeCompletionContext CompletionContext) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001905 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001906 ResultBuilder Results(*this);
1907
1908 // Determine how to filter results, e.g., so that the names of
1909 // values (functions, enumerators, function templates, etc.) are
1910 // only allowed where we can have an expression.
1911 switch (CompletionContext) {
1912 case CCC_Namespace:
1913 case CCC_Class:
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001914 case CCC_ObjCInterface:
1915 case CCC_ObjCImplementation:
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001916 case CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001917 case CCC_Template:
1918 case CCC_MemberTemplate:
1919 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
1920 break;
1921
1922 case CCC_Expression:
1923 case CCC_Statement:
1924 case CCC_ForInit:
1925 case CCC_Condition:
1926 Results.setFilter(&ResultBuilder::IsOrdinaryName);
1927 break;
1928 }
1929
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001930 CodeCompletionDeclConsumer Consumer(Results, CurContext);
1931 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001932
1933 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00001934 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001935 Results.ExitScope();
1936
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001937 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00001938 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001939 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00001940}
1941
Douglas Gregor95ac6552009-11-18 01:29:26 +00001942static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00001943 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00001944 DeclContext *CurContext,
1945 ResultBuilder &Results) {
1946 typedef CodeCompleteConsumer::Result Result;
1947
1948 // Add properties in this container.
1949 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1950 PEnd = Container->prop_end();
1951 P != PEnd;
1952 ++P)
1953 Results.MaybeAddResult(Result(*P, 0), CurContext);
1954
1955 // Add properties in referenced protocols.
1956 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1957 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1958 PEnd = Protocol->protocol_end();
1959 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001960 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001961 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00001962 if (AllowCategories) {
1963 // Look through categories.
1964 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1965 Category; Category = Category->getNextClassCategory())
1966 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1967 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001968
1969 // Look through protocols.
1970 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1971 E = IFace->protocol_end();
1972 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001973 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001974
1975 // Look in the superclass.
1976 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00001977 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
1978 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001979 } else if (const ObjCCategoryDecl *Category
1980 = dyn_cast<ObjCCategoryDecl>(Container)) {
1981 // Look through protocols.
1982 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
1983 PEnd = Category->protocol_end();
1984 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001985 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001986 }
1987}
1988
Douglas Gregor81b747b2009-09-17 21:32:03 +00001989void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
1990 SourceLocation OpLoc,
1991 bool IsArrow) {
1992 if (!BaseE || !CodeCompleter)
1993 return;
1994
Douglas Gregor86d9a522009-09-21 16:56:56 +00001995 typedef CodeCompleteConsumer::Result Result;
1996
Douglas Gregor81b747b2009-09-17 21:32:03 +00001997 Expr *Base = static_cast<Expr *>(BaseE);
1998 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001999
2000 if (IsArrow) {
2001 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2002 BaseType = Ptr->getPointeeType();
2003 else if (BaseType->isObjCObjectPointerType())
2004 /*Do nothing*/ ;
2005 else
2006 return;
2007 }
2008
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002009 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002010 Results.EnterNewScope();
2011 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2012 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002013 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002014 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2015 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002016
Douglas Gregor95ac6552009-11-18 01:29:26 +00002017 if (getLangOptions().CPlusPlus) {
2018 if (!Results.empty()) {
2019 // The "template" keyword can follow "->" or "." in the grammar.
2020 // However, we only want to suggest the template keyword if something
2021 // is dependent.
2022 bool IsDependent = BaseType->isDependentType();
2023 if (!IsDependent) {
2024 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2025 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2026 IsDependent = Ctx->isDependentContext();
2027 break;
2028 }
2029 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002030
Douglas Gregor95ac6552009-11-18 01:29:26 +00002031 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002032 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002033 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002034 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002035 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2036 // Objective-C property reference.
2037
2038 // Add property results based on our interface.
2039 const ObjCObjectPointerType *ObjCPtr
2040 = BaseType->getAsObjCInterfacePointerType();
2041 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002042 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002043
2044 // Add properties from the protocols in a qualified interface.
2045 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2046 E = ObjCPtr->qual_end();
2047 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002048 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002049 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002050 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002051 // Objective-C instance variable access.
2052 ObjCInterfaceDecl *Class = 0;
2053 if (const ObjCObjectPointerType *ObjCPtr
2054 = BaseType->getAs<ObjCObjectPointerType>())
2055 Class = ObjCPtr->getInterfaceDecl();
2056 else
John McCallc12c5bb2010-05-15 11:32:37 +00002057 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002058
2059 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002060 if (Class) {
2061 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2062 Results.setFilter(&ResultBuilder::IsObjCIvar);
2063 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002064 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002065 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002066
2067 // FIXME: How do we cope with isa?
2068
2069 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002070
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002071 // Hand off the results found for code completion.
2072 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002073}
2074
Douglas Gregor374929f2009-09-18 15:37:17 +00002075void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2076 if (!CodeCompleter)
2077 return;
2078
Douglas Gregor86d9a522009-09-21 16:56:56 +00002079 typedef CodeCompleteConsumer::Result Result;
2080 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00002081 switch ((DeclSpec::TST)TagSpec) {
2082 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002083 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00002084 break;
2085
2086 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002087 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00002088 break;
2089
2090 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002091 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002092 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00002093 break;
2094
2095 default:
2096 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2097 return;
2098 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002099
John McCall0d6b1642010-04-23 18:46:30 +00002100 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002101 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002102
2103 // First pass: look for tags.
2104 Results.setFilter(Filter);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002105 LookupVisibleDecls(S, LookupTagName, Consumer);
John McCall0d6b1642010-04-23 18:46:30 +00002106
2107 // Second pass: look for nested name specifiers.
2108 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2109 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002110
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002111 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002112}
2113
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002114void Sema::CodeCompleteCase(Scope *S) {
2115 if (getSwitchStack().empty() || !CodeCompleter)
2116 return;
2117
2118 SwitchStmt *Switch = getSwitchStack().back();
2119 if (!Switch->getCond()->getType()->isEnumeralType())
2120 return;
2121
2122 // Code-complete the cases of a switch statement over an enumeration type
2123 // by providing the list of
2124 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2125
2126 // Determine which enumerators we have already seen in the switch statement.
2127 // FIXME: Ideally, we would also be able to look *past* the code-completion
2128 // token, in case we are code-completing in the middle of the switch and not
2129 // at the end. However, we aren't able to do so at the moment.
2130 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002131 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002132 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2133 SC = SC->getNextSwitchCase()) {
2134 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2135 if (!Case)
2136 continue;
2137
2138 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2139 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2140 if (EnumConstantDecl *Enumerator
2141 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2142 // We look into the AST of the case statement to determine which
2143 // enumerator was named. Alternatively, we could compute the value of
2144 // the integral constant expression, then compare it against the
2145 // values of each enumerator. However, value-based approach would not
2146 // work as well with C++ templates where enumerators declared within a
2147 // template are type- and value-dependent.
2148 EnumeratorsSeen.insert(Enumerator);
2149
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002150 // If this is a qualified-id, keep track of the nested-name-specifier
2151 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002152 //
2153 // switch (TagD.getKind()) {
2154 // case TagDecl::TK_enum:
2155 // break;
2156 // case XXX
2157 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002158 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002159 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2160 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002161 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002162 }
2163 }
2164
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002165 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2166 // If there are no prior enumerators in C++, check whether we have to
2167 // qualify the names of the enumerators that we suggest, because they
2168 // may not be visible in this scope.
2169 Qualifier = getRequiredQualification(Context, CurContext,
2170 Enum->getDeclContext());
2171
2172 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2173 }
2174
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002175 // Add any enumerators that have not yet been mentioned.
2176 ResultBuilder Results(*this);
2177 Results.EnterNewScope();
2178 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2179 EEnd = Enum->enumerator_end();
2180 E != EEnd; ++E) {
2181 if (EnumeratorsSeen.count(*E))
2182 continue;
2183
Douglas Gregor608300b2010-01-14 16:14:35 +00002184 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2185 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002186 }
2187 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002188
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002189 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002190 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002191 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002192}
2193
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002194namespace {
2195 struct IsBetterOverloadCandidate {
2196 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002197 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002198
2199 public:
John McCall5769d612010-02-08 23:07:23 +00002200 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2201 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002202
2203 bool
2204 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5769d612010-02-08 23:07:23 +00002205 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002206 }
2207 };
2208}
2209
2210void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2211 ExprTy **ArgsIn, unsigned NumArgs) {
2212 if (!CodeCompleter)
2213 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002214
2215 // When we're code-completing for a call, we fall back to ordinary
2216 // name code-completion whenever we can't produce specific
2217 // results. We may want to revisit this strategy in the future,
2218 // e.g., by merging the two kinds of results.
2219
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002220 Expr *Fn = (Expr *)FnIn;
2221 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002222
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002223 // Ignore type-dependent call expressions entirely.
2224 if (Fn->isTypeDependent() ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002225 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00002226 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002227 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002228 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002229
John McCall3b4294e2009-12-16 12:17:52 +00002230 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002231 SourceLocation Loc = Fn->getExprLoc();
2232 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002233
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002234 // FIXME: What if we're calling something that isn't a function declaration?
2235 // FIXME: What if we're calling a pseudo-destructor?
2236 // FIXME: What if we're calling a member function?
2237
Douglas Gregorc0265402010-01-21 15:46:19 +00002238 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2239 llvm::SmallVector<ResultCandidate, 8> Results;
2240
John McCall3b4294e2009-12-16 12:17:52 +00002241 Expr *NakedFn = Fn->IgnoreParenCasts();
2242 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2243 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2244 /*PartialOverloading=*/ true);
2245 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2246 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002247 if (FDecl) {
2248 if (!FDecl->getType()->getAs<FunctionProtoType>())
2249 Results.push_back(ResultCandidate(FDecl));
2250 else
John McCall86820f52010-01-26 01:37:31 +00002251 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002252 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2253 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00002254 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002255 }
John McCall3b4294e2009-12-16 12:17:52 +00002256 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002257
Douglas Gregorc0265402010-01-21 15:46:19 +00002258 if (!CandidateSet.empty()) {
2259 // Sort the overload candidate set by placing the best overloads first.
2260 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002261 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002262
Douglas Gregorc0265402010-01-21 15:46:19 +00002263 // Add the remaining viable overload candidates as code-completion reslults.
2264 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2265 CandEnd = CandidateSet.end();
2266 Cand != CandEnd; ++Cand) {
2267 if (Cand->Viable)
2268 Results.push_back(ResultCandidate(Cand->Function));
2269 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002270 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002271
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002272 CodeCompleteOrdinaryName(S, CCC_Expression);
2273 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002274 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2275 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002276}
2277
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00002278void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00002279 bool EnteringContext) {
2280 if (!SS.getScopeRep() || !CodeCompleter)
2281 return;
2282
Douglas Gregor86d9a522009-09-21 16:56:56 +00002283 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2284 if (!Ctx)
2285 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002286
2287 // Try to instantiate any non-dependent declaration contexts before
2288 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00002289 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002290 return;
2291
Douglas Gregor86d9a522009-09-21 16:56:56 +00002292 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002293 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2294 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002295
2296 // The "template" keyword can follow "::" in the grammar, but only
2297 // put it into the grammar if the nested-name-specifier is dependent.
2298 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2299 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00002300 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002301
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002302 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002303}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002304
2305void Sema::CodeCompleteUsing(Scope *S) {
2306 if (!CodeCompleter)
2307 return;
2308
Douglas Gregor86d9a522009-09-21 16:56:56 +00002309 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002310 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002311
2312 // If we aren't in class scope, we could see the "namespace" keyword.
2313 if (!S->isClassScope())
Douglas Gregora4477812010-01-14 16:01:26 +00002314 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002315
2316 // After "using", we can see anything that would start a
2317 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002318 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2319 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002320 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002321
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002322 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002323}
2324
2325void Sema::CodeCompleteUsingDirective(Scope *S) {
2326 if (!CodeCompleter)
2327 return;
2328
Douglas Gregor86d9a522009-09-21 16:56:56 +00002329 // After "using namespace", we expect to see a namespace name or namespace
2330 // alias.
2331 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002332 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002333 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2334 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002335 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002336 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002337}
2338
2339void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2340 if (!CodeCompleter)
2341 return;
2342
Douglas Gregor86d9a522009-09-21 16:56:56 +00002343 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2344 DeclContext *Ctx = (DeclContext *)S->getEntity();
2345 if (!S->getParent())
2346 Ctx = Context.getTranslationUnitDecl();
2347
2348 if (Ctx && Ctx->isFileContext()) {
2349 // We only want to see those namespaces that have already been defined
2350 // within this scope, because its likely that the user is creating an
2351 // extended namespace declaration. Keep track of the most recent
2352 // definition of each namespace.
2353 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2354 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2355 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2356 NS != NSEnd; ++NS)
2357 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2358
2359 // Add the most recent definition (or extended definition) of each
2360 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002361 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002362 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2363 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2364 NS != NSEnd; ++NS)
Douglas Gregor608300b2010-01-14 16:14:35 +00002365 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2366 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002367 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002368 }
2369
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002370 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002371}
2372
2373void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2374 if (!CodeCompleter)
2375 return;
2376
Douglas Gregor86d9a522009-09-21 16:56:56 +00002377 // After "namespace", we expect to see a namespace or alias.
2378 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002379 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2380 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002381 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002382}
2383
Douglas Gregored8d3222009-09-18 20:05:18 +00002384void Sema::CodeCompleteOperatorName(Scope *S) {
2385 if (!CodeCompleter)
2386 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002387
2388 typedef CodeCompleteConsumer::Result Result;
2389 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002390 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00002391
Douglas Gregor86d9a522009-09-21 16:56:56 +00002392 // Add the names of overloadable operators.
2393#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2394 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00002395 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002396#include "clang/Basic/OperatorKinds.def"
2397
2398 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00002399 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002400 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2401 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002402
2403 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00002404 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002405 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002406
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002407 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00002408}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002409
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002410// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2411// true or false.
2412#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00002413static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002414 ResultBuilder &Results,
2415 bool NeedAt) {
2416 typedef CodeCompleteConsumer::Result Result;
2417 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00002418 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002419
2420 CodeCompletionString *Pattern = 0;
2421 if (LangOpts.ObjC2) {
2422 // @dynamic
2423 Pattern = new CodeCompletionString;
2424 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2425 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2426 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002427 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002428
2429 // @synthesize
2430 Pattern = new CodeCompletionString;
2431 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2432 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2433 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002434 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002435 }
2436}
2437
Douglas Gregorbca403c2010-01-13 23:51:12 +00002438static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002439 ResultBuilder &Results,
2440 bool NeedAt) {
2441 typedef CodeCompleteConsumer::Result Result;
2442
2443 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00002444 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002445
2446 if (LangOpts.ObjC2) {
2447 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00002448 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002449
2450 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00002451 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002452
2453 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00002454 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002455 }
2456}
2457
Douglas Gregorbca403c2010-01-13 23:51:12 +00002458static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002459 typedef CodeCompleteConsumer::Result Result;
2460 CodeCompletionString *Pattern = 0;
2461
2462 // @class name ;
2463 Pattern = new CodeCompletionString;
2464 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2465 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2466 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00002467 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002468
2469 // @interface name
2470 // FIXME: Could introduce the whole pattern, including superclasses and
2471 // such.
2472 Pattern = new CodeCompletionString;
2473 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2474 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2475 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002476 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002477
2478 // @protocol name
2479 Pattern = new CodeCompletionString;
2480 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2481 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2482 Pattern->AddPlaceholderChunk("protocol");
Douglas Gregora4477812010-01-14 16:01:26 +00002483 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002484
2485 // @implementation name
2486 Pattern = new CodeCompletionString;
2487 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2488 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2489 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002490 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002491
2492 // @compatibility_alias name
2493 Pattern = new CodeCompletionString;
2494 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2495 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2496 Pattern->AddPlaceholderChunk("alias");
2497 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2498 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002499 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002500}
2501
Douglas Gregorc464ae82009-12-07 09:27:33 +00002502void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2503 bool InInterface) {
2504 typedef CodeCompleteConsumer::Result Result;
2505 ResultBuilder Results(*this);
2506 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002507 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002508 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002509 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002510 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002511 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00002512 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00002513 Results.ExitScope();
2514 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2515}
2516
Douglas Gregorbca403c2010-01-13 23:51:12 +00002517static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002518 typedef CodeCompleteConsumer::Result Result;
2519 CodeCompletionString *Pattern = 0;
2520
2521 // @encode ( type-name )
2522 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002523 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002524 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2525 Pattern->AddPlaceholderChunk("type-name");
2526 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002527 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002528
2529 // @protocol ( protocol-name )
2530 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002531 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002532 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2533 Pattern->AddPlaceholderChunk("protocol-name");
2534 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002535 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002536
2537 // @selector ( selector )
2538 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002539 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002540 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2541 Pattern->AddPlaceholderChunk("selector");
2542 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002543 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002544}
2545
Douglas Gregorbca403c2010-01-13 23:51:12 +00002546static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002547 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002548 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002549
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002550 // @try { statements } @catch ( declaration ) { statements } @finally
2551 // { statements }
2552 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002553 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002554 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2555 Pattern->AddPlaceholderChunk("statements");
2556 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2557 Pattern->AddTextChunk("@catch");
2558 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2559 Pattern->AddPlaceholderChunk("parameter");
2560 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2561 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2562 Pattern->AddPlaceholderChunk("statements");
2563 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2564 Pattern->AddTextChunk("@finally");
2565 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2566 Pattern->AddPlaceholderChunk("statements");
2567 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00002568 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002569
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002570 // @throw
2571 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002572 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00002573 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002574 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00002575 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002576
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002577 // @synchronized ( expression ) { statements }
2578 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002579 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
Douglas Gregor834389b2010-01-12 06:38:28 +00002580 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002581 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2582 Pattern->AddPlaceholderChunk("expression");
2583 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2584 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2585 Pattern->AddPlaceholderChunk("statements");
2586 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00002587 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002588}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002589
Douglas Gregorbca403c2010-01-13 23:51:12 +00002590static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002591 ResultBuilder &Results,
2592 bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002593 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +00002594 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2595 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2596 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002597 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00002598 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002599}
2600
2601void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2602 ResultBuilder Results(*this);
2603 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002604 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002605 Results.ExitScope();
2606 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2607}
2608
2609void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002610 ResultBuilder Results(*this);
2611 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002612 AddObjCStatementResults(Results, false);
2613 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002614 Results.ExitScope();
2615 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2616}
2617
2618void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2619 ResultBuilder Results(*this);
2620 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002621 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002622 Results.ExitScope();
2623 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2624}
2625
Douglas Gregor988358f2009-11-19 00:14:45 +00002626/// \brief Determine whether the addition of the given flag to an Objective-C
2627/// property's attributes will cause a conflict.
2628static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2629 // Check if we've already added this flag.
2630 if (Attributes & NewFlag)
2631 return true;
2632
2633 Attributes |= NewFlag;
2634
2635 // Check for collisions with "readonly".
2636 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2637 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2638 ObjCDeclSpec::DQ_PR_assign |
2639 ObjCDeclSpec::DQ_PR_copy |
2640 ObjCDeclSpec::DQ_PR_retain)))
2641 return true;
2642
2643 // Check for more than one of { assign, copy, retain }.
2644 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2645 ObjCDeclSpec::DQ_PR_copy |
2646 ObjCDeclSpec::DQ_PR_retain);
2647 if (AssignCopyRetMask &&
2648 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2649 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2650 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2651 return true;
2652
2653 return false;
2654}
2655
Douglas Gregora93b1082009-11-18 23:08:07 +00002656void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00002657 if (!CodeCompleter)
2658 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00002659
Steve Naroffece8e712009-10-08 21:55:05 +00002660 unsigned Attributes = ODS.getPropertyAttributes();
2661
2662 typedef CodeCompleteConsumer::Result Result;
2663 ResultBuilder Results(*this);
2664 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00002665 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregora4477812010-01-14 16:01:26 +00002666 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002667 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregora4477812010-01-14 16:01:26 +00002668 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002669 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregora4477812010-01-14 16:01:26 +00002670 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002671 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregora4477812010-01-14 16:01:26 +00002672 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002673 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregora4477812010-01-14 16:01:26 +00002674 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002675 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregora4477812010-01-14 16:01:26 +00002676 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002677 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002678 CodeCompletionString *Setter = new CodeCompletionString;
2679 Setter->AddTypedTextChunk("setter");
2680 Setter->AddTextChunk(" = ");
2681 Setter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00002682 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00002683 }
Douglas Gregor988358f2009-11-19 00:14:45 +00002684 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002685 CodeCompletionString *Getter = new CodeCompletionString;
2686 Getter->AddTypedTextChunk("getter");
2687 Getter->AddTextChunk(" = ");
2688 Getter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00002689 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00002690 }
Steve Naroffece8e712009-10-08 21:55:05 +00002691 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002692 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00002693}
Steve Naroffc4df6d22009-11-07 02:08:14 +00002694
Douglas Gregor4ad96852009-11-19 07:41:15 +00002695/// \brief Descripts the kind of Objective-C method that we want to find
2696/// via code completion.
2697enum ObjCMethodKind {
2698 MK_Any, //< Any kind of method, provided it means other specified criteria.
2699 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2700 MK_OneArgSelector //< One-argument selector.
2701};
2702
2703static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2704 ObjCMethodKind WantKind,
2705 IdentifierInfo **SelIdents,
2706 unsigned NumSelIdents) {
2707 Selector Sel = Method->getSelector();
2708 if (NumSelIdents > Sel.getNumArgs())
2709 return false;
2710
2711 switch (WantKind) {
2712 case MK_Any: break;
2713 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2714 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2715 }
2716
2717 for (unsigned I = 0; I != NumSelIdents; ++I)
2718 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2719 return false;
2720
2721 return true;
2722}
2723
Douglas Gregor36ecb042009-11-17 23:22:23 +00002724/// \brief Add all of the Objective-C methods in the given Objective-C
2725/// container to the set of results.
2726///
2727/// The container will be a class, protocol, category, or implementation of
2728/// any of the above. This mether will recurse to include methods from
2729/// the superclasses of classes along with their categories, protocols, and
2730/// implementations.
2731///
2732/// \param Container the container in which we'll look to find methods.
2733///
2734/// \param WantInstance whether to add instance methods (only); if false, this
2735/// routine will add factory methods (only).
2736///
2737/// \param CurContext the context in which we're performing the lookup that
2738/// finds methods.
2739///
2740/// \param Results the structure into which we'll add results.
2741static void AddObjCMethods(ObjCContainerDecl *Container,
2742 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00002743 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00002744 IdentifierInfo **SelIdents,
2745 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00002746 DeclContext *CurContext,
2747 ResultBuilder &Results) {
2748 typedef CodeCompleteConsumer::Result Result;
2749 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2750 MEnd = Container->meth_end();
2751 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002752 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2753 // Check whether the selector identifiers we've been given are a
2754 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002755 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00002756 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002757
Douglas Gregord3c68542009-11-19 01:08:35 +00002758 Result R = Result(*M, 0);
2759 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002760 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00002761 Results.MaybeAddResult(R, CurContext);
2762 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00002763 }
2764
2765 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2766 if (!IFace)
2767 return;
2768
2769 // Add methods in protocols.
2770 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2771 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2772 E = Protocols.end();
2773 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002774 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00002775 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002776
2777 // Add methods in categories.
2778 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2779 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00002780 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2781 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002782
2783 // Add a categories protocol methods.
2784 const ObjCList<ObjCProtocolDecl> &Protocols
2785 = CatDecl->getReferencedProtocols();
2786 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2787 E = Protocols.end();
2788 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002789 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2790 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002791
2792 // Add methods in category implementations.
2793 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002794 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2795 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002796 }
2797
2798 // Add methods in superclass.
2799 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002800 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2801 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002802
2803 // Add methods in our implementation, if any.
2804 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002805 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2806 NumSelIdents, CurContext, Results);
2807}
2808
2809
2810void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2811 DeclPtrTy *Methods,
2812 unsigned NumMethods) {
2813 typedef CodeCompleteConsumer::Result Result;
2814
2815 // Try to find the interface where getters might live.
2816 ObjCInterfaceDecl *Class
2817 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2818 if (!Class) {
2819 if (ObjCCategoryDecl *Category
2820 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2821 Class = Category->getClassInterface();
2822
2823 if (!Class)
2824 return;
2825 }
2826
2827 // Find all of the potential getters.
2828 ResultBuilder Results(*this);
2829 Results.EnterNewScope();
2830
2831 // FIXME: We need to do this because Objective-C methods don't get
2832 // pushed into DeclContexts early enough. Argh!
2833 for (unsigned I = 0; I != NumMethods; ++I) {
2834 if (ObjCMethodDecl *Method
2835 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2836 if (Method->isInstanceMethod() &&
2837 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2838 Result R = Result(Method, 0);
2839 R.AllParametersAreInformative = true;
2840 Results.MaybeAddResult(R, CurContext);
2841 }
2842 }
2843
2844 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2845 Results.ExitScope();
2846 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2847}
2848
2849void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2850 DeclPtrTy *Methods,
2851 unsigned NumMethods) {
2852 typedef CodeCompleteConsumer::Result Result;
2853
2854 // Try to find the interface where setters might live.
2855 ObjCInterfaceDecl *Class
2856 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2857 if (!Class) {
2858 if (ObjCCategoryDecl *Category
2859 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2860 Class = Category->getClassInterface();
2861
2862 if (!Class)
2863 return;
2864 }
2865
2866 // Find all of the potential getters.
2867 ResultBuilder Results(*this);
2868 Results.EnterNewScope();
2869
2870 // FIXME: We need to do this because Objective-C methods don't get
2871 // pushed into DeclContexts early enough. Argh!
2872 for (unsigned I = 0; I != NumMethods; ++I) {
2873 if (ObjCMethodDecl *Method
2874 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2875 if (Method->isInstanceMethod() &&
2876 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2877 Result R = Result(Method, 0);
2878 R.AllParametersAreInformative = true;
2879 Results.MaybeAddResult(R, CurContext);
2880 }
2881 }
2882
2883 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2884
2885 Results.ExitScope();
2886 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00002887}
2888
Douglas Gregor22f56992010-04-06 19:22:33 +00002889/// \brief When we have an expression with type "id", we may assume
2890/// that it has some more-specific class type based on knowledge of
2891/// common uses of Objective-C. This routine returns that class type,
2892/// or NULL if no better result could be determined.
2893static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
2894 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
2895 if (!Msg)
2896 return 0;
2897
2898 Selector Sel = Msg->getSelector();
2899 if (Sel.isNull())
2900 return 0;
2901
2902 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
2903 if (!Id)
2904 return 0;
2905
2906 ObjCMethodDecl *Method = Msg->getMethodDecl();
2907 if (!Method)
2908 return 0;
2909
2910 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00002911 ObjCInterfaceDecl *IFace = 0;
2912 switch (Msg->getReceiverKind()) {
2913 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00002914 if (const ObjCObjectType *ObjType
2915 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
2916 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00002917 break;
2918
2919 case ObjCMessageExpr::Instance: {
2920 QualType T = Msg->getInstanceReceiver()->getType();
2921 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
2922 IFace = Ptr->getInterfaceDecl();
2923 break;
2924 }
2925
2926 case ObjCMessageExpr::SuperInstance:
2927 case ObjCMessageExpr::SuperClass:
2928 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00002929 }
2930
2931 if (!IFace)
2932 return 0;
2933
2934 ObjCInterfaceDecl *Super = IFace->getSuperClass();
2935 if (Method->isInstanceMethod())
2936 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2937 .Case("retain", IFace)
2938 .Case("autorelease", IFace)
2939 .Case("copy", IFace)
2940 .Case("copyWithZone", IFace)
2941 .Case("mutableCopy", IFace)
2942 .Case("mutableCopyWithZone", IFace)
2943 .Case("awakeFromCoder", IFace)
2944 .Case("replacementObjectFromCoder", IFace)
2945 .Case("class", IFace)
2946 .Case("classForCoder", IFace)
2947 .Case("superclass", Super)
2948 .Default(0);
2949
2950 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2951 .Case("new", IFace)
2952 .Case("alloc", IFace)
2953 .Case("allocWithZone", IFace)
2954 .Case("class", IFace)
2955 .Case("superclass", Super)
2956 .Default(0);
2957}
2958
Douglas Gregor2725ca82010-04-21 19:57:20 +00002959void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
2960 IdentifierInfo **SelIdents,
2961 unsigned NumSelIdents) {
2962 ObjCInterfaceDecl *CDecl = 0;
2963 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2964 // Figure out which interface we're in.
2965 CDecl = CurMethod->getClassInterface();
2966 if (!CDecl)
2967 return;
2968
2969 // Find the superclass of this class.
2970 CDecl = CDecl->getSuperClass();
2971 if (!CDecl)
2972 return;
2973
2974 if (CurMethod->isInstanceMethod()) {
2975 // We are inside an instance method, which means that the message
2976 // send [super ...] is actually calling an instance method on the
2977 // current object. Build the super expression and handle this like
2978 // an instance method.
2979 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2980 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2981 OwningExprResult Super
2982 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
2983 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2984 SelIdents, NumSelIdents);
2985 }
2986
2987 // Fall through to send to the superclass in CDecl.
2988 } else {
2989 // "super" may be the name of a type or variable. Figure out which
2990 // it is.
2991 IdentifierInfo *Super = &Context.Idents.get("super");
2992 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
2993 LookupOrdinaryName);
2994 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
2995 // "super" names an interface. Use it.
2996 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00002997 if (const ObjCObjectType *Iface
2998 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
2999 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00003000 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3001 // "super" names an unresolved type; we can't be more specific.
3002 } else {
3003 // Assume that "super" names some kind of value and parse that way.
3004 CXXScopeSpec SS;
3005 UnqualifiedId id;
3006 id.setIdentifier(Super, SuperLoc);
3007 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
3008 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3009 SelIdents, NumSelIdents);
3010 }
3011
3012 // Fall through
3013 }
3014
3015 TypeTy *Receiver = 0;
3016 if (CDecl)
3017 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3018 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3019 NumSelIdents);
3020}
3021
3022void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003023 IdentifierInfo **SelIdents,
3024 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003025 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003026 ObjCInterfaceDecl *CDecl = 0;
3027
Douglas Gregor24a069f2009-11-17 17:59:40 +00003028 // If the given name refers to an interface type, retrieve the
3029 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003030 if (Receiver) {
3031 QualType T = GetTypeFromParser(Receiver, 0);
3032 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00003033 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3034 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003035 }
3036
Douglas Gregor36ecb042009-11-17 23:22:23 +00003037 // Add all of the factory methods in this Objective-C class, its protocols,
3038 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003039 ResultBuilder Results(*this);
3040 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003041
3042 if (CDecl)
3043 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3044 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003045 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00003046 // We're messaging "id" as a type; provide all class/factory methods.
3047
Douglas Gregor719770d2010-04-06 17:30:22 +00003048 // If we have an external source, load the entire class method
3049 // pool from the PCH file.
3050 if (ExternalSource) {
3051 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3052 ++I) {
3053 Selector Sel = ExternalSource->GetSelector(I);
3054 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3055 InstanceMethodPool.count(Sel))
3056 continue;
3057
3058 ReadMethodPool(Sel, /*isInstance=*/false);
3059 }
3060 }
3061
Douglas Gregor13438f92010-04-06 16:40:00 +00003062 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3063 M = FactoryMethodPool.begin(),
3064 MEnd = FactoryMethodPool.end();
3065 M != MEnd;
3066 ++M) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003067 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003068 MethList = MethList->Next) {
3069 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3070 NumSelIdents))
3071 continue;
3072
3073 Result R(MethList->Method, 0);
3074 R.StartParameter = NumSelIdents;
3075 R.AllParametersAreInformative = false;
3076 Results.MaybeAddResult(R, CurContext);
3077 }
3078 }
3079 }
3080
Steve Naroffc4df6d22009-11-07 02:08:14 +00003081 Results.ExitScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00003082
Steve Naroffc4df6d22009-11-07 02:08:14 +00003083 // This also suppresses remaining diagnostics.
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003084 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003085}
3086
Douglas Gregord3c68542009-11-19 01:08:35 +00003087void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3088 IdentifierInfo **SelIdents,
3089 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003090 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003091
3092 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003093
Douglas Gregor36ecb042009-11-17 23:22:23 +00003094 // If necessary, apply function/array conversion to the receiver.
3095 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003096 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003097 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003098
Douglas Gregor36ecb042009-11-17 23:22:23 +00003099 // Build the set of methods we can see.
3100 ResultBuilder Results(*this);
3101 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003102
3103 // If we're messaging an expression with type "id" or "Class", check
3104 // whether we know something special about the receiver that allows
3105 // us to assume a more-specific receiver type.
3106 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3107 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3108 ReceiverType = Context.getObjCObjectPointerType(
3109 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003110
Douglas Gregorf74a4192009-11-18 00:06:18 +00003111 // Handle messages to Class. This really isn't a message to an instance
3112 // method, so we treat it the same way we would treat a message send to a
3113 // class method.
3114 if (ReceiverType->isObjCClassType() ||
3115 ReceiverType->isObjCQualifiedClassType()) {
3116 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3117 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003118 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3119 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003120 }
3121 }
3122 // Handle messages to a qualified ID ("id<foo>").
3123 else if (const ObjCObjectPointerType *QualID
3124 = ReceiverType->getAsObjCQualifiedIdType()) {
3125 // Search protocols for instance methods.
3126 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3127 E = QualID->qual_end();
3128 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003129 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3130 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003131 }
3132 // Handle messages to a pointer to interface type.
3133 else if (const ObjCObjectPointerType *IFacePtr
3134 = ReceiverType->getAsObjCInterfacePointerType()) {
3135 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003136 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3137 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003138
3139 // Search protocols for instance methods.
3140 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3141 E = IFacePtr->qual_end();
3142 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003143 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3144 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003145 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003146 // Handle messages to "id".
3147 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003148 // We're messaging "id", so provide all instance methods we know
3149 // about as code-completion results.
3150
3151 // If we have an external source, load the entire class method
3152 // pool from the PCH file.
3153 if (ExternalSource) {
3154 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3155 ++I) {
3156 Selector Sel = ExternalSource->GetSelector(I);
3157 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3158 FactoryMethodPool.count(Sel))
3159 continue;
3160
3161 ReadMethodPool(Sel, /*isInstance=*/true);
3162 }
3163 }
3164
Douglas Gregor13438f92010-04-06 16:40:00 +00003165 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3166 M = InstanceMethodPool.begin(),
3167 MEnd = InstanceMethodPool.end();
3168 M != MEnd;
3169 ++M) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003170 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003171 MethList = MethList->Next) {
3172 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3173 NumSelIdents))
3174 continue;
3175
3176 Result R(MethList->Method, 0);
3177 R.StartParameter = NumSelIdents;
3178 R.AllParametersAreInformative = false;
3179 Results.MaybeAddResult(R, CurContext);
3180 }
3181 }
3182 }
3183
Steve Naroffc4df6d22009-11-07 02:08:14 +00003184 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003185 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003186}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003187
3188/// \brief Add all of the protocol declarations that we find in the given
3189/// (translation unit) context.
3190static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003191 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003192 ResultBuilder &Results) {
3193 typedef CodeCompleteConsumer::Result Result;
3194
3195 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3196 DEnd = Ctx->decls_end();
3197 D != DEnd; ++D) {
3198 // Record any protocols we find.
3199 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003200 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003201 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003202
3203 // Record any forward-declared protocols we find.
3204 if (ObjCForwardProtocolDecl *Forward
3205 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3206 for (ObjCForwardProtocolDecl::protocol_iterator
3207 P = Forward->protocol_begin(),
3208 PEnd = Forward->protocol_end();
3209 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003210 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003211 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003212 }
3213 }
3214}
3215
3216void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3217 unsigned NumProtocols) {
3218 ResultBuilder Results(*this);
3219 Results.EnterNewScope();
3220
3221 // Tell the result set to ignore all of the protocols we have
3222 // already seen.
3223 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003224 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3225 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00003226 Results.Ignore(Protocol);
3227
3228 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003229 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3230 Results);
3231
3232 Results.ExitScope();
3233 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3234}
3235
3236void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3237 ResultBuilder Results(*this);
3238 Results.EnterNewScope();
3239
3240 // Add all protocols.
3241 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3242 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003243
3244 Results.ExitScope();
3245 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3246}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003247
3248/// \brief Add all of the Objective-C interface declarations that we find in
3249/// the given (translation unit) context.
3250static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3251 bool OnlyForwardDeclarations,
3252 bool OnlyUnimplemented,
3253 ResultBuilder &Results) {
3254 typedef CodeCompleteConsumer::Result Result;
3255
3256 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3257 DEnd = Ctx->decls_end();
3258 D != DEnd; ++D) {
3259 // Record any interfaces we find.
3260 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3261 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3262 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003263 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003264
3265 // Record any forward-declared interfaces we find.
3266 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3267 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3268 C != CEnd; ++C)
3269 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3270 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003271 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3272 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003273 }
3274 }
3275}
3276
3277void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3278 ResultBuilder Results(*this);
3279 Results.EnterNewScope();
3280
3281 // Add all classes.
3282 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3283 false, Results);
3284
3285 Results.ExitScope();
3286 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3287}
3288
Douglas Gregorc83c6872010-04-15 22:33:43 +00003289void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3290 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003291 ResultBuilder Results(*this);
3292 Results.EnterNewScope();
3293
3294 // Make sure that we ignore the class we're currently defining.
3295 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003296 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003297 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003298 Results.Ignore(CurClass);
3299
3300 // Add all classes.
3301 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3302 false, Results);
3303
3304 Results.ExitScope();
3305 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3306}
3307
3308void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3309 ResultBuilder Results(*this);
3310 Results.EnterNewScope();
3311
3312 // Add all unimplemented classes.
3313 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3314 true, Results);
3315
3316 Results.ExitScope();
3317 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3318}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003319
3320void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00003321 IdentifierInfo *ClassName,
3322 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003323 typedef CodeCompleteConsumer::Result Result;
3324
3325 ResultBuilder Results(*this);
3326
3327 // Ignore any categories we find that have already been implemented by this
3328 // interface.
3329 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3330 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003331 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003332 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3333 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3334 Category = Category->getNextClassCategory())
3335 CategoryNames.insert(Category->getIdentifier());
3336
3337 // Add all of the categories we know about.
3338 Results.EnterNewScope();
3339 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3340 for (DeclContext::decl_iterator D = TU->decls_begin(),
3341 DEnd = TU->decls_end();
3342 D != DEnd; ++D)
3343 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3344 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003345 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003346 Results.ExitScope();
3347
3348 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3349}
3350
3351void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00003352 IdentifierInfo *ClassName,
3353 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003354 typedef CodeCompleteConsumer::Result Result;
3355
3356 // Find the corresponding interface. If we couldn't find the interface, the
3357 // program itself is ill-formed. However, we'll try to be helpful still by
3358 // providing the list of all of the categories we know about.
3359 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003360 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003361 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3362 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003363 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003364
3365 ResultBuilder Results(*this);
3366
3367 // Add all of the categories that have have corresponding interface
3368 // declarations in this class and any of its superclasses, except for
3369 // already-implemented categories in the class itself.
3370 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3371 Results.EnterNewScope();
3372 bool IgnoreImplemented = true;
3373 while (Class) {
3374 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3375 Category = Category->getNextClassCategory())
3376 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3377 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003378 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003379
3380 Class = Class->getSuperClass();
3381 IgnoreImplemented = false;
3382 }
3383 Results.ExitScope();
3384
3385 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3386}
Douglas Gregor322328b2009-11-18 22:32:06 +00003387
Douglas Gregor424b2a52009-11-18 22:56:13 +00003388void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00003389 typedef CodeCompleteConsumer::Result Result;
3390 ResultBuilder Results(*this);
3391
3392 // Figure out where this @synthesize lives.
3393 ObjCContainerDecl *Container
3394 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3395 if (!Container ||
3396 (!isa<ObjCImplementationDecl>(Container) &&
3397 !isa<ObjCCategoryImplDecl>(Container)))
3398 return;
3399
3400 // Ignore any properties that have already been implemented.
3401 for (DeclContext::decl_iterator D = Container->decls_begin(),
3402 DEnd = Container->decls_end();
3403 D != DEnd; ++D)
3404 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3405 Results.Ignore(PropertyImpl->getPropertyDecl());
3406
3407 // Add any properties that we find.
3408 Results.EnterNewScope();
3409 if (ObjCImplementationDecl *ClassImpl
3410 = dyn_cast<ObjCImplementationDecl>(Container))
3411 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3412 Results);
3413 else
3414 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3415 false, CurContext, Results);
3416 Results.ExitScope();
3417
3418 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3419}
3420
3421void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3422 IdentifierInfo *PropertyName,
3423 DeclPtrTy ObjCImpDecl) {
3424 typedef CodeCompleteConsumer::Result Result;
3425 ResultBuilder Results(*this);
3426
3427 // Figure out where this @synthesize lives.
3428 ObjCContainerDecl *Container
3429 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3430 if (!Container ||
3431 (!isa<ObjCImplementationDecl>(Container) &&
3432 !isa<ObjCCategoryImplDecl>(Container)))
3433 return;
3434
3435 // Figure out which interface we're looking into.
3436 ObjCInterfaceDecl *Class = 0;
3437 if (ObjCImplementationDecl *ClassImpl
3438 = dyn_cast<ObjCImplementationDecl>(Container))
3439 Class = ClassImpl->getClassInterface();
3440 else
3441 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3442 ->getClassInterface();
3443
3444 // Add all of the instance variables in this class and its superclasses.
3445 Results.EnterNewScope();
3446 for(; Class; Class = Class->getSuperClass()) {
3447 // FIXME: We could screen the type of each ivar for compatibility with
3448 // the property, but is that being too paternal?
3449 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3450 IVarEnd = Class->ivar_end();
3451 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00003452 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00003453 }
3454 Results.ExitScope();
3455
3456 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3457}
Douglas Gregore8f5a172010-04-07 00:21:17 +00003458
3459typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
3460
3461/// \brief Find all of the methods that reside in the given container
3462/// (and its superclasses, protocols, etc.) that meet the given
3463/// criteria. Insert those methods into the map of known methods,
3464/// indexed by selector so they can be easily found.
3465static void FindImplementableMethods(ASTContext &Context,
3466 ObjCContainerDecl *Container,
3467 bool WantInstanceMethods,
3468 QualType ReturnType,
3469 bool IsInImplementation,
3470 KnownMethodsMap &KnownMethods) {
3471 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
3472 // Recurse into protocols.
3473 const ObjCList<ObjCProtocolDecl> &Protocols
3474 = IFace->getReferencedProtocols();
3475 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3476 E = Protocols.end();
3477 I != E; ++I)
3478 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3479 IsInImplementation, KnownMethods);
3480
3481 // If we're not in the implementation of a class, also visit the
3482 // superclass.
3483 if (!IsInImplementation && IFace->getSuperClass())
3484 FindImplementableMethods(Context, IFace->getSuperClass(),
3485 WantInstanceMethods, ReturnType,
3486 IsInImplementation, KnownMethods);
3487
3488 // Add methods from any class extensions (but not from categories;
3489 // those should go into category implementations).
3490 for (ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
3491 Cat = Cat->getNextClassCategory()) {
3492 if (!Cat->IsClassExtension())
3493 continue;
3494
3495 FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
3496 IsInImplementation, KnownMethods);
3497 }
3498 }
3499
3500 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
3501 // Recurse into protocols.
3502 const ObjCList<ObjCProtocolDecl> &Protocols
3503 = Category->getReferencedProtocols();
3504 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3505 E = Protocols.end();
3506 I != E; ++I)
3507 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3508 IsInImplementation, KnownMethods);
3509 }
3510
3511 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3512 // Recurse into protocols.
3513 const ObjCList<ObjCProtocolDecl> &Protocols
3514 = Protocol->getReferencedProtocols();
3515 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3516 E = Protocols.end();
3517 I != E; ++I)
3518 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3519 IsInImplementation, KnownMethods);
3520 }
3521
3522 // Add methods in this container. This operation occurs last because
3523 // we want the methods from this container to override any methods
3524 // we've previously seen with the same selector.
3525 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3526 MEnd = Container->meth_end();
3527 M != MEnd; ++M) {
3528 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3529 if (!ReturnType.isNull() &&
3530 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
3531 continue;
3532
3533 KnownMethods[(*M)->getSelector()] = *M;
3534 }
3535 }
3536}
3537
3538void Sema::CodeCompleteObjCMethodDecl(Scope *S,
3539 bool IsInstanceMethod,
3540 TypeTy *ReturnTy,
3541 DeclPtrTy IDecl) {
3542 // Determine the return type of the method we're declaring, if
3543 // provided.
3544 QualType ReturnType = GetTypeFromParser(ReturnTy);
3545
3546 // Determine where we should start searching for methods, and where we
3547 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
3548 bool IsInImplementation = false;
3549 if (Decl *D = IDecl.getAs<Decl>()) {
3550 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
3551 SearchDecl = Impl->getClassInterface();
3552 CurrentDecl = Impl;
3553 IsInImplementation = true;
3554 } else if (ObjCCategoryImplDecl *CatImpl
3555 = dyn_cast<ObjCCategoryImplDecl>(D)) {
3556 SearchDecl = CatImpl->getCategoryDecl();
3557 CurrentDecl = CatImpl;
3558 IsInImplementation = true;
3559 } else {
3560 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
3561 CurrentDecl = SearchDecl;
3562 }
3563 }
3564
3565 if (!SearchDecl && S) {
3566 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
3567 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
3568 CurrentDecl = SearchDecl;
3569 }
3570 }
3571
3572 if (!SearchDecl || !CurrentDecl) {
3573 HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
3574 return;
3575 }
3576
3577 // Find all of the methods that we could declare/implement here.
3578 KnownMethodsMap KnownMethods;
3579 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
3580 ReturnType, IsInImplementation, KnownMethods);
3581
3582 // Erase any methods that have already been declared or
3583 // implemented here.
3584 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
3585 MEnd = CurrentDecl->meth_end();
3586 M != MEnd; ++M) {
3587 if ((*M)->isInstanceMethod() != IsInstanceMethod)
3588 continue;
3589
3590 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
3591 if (Pos != KnownMethods.end())
3592 KnownMethods.erase(Pos);
3593 }
3594
3595 // Add declarations or definitions for each of the known methods.
3596 typedef CodeCompleteConsumer::Result Result;
3597 ResultBuilder Results(*this);
3598 Results.EnterNewScope();
3599 PrintingPolicy Policy(Context.PrintingPolicy);
3600 Policy.AnonymousTagLocations = false;
3601 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
3602 MEnd = KnownMethods.end();
3603 M != MEnd; ++M) {
3604 ObjCMethodDecl *Method = M->second;
3605 CodeCompletionString *Pattern = new CodeCompletionString;
3606
3607 // If the result type was not already provided, add it to the
3608 // pattern as (type).
3609 if (ReturnType.isNull()) {
3610 std::string TypeStr;
3611 Method->getResultType().getAsStringInternal(TypeStr, Policy);
3612 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3613 Pattern->AddTextChunk(TypeStr);
3614 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3615 }
3616
3617 Selector Sel = Method->getSelector();
3618
3619 // Add the first part of the selector to the pattern.
3620 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
3621
3622 // Add parameters to the pattern.
3623 unsigned I = 0;
3624 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
3625 PEnd = Method->param_end();
3626 P != PEnd; (void)++P, ++I) {
3627 // Add the part of the selector name.
3628 if (I == 0)
3629 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3630 else if (I < Sel.getNumArgs()) {
3631 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3632 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
3633 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3634 } else
3635 break;
3636
3637 // Add the parameter type.
3638 std::string TypeStr;
3639 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
3640 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3641 Pattern->AddTextChunk(TypeStr);
3642 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3643
3644 if (IdentifierInfo *Id = (*P)->getIdentifier())
3645 Pattern->AddTextChunk(Id->getName());
3646 }
3647
3648 if (Method->isVariadic()) {
3649 if (Method->param_size() > 0)
3650 Pattern->AddChunk(CodeCompletionString::CK_Comma);
3651 Pattern->AddTextChunk("...");
3652 }
3653
3654 if (IsInImplementation) {
3655 // We will be defining the method here, so add a compound statement.
3656 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3657 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3658 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3659 if (!Method->getResultType()->isVoidType()) {
3660 // If the result type is not void, add a return clause.
3661 Pattern->AddTextChunk("return");
3662 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3663 Pattern->AddPlaceholderChunk("expression");
3664 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
3665 } else
3666 Pattern->AddPlaceholderChunk("statements");
3667
3668 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3669 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3670 }
3671
3672 Results.AddResult(Result(Pattern));
3673 }
3674
3675 Results.ExitScope();
3676
3677 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3678}