blob: e0019433732d2c9aa07b5dbe2da50d95bf5e1d3f [file] [log] [blame]
Douglas Gregor2436e712009-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 Gregorc580c522010-01-14 01:09:38 +000014#include "Lookup.h"
Douglas Gregor2436e712009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregord720daf2010-04-06 17:30:22 +000016#include "clang/Sema/ExternalSemaSource.h"
Douglas Gregorf2510672009-09-21 19:57:38 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor8ce33212009-11-17 17:59:40 +000018#include "clang/AST/ExprObjC.h"
Douglas Gregorf329c7c2009-10-30 16:50:04 +000019#include "clang/Lex/MacroInfo.h"
20#include "clang/Lex/Preprocessor.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000021#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregore6688e62009-09-28 03:51:44 +000022#include "llvm/ADT/StringExtras.h"
Douglas Gregor9d2ddb22010-04-06 19:22:33 +000023#include "llvm/ADT/StringSwitch.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000024#include <list>
25#include <map>
26#include <vector>
Douglas Gregor2436e712009-09-17 21:32:03 +000027
28using namespace clang;
29
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-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 Gregor3545ff42009-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 Gregor05e7ca32009-12-06 20:23:50 +0000108 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor3545ff42009-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 Gregor6ae4c522010-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 Gregor3545ff42009-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 Gregor6ae4c522010-01-14 03:21:49 +0000128 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000129
Douglas Gregorf64acca2010-05-25 21:41:55 +0000130 /// \brief Whether we should include code patterns in the completion
131 /// results.
132 bool includeCodePatterns() const {
133 return SemaRef.CodeCompleter &&
134 SemaRef.CodeCompleter->includeCodePatterns();
135 }
136
Douglas Gregor3545ff42009-09-21 16:56:56 +0000137 /// \brief Set the filter used for code-completion results.
138 void setFilter(LookupFilter Filter) {
139 this->Filter = Filter;
140 }
141
142 typedef std::vector<Result>::iterator iterator;
143 iterator begin() { return Results.begin(); }
144 iterator end() { return Results.end(); }
145
146 Result *data() { return Results.empty()? 0 : &Results.front(); }
147 unsigned size() const { return Results.size(); }
148 bool empty() const { return Results.empty(); }
149
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000150 /// \brief Specify whether nested-name-specifiers are allowed.
151 void allowNestedNameSpecifiers(bool Allow = true) {
152 AllowNestedNameSpecifiers = Allow;
153 }
154
Douglas Gregor7c208612010-01-14 00:20:49 +0000155 /// \brief Determine whether the given declaration is at all interesting
156 /// as a code-completion result.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000157 ///
158 /// \param ND the declaration that we are inspecting.
159 ///
160 /// \param AsNestedNameSpecifier will be set true if this declaration is
161 /// only interesting when it is a nested-name-specifier.
162 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregore0717ab2010-01-14 00:41:07 +0000163
164 /// \brief Check whether the result is hidden by the Hiding declaration.
165 ///
166 /// \returns true if the result is hidden and cannot be found, false if
167 /// the hidden result could still be found. When false, \p R may be
168 /// modified to describe how the result can be found (e.g., via extra
169 /// qualification).
170 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
171 NamedDecl *Hiding);
172
Douglas Gregor3545ff42009-09-21 16:56:56 +0000173 /// \brief Add a new result to this result set (if it isn't already in one
174 /// of the shadow maps), or replace an existing result (for, e.g., a
175 /// redeclaration).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000176 ///
Douglas Gregorc580c522010-01-14 01:09:38 +0000177 /// \param CurContext the result to add (if it is unique).
Douglas Gregor2af2f672009-09-21 20:12:40 +0000178 ///
179 /// \param R the context in which this result will be named.
180 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000181
Douglas Gregorc580c522010-01-14 01:09:38 +0000182 /// \brief Add a new result to this result set, where we already know
183 /// the hiding declation (if any).
184 ///
185 /// \param R the result to add (if it is unique).
186 ///
187 /// \param CurContext the context in which this result will be named.
188 ///
189 /// \param Hiding the declaration that hides the result.
Douglas Gregor09bbc652010-01-14 15:47:35 +0000190 ///
191 /// \param InBaseClass whether the result was found in a base
192 /// class of the searched context.
193 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
194 bool InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000195
Douglas Gregor78a21012010-01-14 16:01:26 +0000196 /// \brief Add a new non-declaration result to this result set.
197 void AddResult(Result R);
198
Douglas Gregor3545ff42009-09-21 16:56:56 +0000199 /// \brief Enter into a new scope.
200 void EnterNewScope();
201
202 /// \brief Exit from the current scope.
203 void ExitScope();
204
Douglas Gregorbaf69612009-11-18 04:19:12 +0000205 /// \brief Ignore this declaration, if it is seen again.
206 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
207
Douglas Gregor3545ff42009-09-21 16:56:56 +0000208 /// \name Name lookup predicates
209 ///
210 /// These predicates can be passed to the name lookup functions to filter the
211 /// results of name lookup. All of the predicates have the same type, so that
212 ///
213 //@{
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000214 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000215 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000216 bool IsNestedNameSpecifier(NamedDecl *ND) const;
217 bool IsEnum(NamedDecl *ND) const;
218 bool IsClassOrStruct(NamedDecl *ND) const;
219 bool IsUnion(NamedDecl *ND) const;
220 bool IsNamespace(NamedDecl *ND) const;
221 bool IsNamespaceOrAlias(NamedDecl *ND) const;
222 bool IsType(NamedDecl *ND) const;
Douglas Gregore412a5a2009-09-23 22:26:46 +0000223 bool IsMember(NamedDecl *ND) const;
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000224 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000225 //@}
226 };
227}
228
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000229class ResultBuilder::ShadowMapEntry::iterator {
230 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
231 unsigned SingleDeclIndex;
232
233public:
234 typedef DeclIndexPair value_type;
235 typedef value_type reference;
236 typedef std::ptrdiff_t difference_type;
237 typedef std::input_iterator_tag iterator_category;
238
239 class pointer {
240 DeclIndexPair Value;
241
242 public:
243 pointer(const DeclIndexPair &Value) : Value(Value) { }
244
245 const DeclIndexPair *operator->() const {
246 return &Value;
247 }
248 };
249
250 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
251
252 iterator(NamedDecl *SingleDecl, unsigned Index)
253 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
254
255 iterator(const DeclIndexPair *Iterator)
256 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
257
258 iterator &operator++() {
259 if (DeclOrIterator.is<NamedDecl *>()) {
260 DeclOrIterator = (NamedDecl *)0;
261 SingleDeclIndex = 0;
262 return *this;
263 }
264
265 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
266 ++I;
267 DeclOrIterator = I;
268 return *this;
269 }
270
271 iterator operator++(int) {
272 iterator tmp(*this);
273 ++(*this);
274 return tmp;
275 }
276
277 reference operator*() const {
278 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
279 return reference(ND, SingleDeclIndex);
280
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000281 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000282 }
283
284 pointer operator->() const {
285 return pointer(**this);
286 }
287
288 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000289 return X.DeclOrIterator.getOpaqueValue()
290 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000291 X.SingleDeclIndex == Y.SingleDeclIndex;
292 }
293
294 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000295 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000296 }
297};
298
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000299ResultBuilder::ShadowMapEntry::iterator
300ResultBuilder::ShadowMapEntry::begin() const {
301 if (DeclOrVector.isNull())
302 return iterator();
303
304 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
305 return iterator(ND, SingleDeclIndex);
306
307 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
308}
309
310ResultBuilder::ShadowMapEntry::iterator
311ResultBuilder::ShadowMapEntry::end() const {
312 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
313 return iterator();
314
315 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
316}
317
Douglas Gregor2af2f672009-09-21 20:12:40 +0000318/// \brief Compute the qualification required to get from the current context
319/// (\p CurContext) to the target context (\p TargetContext).
320///
321/// \param Context the AST context in which the qualification will be used.
322///
323/// \param CurContext the context where an entity is being named, which is
324/// typically based on the current scope.
325///
326/// \param TargetContext the context in which the named entity actually
327/// resides.
328///
329/// \returns a nested name specifier that refers into the target context, or
330/// NULL if no qualification is needed.
331static NestedNameSpecifier *
332getRequiredQualification(ASTContext &Context,
333 DeclContext *CurContext,
334 DeclContext *TargetContext) {
335 llvm::SmallVector<DeclContext *, 4> TargetParents;
336
337 for (DeclContext *CommonAncestor = TargetContext;
338 CommonAncestor && !CommonAncestor->Encloses(CurContext);
339 CommonAncestor = CommonAncestor->getLookupParent()) {
340 if (CommonAncestor->isTransparentContext() ||
341 CommonAncestor->isFunctionOrMethod())
342 continue;
343
344 TargetParents.push_back(CommonAncestor);
345 }
346
347 NestedNameSpecifier *Result = 0;
348 while (!TargetParents.empty()) {
349 DeclContext *Parent = TargetParents.back();
350 TargetParents.pop_back();
351
352 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
353 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
354 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
355 Result = NestedNameSpecifier::Create(Context, Result,
356 false,
357 Context.getTypeDeclType(TD).getTypePtr());
358 else
359 assert(Parent->isTranslationUnit());
Douglas Gregor9eb77012009-11-07 00:00:49 +0000360 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000361 return Result;
362}
363
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000364bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
365 bool &AsNestedNameSpecifier) const {
366 AsNestedNameSpecifier = false;
367
Douglas Gregor7c208612010-01-14 00:20:49 +0000368 ND = ND->getUnderlyingDecl();
369 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregor58acf322009-10-09 22:16:47 +0000370
371 // Skip unnamed entities.
Douglas Gregor7c208612010-01-14 00:20:49 +0000372 if (!ND->getDeclName())
373 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000374
375 // Friend declarations and declarations introduced due to friends are never
376 // added as results.
John McCallbbbbe4e2010-03-11 07:50:04 +0000377 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregor7c208612010-01-14 00:20:49 +0000378 return false;
379
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000380 // Class template (partial) specializations are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000381 if (isa<ClassTemplateSpecializationDecl>(ND) ||
382 isa<ClassTemplatePartialSpecializationDecl>(ND))
383 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000384
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000385 // Using declarations themselves are never added as results.
Douglas Gregor7c208612010-01-14 00:20:49 +0000386 if (isa<UsingDecl>(ND))
387 return false;
388
389 // Some declarations have reserved names that we don't want to ever show.
390 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000391 // __va_list_tag is a freak of nature. Find it and skip it.
392 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregor7c208612010-01-14 00:20:49 +0000393 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000394
Douglas Gregor58acf322009-10-09 22:16:47 +0000395 // Filter out names reserved for the implementation (C99 7.1.3,
396 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000397 //
398 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000399 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000400 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000401 if (Name[0] == '_' &&
402 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregor7c208612010-01-14 00:20:49 +0000403 return false;
Douglas Gregor58acf322009-10-09 22:16:47 +0000404 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000405 }
Douglas Gregor7c208612010-01-14 00:20:49 +0000406
Douglas Gregor3545ff42009-09-21 16:56:56 +0000407 // C++ constructors are never found by name lookup.
Douglas Gregor7c208612010-01-14 00:20:49 +0000408 if (isa<CXXConstructorDecl>(ND))
409 return false;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000410
411 // Filter out any unwanted results.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000412 if (Filter && !(this->*Filter)(ND)) {
413 // Check whether it is interesting as a nested-name-specifier.
414 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
415 IsNestedNameSpecifier(ND) &&
416 (Filter != &ResultBuilder::IsMember ||
417 (isa<CXXRecordDecl>(ND) &&
418 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
419 AsNestedNameSpecifier = true;
420 return true;
421 }
422
Douglas Gregor7c208612010-01-14 00:20:49 +0000423 return false;
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000424 }
John McCalle87beb22010-04-23 18:46:30 +0000425
426 if (Filter == &ResultBuilder::IsNestedNameSpecifier)
427 AsNestedNameSpecifier = true;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000428
Douglas Gregor7c208612010-01-14 00:20:49 +0000429 // ... then it must be interesting!
430 return true;
431}
432
Douglas Gregore0717ab2010-01-14 00:41:07 +0000433bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
434 NamedDecl *Hiding) {
435 // In C, there is no way to refer to a hidden name.
436 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
437 // name if we introduce the tag type.
438 if (!SemaRef.getLangOptions().CPlusPlus)
439 return true;
440
441 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
442
443 // There is no way to qualify a name declared in a function or method.
444 if (HiddenCtx->isFunctionOrMethod())
445 return true;
446
447 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
448 return true;
449
450 // We can refer to the result with the appropriate qualification. Do it.
451 R.Hidden = true;
452 R.QualifierIsInformative = false;
453
454 if (!R.Qualifier)
455 R.Qualifier = getRequiredQualification(SemaRef.Context,
456 CurContext,
457 R.Declaration->getDeclContext());
458 return false;
459}
460
Douglas Gregor7c208612010-01-14 00:20:49 +0000461void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
462 assert(!ShadowMaps.empty() && "Must enter into a results scope");
463
464 if (R.Kind != Result::RK_Declaration) {
465 // For non-declaration results, just add the result.
466 Results.push_back(R);
467 return;
468 }
469
470 // Look through using declarations.
471 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
472 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
473 return;
474 }
475
476 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
477 unsigned IDNS = CanonDecl->getIdentifierNamespace();
478
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000479 bool AsNestedNameSpecifier = false;
480 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor7c208612010-01-14 00:20:49 +0000481 return;
482
Douglas Gregor3545ff42009-09-21 16:56:56 +0000483 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000484 ShadowMapEntry::iterator I, IEnd;
485 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
486 if (NamePos != SMap.end()) {
487 I = NamePos->second.begin();
488 IEnd = NamePos->second.end();
489 }
490
491 for (; I != IEnd; ++I) {
492 NamedDecl *ND = I->first;
493 unsigned Index = I->second;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000494 if (ND->getCanonicalDecl() == CanonDecl) {
495 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000496 Results[Index].Declaration = R.Declaration;
497
Douglas Gregor3545ff42009-09-21 16:56:56 +0000498 // We're done.
499 return;
500 }
501 }
502
503 // This is a new declaration in this scope. However, check whether this
504 // declaration name is hidden by a similarly-named declaration in an outer
505 // scope.
506 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
507 --SMEnd;
508 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000509 ShadowMapEntry::iterator I, IEnd;
510 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
511 if (NamePos != SM->end()) {
512 I = NamePos->second.begin();
513 IEnd = NamePos->second.end();
514 }
515 for (; I != IEnd; ++I) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000516 // A tag declaration does not hide a non-tag declaration.
John McCalle87beb22010-04-23 18:46:30 +0000517 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor3545ff42009-09-21 16:56:56 +0000518 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
519 Decl::IDNS_ObjCProtocol)))
520 continue;
521
522 // Protocols are in distinct namespaces from everything else.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000523 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000524 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000525 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000526 continue;
527
528 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregore0717ab2010-01-14 00:41:07 +0000529 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor3545ff42009-09-21 16:56:56 +0000530 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000531
532 break;
533 }
534 }
535
536 // Make sure that any given declaration only shows up in the result set once.
537 if (!AllDeclsFound.insert(CanonDecl))
538 return;
539
Douglas Gregore412a5a2009-09-23 22:26:46 +0000540 // If the filter is for nested-name-specifiers, then this result starts a
541 // nested-name-specifier.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000542 if (AsNestedNameSpecifier)
Douglas Gregore412a5a2009-09-23 22:26:46 +0000543 R.StartsNestedNameSpecifier = true;
544
Douglas Gregor5bf52692009-09-22 23:15:58 +0000545 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000546 if (R.QualifierIsInformative && !R.Qualifier &&
547 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-09-22 23:15:58 +0000548 DeclContext *Ctx = R.Declaration->getDeclContext();
549 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
550 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
551 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
552 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
553 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
554 else
555 R.QualifierIsInformative = false;
556 }
Douglas Gregore412a5a2009-09-23 22:26:46 +0000557
Douglas Gregor3545ff42009-09-21 16:56:56 +0000558 // Insert this result into the set of results and into the current shadow
559 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000560 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-09-21 16:56:56 +0000561 Results.push_back(R);
562}
563
Douglas Gregorc580c522010-01-14 01:09:38 +0000564void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor09bbc652010-01-14 15:47:35 +0000565 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000566 if (R.Kind != Result::RK_Declaration) {
567 // For non-declaration results, just add the result.
568 Results.push_back(R);
569 return;
570 }
571
Douglas Gregorc580c522010-01-14 01:09:38 +0000572 // Look through using declarations.
573 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
574 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
575 return;
576 }
577
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000578 bool AsNestedNameSpecifier = false;
579 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregorc580c522010-01-14 01:09:38 +0000580 return;
581
582 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
583 return;
584
585 // Make sure that any given declaration only shows up in the result set once.
586 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
587 return;
588
589 // If the filter is for nested-name-specifiers, then this result starts a
590 // nested-name-specifier.
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000591 if (AsNestedNameSpecifier)
Douglas Gregorc580c522010-01-14 01:09:38 +0000592 R.StartsNestedNameSpecifier = true;
Douglas Gregor09bbc652010-01-14 15:47:35 +0000593 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
594 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
595 ->getLookupContext()))
596 R.QualifierIsInformative = true;
597
Douglas Gregorc580c522010-01-14 01:09:38 +0000598 // If this result is supposed to have an informative qualifier, add one.
599 if (R.QualifierIsInformative && !R.Qualifier &&
600 !R.StartsNestedNameSpecifier) {
601 DeclContext *Ctx = R.Declaration->getDeclContext();
602 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
603 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
604 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
605 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor6ae4c522010-01-14 03:21:49 +0000606 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregorc580c522010-01-14 01:09:38 +0000607 else
608 R.QualifierIsInformative = false;
609 }
610
611 // Insert this result into the set of results.
612 Results.push_back(R);
613}
614
Douglas Gregor78a21012010-01-14 16:01:26 +0000615void ResultBuilder::AddResult(Result R) {
616 assert(R.Kind != Result::RK_Declaration &&
617 "Declaration results need more context");
618 Results.push_back(R);
619}
620
Douglas Gregor3545ff42009-09-21 16:56:56 +0000621/// \brief Enter into a new scope.
622void ResultBuilder::EnterNewScope() {
623 ShadowMaps.push_back(ShadowMap());
624}
625
626/// \brief Exit from the current scope.
627void ResultBuilder::ExitScope() {
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000628 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
629 EEnd = ShadowMaps.back().end();
630 E != EEnd;
631 ++E)
632 E->second.Destroy();
633
Douglas Gregor3545ff42009-09-21 16:56:56 +0000634 ShadowMaps.pop_back();
635}
636
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000637/// \brief Determines whether this given declaration will be found by
638/// ordinary name lookup.
639bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
640 unsigned IDNS = Decl::IDNS_Ordinary;
641 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000642 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregorc580c522010-01-14 01:09:38 +0000643 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
644 return true;
645
Douglas Gregor9d64c5e2009-09-21 20:51:25 +0000646 return ND->getIdentifierNamespace() & IDNS;
647}
648
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000649/// \brief Determines whether this given declaration will be found by
650/// ordinary name lookup.
651bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
652 unsigned IDNS = Decl::IDNS_Ordinary;
653 if (SemaRef.getLangOptions().CPlusPlus)
John McCalle87beb22010-04-23 18:46:30 +0000654 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000655
656 return (ND->getIdentifierNamespace() & IDNS) &&
657 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
658}
659
Douglas Gregor3545ff42009-09-21 16:56:56 +0000660/// \brief Determines whether the given declaration is suitable as the
661/// start of a C++ nested-name-specifier, e.g., a class or namespace.
662bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
663 // Allow us to find class templates, too.
664 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
665 ND = ClassTemplate->getTemplatedDecl();
666
667 return SemaRef.isAcceptableNestedNameSpecifier(ND);
668}
669
670/// \brief Determines whether the given declaration is an enumeration.
671bool ResultBuilder::IsEnum(NamedDecl *ND) const {
672 return isa<EnumDecl>(ND);
673}
674
675/// \brief Determines whether the given declaration is a class or struct.
676bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
677 // Allow us to find class templates, too.
678 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
679 ND = ClassTemplate->getTemplatedDecl();
680
681 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000682 return RD->getTagKind() == TTK_Class ||
683 RD->getTagKind() == TTK_Struct;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000684
685 return false;
686}
687
688/// \brief Determines whether the given declaration is a union.
689bool ResultBuilder::IsUnion(NamedDecl *ND) const {
690 // Allow us to find class templates, too.
691 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
692 ND = ClassTemplate->getTemplatedDecl();
693
694 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara6150c882010-05-11 21:36:43 +0000695 return RD->getTagKind() == TTK_Union;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000696
697 return false;
698}
699
700/// \brief Determines whether the given declaration is a namespace.
701bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
702 return isa<NamespaceDecl>(ND);
703}
704
705/// \brief Determines whether the given declaration is a namespace or
706/// namespace alias.
707bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
708 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
709}
710
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000711/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000712bool ResultBuilder::IsType(NamedDecl *ND) const {
713 return isa<TypeDecl>(ND);
714}
715
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000716/// \brief Determines which members of a class should be visible via
717/// "." or "->". Only value declarations, nested name specifiers, and
718/// using declarations thereof should show up.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000719bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000720 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
721 ND = Using->getTargetDecl();
722
Douglas Gregor70788392009-12-11 18:14:22 +0000723 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
724 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000725}
726
Douglas Gregor2b8162b2010-01-14 16:08:12 +0000727/// \rief Determines whether the given declaration is an Objective-C
728/// instance variable.
729bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
730 return isa<ObjCIvarDecl>(ND);
731}
732
Douglas Gregorc580c522010-01-14 01:09:38 +0000733namespace {
734 /// \brief Visible declaration consumer that adds a code-completion result
735 /// for each visible declaration.
736 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
737 ResultBuilder &Results;
738 DeclContext *CurContext;
739
740 public:
741 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
742 : Results(Results), CurContext(CurContext) { }
743
Douglas Gregor09bbc652010-01-14 15:47:35 +0000744 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
745 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregorc580c522010-01-14 01:09:38 +0000746 }
747 };
748}
749
Douglas Gregor3545ff42009-09-21 16:56:56 +0000750/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000751static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor3545ff42009-09-21 16:56:56 +0000752 ResultBuilder &Results) {
753 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +0000754 Results.AddResult(Result("short"));
755 Results.AddResult(Result("long"));
756 Results.AddResult(Result("signed"));
757 Results.AddResult(Result("unsigned"));
758 Results.AddResult(Result("void"));
759 Results.AddResult(Result("char"));
760 Results.AddResult(Result("int"));
761 Results.AddResult(Result("float"));
762 Results.AddResult(Result("double"));
763 Results.AddResult(Result("enum"));
764 Results.AddResult(Result("struct"));
765 Results.AddResult(Result("union"));
766 Results.AddResult(Result("const"));
767 Results.AddResult(Result("volatile"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000768
Douglas Gregor3545ff42009-09-21 16:56:56 +0000769 if (LangOpts.C99) {
770 // C99-specific
Douglas Gregor78a21012010-01-14 16:01:26 +0000771 Results.AddResult(Result("_Complex"));
772 Results.AddResult(Result("_Imaginary"));
773 Results.AddResult(Result("_Bool"));
774 Results.AddResult(Result("restrict"));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000775 }
776
777 if (LangOpts.CPlusPlus) {
778 // C++-specific
Douglas Gregor78a21012010-01-14 16:01:26 +0000779 Results.AddResult(Result("bool"));
780 Results.AddResult(Result("class"));
781 Results.AddResult(Result("wchar_t"));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000782
Douglas Gregorf64acca2010-05-25 21:41:55 +0000783 if (Results.includeCodePatterns()) {
784 // typename qualified-id
785 CodeCompletionString *Pattern = new CodeCompletionString;
786 Pattern->AddTypedTextChunk("typename");
787 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
788 Pattern->AddPlaceholderChunk("qualified-id");
789 Results.AddResult(Result(Pattern));
790 }
791
Douglas Gregor3545ff42009-09-21 16:56:56 +0000792 if (LangOpts.CPlusPlus0x) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000793 Results.AddResult(Result("auto"));
794 Results.AddResult(Result("char16_t"));
795 Results.AddResult(Result("char32_t"));
796 Results.AddResult(Result("decltype"));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000797 }
798 }
799
800 // GNU extensions
801 if (LangOpts.GNUMode) {
802 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregor78a21012010-01-14 16:01:26 +0000803 // Results.AddResult(Result("_Decimal32"));
804 // Results.AddResult(Result("_Decimal64"));
805 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000806
Douglas Gregorf64acca2010-05-25 21:41:55 +0000807 if (Results.includeCodePatterns()) {
808 CodeCompletionString *Pattern = new CodeCompletionString;
809 Pattern->AddTypedTextChunk("typeof");
810 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
811 Pattern->AddPlaceholderChunk("expression-or-type");
812 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
813 Results.AddResult(Result(Pattern));
814 }
Douglas Gregor3545ff42009-09-21 16:56:56 +0000815 }
816}
817
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000818static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
819 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000820 ResultBuilder &Results) {
821 typedef CodeCompleteConsumer::Result Result;
822 // Note: we don't suggest either "auto" or "register", because both
823 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
824 // in C++0x as a type specifier.
Douglas Gregor78a21012010-01-14 16:01:26 +0000825 Results.AddResult(Result("extern"));
826 Results.AddResult(Result("static"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000827}
828
829static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
830 const LangOptions &LangOpts,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000831 ResultBuilder &Results) {
832 typedef CodeCompleteConsumer::Result Result;
833 switch (CCC) {
834 case Action::CCC_Class:
835 case Action::CCC_MemberTemplate:
836 if (LangOpts.CPlusPlus) {
Douglas Gregor78a21012010-01-14 16:01:26 +0000837 Results.AddResult(Result("explicit"));
838 Results.AddResult(Result("friend"));
839 Results.AddResult(Result("mutable"));
840 Results.AddResult(Result("virtual"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000841 }
842 // Fall through
843
Douglas Gregorf1934162010-01-13 21:24:21 +0000844 case Action::CCC_ObjCInterface:
845 case Action::CCC_ObjCImplementation:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000846 case Action::CCC_Namespace:
847 case Action::CCC_Template:
848 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregor78a21012010-01-14 16:01:26 +0000849 Results.AddResult(Result("inline"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000850 break;
851
Douglas Gregor48d46252010-01-13 21:54:15 +0000852 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000853 case Action::CCC_Expression:
854 case Action::CCC_Statement:
855 case Action::CCC_ForInit:
856 case Action::CCC_Condition:
Douglas Gregor6da3db42010-05-25 05:58:43 +0000857 case Action::CCC_RecoveryInFunction:
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000858 break;
859 }
860}
861
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000862static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
863static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
864static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +0000865 ResultBuilder &Results,
866 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000867static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000868 ResultBuilder &Results,
869 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000870static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +0000871 ResultBuilder &Results,
872 bool NeedAt);
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000873static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorf1934162010-01-13 21:24:21 +0000874
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000875/// \brief Add language constructs that show up for "ordinary" names.
876static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
877 Scope *S,
878 Sema &SemaRef,
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000879 ResultBuilder &Results) {
880 typedef CodeCompleteConsumer::Result Result;
881 switch (CCC) {
882 case Action::CCC_Namespace:
Douglas Gregorf64acca2010-05-25 21:41:55 +0000883 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000884 // namespace <identifier> { }
885 CodeCompletionString *Pattern = new CodeCompletionString;
886 Pattern->AddTypedTextChunk("namespace");
887 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
888 Pattern->AddPlaceholderChunk("identifier");
889 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
890 Pattern->AddPlaceholderChunk("declarations");
891 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
892 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +0000893 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000894
895 // namespace identifier = identifier ;
896 Pattern = new CodeCompletionString;
897 Pattern->AddTypedTextChunk("namespace");
898 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
899 Pattern->AddPlaceholderChunk("identifier");
900 Pattern->AddChunk(CodeCompletionString::CK_Equal);
901 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +0000902 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000903
904 // Using directives
905 Pattern = new CodeCompletionString;
906 Pattern->AddTypedTextChunk("using");
907 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
908 Pattern->AddTextChunk("namespace");
909 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
910 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +0000911 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000912
913 // asm(string-literal)
914 Pattern = new CodeCompletionString;
915 Pattern->AddTypedTextChunk("asm");
916 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
917 Pattern->AddPlaceholderChunk("string-literal");
918 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +0000919 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000920
921 // Explicit template instantiation
922 Pattern = new CodeCompletionString;
923 Pattern->AddTypedTextChunk("template");
924 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
925 Pattern->AddPlaceholderChunk("declaration");
Douglas Gregor78a21012010-01-14 16:01:26 +0000926 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000927 }
Douglas Gregorf1934162010-01-13 21:24:21 +0000928
929 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000930 AddObjCTopLevelResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +0000931
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000932 // Fall through
933
934 case Action::CCC_Class:
Douglas Gregorf64acca2010-05-25 21:41:55 +0000935 if (Results.includeCodePatterns())
936 Results.AddResult(Result("typedef"));
937
938 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000939 // Using declaration
940 CodeCompletionString *Pattern = new CodeCompletionString;
941 Pattern->AddTypedTextChunk("using");
942 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
943 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregor78a21012010-01-14 16:01:26 +0000944 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000945
946 // using typename qualified-id; (only in a dependent context)
947 if (SemaRef.CurContext->isDependentContext()) {
948 Pattern = new CodeCompletionString;
949 Pattern->AddTypedTextChunk("using");
950 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
951 Pattern->AddTextChunk("typename");
952 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
953 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregor78a21012010-01-14 16:01:26 +0000954 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000955 }
956
957 if (CCC == Action::CCC_Class) {
958 // public:
959 Pattern = new CodeCompletionString;
960 Pattern->AddTypedTextChunk("public");
961 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000962 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000963
964 // protected:
965 Pattern = new CodeCompletionString;
966 Pattern->AddTypedTextChunk("protected");
967 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000968 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000969
970 // private:
971 Pattern = new CodeCompletionString;
972 Pattern->AddTypedTextChunk("private");
973 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +0000974 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000975 }
976 }
977 // Fall through
978
979 case Action::CCC_Template:
980 case Action::CCC_MemberTemplate:
Douglas Gregorf64acca2010-05-25 21:41:55 +0000981 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000982 // template < parameters >
983 CodeCompletionString *Pattern = new CodeCompletionString;
984 Pattern->AddTypedTextChunk("template");
985 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
986 Pattern->AddPlaceholderChunk("parameters");
987 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregor78a21012010-01-14 16:01:26 +0000988 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000989 }
990
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000991 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
992 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +0000993 break;
994
Douglas Gregorf1934162010-01-13 21:24:21 +0000995 case Action::CCC_ObjCInterface:
Douglas Gregorf98e6a22010-01-13 23:51:12 +0000996 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
997 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
998 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +0000999 break;
1000
1001 case Action::CCC_ObjCImplementation:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001002 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1003 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1004 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorf1934162010-01-13 21:24:21 +00001005 break;
1006
Douglas Gregor48d46252010-01-13 21:54:15 +00001007 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001008 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregor48d46252010-01-13 21:54:15 +00001009 break;
1010
Douglas Gregor6da3db42010-05-25 05:58:43 +00001011 case Action::CCC_RecoveryInFunction:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001012 case Action::CCC_Statement: {
Douglas Gregorf64acca2010-05-25 21:41:55 +00001013 if (Results.includeCodePatterns())
1014 Results.AddResult(Result("typedef"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001015
1016 CodeCompletionString *Pattern = 0;
Douglas Gregorf64acca2010-05-25 21:41:55 +00001017 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001018 Pattern = new CodeCompletionString;
1019 Pattern->AddTypedTextChunk("try");
1020 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1021 Pattern->AddPlaceholderChunk("statements");
1022 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1023 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1024 Pattern->AddTextChunk("catch");
1025 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1026 Pattern->AddPlaceholderChunk("declaration");
1027 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1028 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1029 Pattern->AddPlaceholderChunk("statements");
1030 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1031 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00001032 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001033 }
Douglas Gregorf1934162010-01-13 21:24:21 +00001034 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001035 AddObjCStatementResults(Results, true);
Douglas Gregorf1934162010-01-13 21:24:21 +00001036
Douglas Gregorf64acca2010-05-25 21:41:55 +00001037 if (Results.includeCodePatterns()) {
1038 // if (condition) { statements }
1039 Pattern = new CodeCompletionString;
1040 Pattern->AddTypedTextChunk("if");
1041 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1042 if (SemaRef.getLangOptions().CPlusPlus)
1043 Pattern->AddPlaceholderChunk("condition");
1044 else
1045 Pattern->AddPlaceholderChunk("expression");
1046 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1047 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1048 Pattern->AddPlaceholderChunk("statements");
1049 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1050 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1051 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001052
Douglas Gregorf64acca2010-05-25 21:41:55 +00001053 // switch (condition) { }
1054 Pattern = new CodeCompletionString;
1055 Pattern->AddTypedTextChunk("switch");
1056 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1057 if (SemaRef.getLangOptions().CPlusPlus)
1058 Pattern->AddPlaceholderChunk("condition");
1059 else
1060 Pattern->AddPlaceholderChunk("expression");
1061 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1062 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1063 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1064 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1065 Results.AddResult(Result(Pattern));
1066 }
1067
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001068 // Switch-specific statements.
Douglas Gregorf64acca2010-05-25 21:41:55 +00001069 if (!SemaRef.getSwitchStack().empty() && Results.includeCodePatterns()) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001070 // case expression:
1071 Pattern = new CodeCompletionString;
1072 Pattern->AddTypedTextChunk("case");
1073 Pattern->AddPlaceholderChunk("expression");
1074 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001075 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001076
1077 // default:
1078 Pattern = new CodeCompletionString;
1079 Pattern->AddTypedTextChunk("default");
1080 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregor78a21012010-01-14 16:01:26 +00001081 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001082 }
1083
Douglas Gregorf64acca2010-05-25 21:41:55 +00001084 if (Results.includeCodePatterns()) {
1085 /// while (condition) { statements }
1086 Pattern = new CodeCompletionString;
1087 Pattern->AddTypedTextChunk("while");
1088 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1089 if (SemaRef.getLangOptions().CPlusPlus)
1090 Pattern->AddPlaceholderChunk("condition");
1091 else
1092 Pattern->AddPlaceholderChunk("expression");
1093 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1094 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1095 Pattern->AddPlaceholderChunk("statements");
1096 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1097 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1098 Results.AddResult(Result(Pattern));
1099
1100 // do { statements } while ( expression );
1101 Pattern = new CodeCompletionString;
1102 Pattern->AddTypedTextChunk("do");
1103 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1104 Pattern->AddPlaceholderChunk("statements");
1105 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1106 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1107 Pattern->AddTextChunk("while");
1108 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001109 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorf64acca2010-05-25 21:41:55 +00001110 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1111 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001112
Douglas Gregorf64acca2010-05-25 21:41:55 +00001113 // for ( for-init-statement ; condition ; expression ) { statements }
1114 Pattern = new CodeCompletionString;
1115 Pattern->AddTypedTextChunk("for");
1116 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1117 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1118 Pattern->AddPlaceholderChunk("init-statement");
1119 else
1120 Pattern->AddPlaceholderChunk("init-expression");
1121 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1122 Pattern->AddPlaceholderChunk("condition");
1123 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1124 Pattern->AddPlaceholderChunk("inc-expression");
1125 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1126 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1127 Pattern->AddPlaceholderChunk("statements");
1128 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1129 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1130 Results.AddResult(Result(Pattern));
1131 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001132
1133 if (S->getContinueParent()) {
1134 // continue ;
1135 Pattern = new CodeCompletionString;
1136 Pattern->AddTypedTextChunk("continue");
Douglas Gregor78a21012010-01-14 16:01:26 +00001137 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001138 }
1139
1140 if (S->getBreakParent()) {
1141 // break ;
1142 Pattern = new CodeCompletionString;
1143 Pattern->AddTypedTextChunk("break");
Douglas Gregor78a21012010-01-14 16:01:26 +00001144 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001145 }
1146
1147 // "return expression ;" or "return ;", depending on whether we
1148 // know the function is void or not.
1149 bool isVoid = false;
1150 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1151 isVoid = Function->getResultType()->isVoidType();
1152 else if (ObjCMethodDecl *Method
1153 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1154 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9a28e842010-03-01 23:15:13 +00001155 else if (SemaRef.getCurBlock() &&
1156 !SemaRef.getCurBlock()->ReturnType.isNull())
1157 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001158 Pattern = new CodeCompletionString;
1159 Pattern->AddTypedTextChunk("return");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001160 if (!isVoid) {
1161 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001162 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor44272ca2010-02-18 04:06:48 +00001163 }
Douglas Gregor78a21012010-01-14 16:01:26 +00001164 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001165
Douglas Gregorf64acca2010-05-25 21:41:55 +00001166 if (Results.includeCodePatterns()) {
1167 // goto identifier ;
1168 Pattern = new CodeCompletionString;
1169 Pattern->AddTypedTextChunk("goto");
1170 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1171 Pattern->AddPlaceholderChunk("identifier");
1172 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001173
Douglas Gregorf64acca2010-05-25 21:41:55 +00001174 // Using directives
1175 Pattern = new CodeCompletionString;
1176 Pattern->AddTypedTextChunk("using");
1177 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1178 Pattern->AddTextChunk("namespace");
1179 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1180 Pattern->AddPlaceholderChunk("identifier");
1181 Results.AddResult(Result(Pattern));
1182 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001183 }
1184
1185 // Fall through (for statement expressions).
1186 case Action::CCC_ForInit:
1187 case Action::CCC_Condition:
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001188 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001189 // Fall through: conditions and statements can have expressions.
1190
1191 case Action::CCC_Expression: {
1192 CodeCompletionString *Pattern = 0;
1193 if (SemaRef.getLangOptions().CPlusPlus) {
1194 // 'this', if we're in a non-static member function.
1195 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1196 if (!Method->isStatic())
Douglas Gregor78a21012010-01-14 16:01:26 +00001197 Results.AddResult(Result("this"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001198
1199 // true, false
Douglas Gregor78a21012010-01-14 16:01:26 +00001200 Results.AddResult(Result("true"));
1201 Results.AddResult(Result("false"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001202
Douglas Gregorf64acca2010-05-25 21:41:55 +00001203 if (Results.includeCodePatterns()) {
1204 // dynamic_cast < type-id > ( expression )
1205 Pattern = new CodeCompletionString;
1206 Pattern->AddTypedTextChunk("dynamic_cast");
1207 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1208 Pattern->AddPlaceholderChunk("type-id");
1209 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1210 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1211 Pattern->AddPlaceholderChunk("expression");
1212 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1213 Results.AddResult(Result(Pattern));
1214
1215 // static_cast < type-id > ( expression )
1216 Pattern = new CodeCompletionString;
1217 Pattern->AddTypedTextChunk("static_cast");
1218 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1219 Pattern->AddPlaceholderChunk("type-id");
1220 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1221 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1222 Pattern->AddPlaceholderChunk("expression");
1223 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1224 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001225
Douglas Gregorf64acca2010-05-25 21:41:55 +00001226 // reinterpret_cast < type-id > ( expression )
1227 Pattern = new CodeCompletionString;
1228 Pattern->AddTypedTextChunk("reinterpret_cast");
1229 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1230 Pattern->AddPlaceholderChunk("type-id");
1231 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1232 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1233 Pattern->AddPlaceholderChunk("expression");
1234 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1235 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001236
Douglas Gregorf64acca2010-05-25 21:41:55 +00001237 // const_cast < type-id > ( expression )
1238 Pattern = new CodeCompletionString;
1239 Pattern->AddTypedTextChunk("const_cast");
1240 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1241 Pattern->AddPlaceholderChunk("type-id");
1242 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1243 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1244 Pattern->AddPlaceholderChunk("expression");
1245 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1246 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001247
Douglas Gregorf64acca2010-05-25 21:41:55 +00001248 // typeid ( expression-or-type )
1249 Pattern = new CodeCompletionString;
1250 Pattern->AddTypedTextChunk("typeid");
1251 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1252 Pattern->AddPlaceholderChunk("expression-or-type");
1253 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1254 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001255
Douglas Gregorf64acca2010-05-25 21:41:55 +00001256 // new T ( ... )
1257 Pattern = new CodeCompletionString;
1258 Pattern->AddTypedTextChunk("new");
1259 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1260 Pattern->AddPlaceholderChunk("type-id");
1261 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1262 Pattern->AddPlaceholderChunk("expressions");
1263 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1264 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001265
Douglas Gregorf64acca2010-05-25 21:41:55 +00001266 // new T [ ] ( ... )
1267 Pattern = new CodeCompletionString;
1268 Pattern->AddTypedTextChunk("new");
1269 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1270 Pattern->AddPlaceholderChunk("type-id");
1271 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1272 Pattern->AddPlaceholderChunk("size");
1273 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1274 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1275 Pattern->AddPlaceholderChunk("expressions");
1276 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1277 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001278
Douglas Gregorf64acca2010-05-25 21:41:55 +00001279 // delete expression
1280 Pattern = new CodeCompletionString;
1281 Pattern->AddTypedTextChunk("delete");
1282 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1283 Pattern->AddPlaceholderChunk("expression");
1284 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001285
Douglas Gregorf64acca2010-05-25 21:41:55 +00001286 // delete [] expression
1287 Pattern = new CodeCompletionString;
1288 Pattern->AddTypedTextChunk("delete");
1289 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1290 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1291 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1292 Pattern->AddPlaceholderChunk("expression");
1293 Results.AddResult(Result(Pattern));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001294
Douglas Gregorf64acca2010-05-25 21:41:55 +00001295 // throw expression
1296 Pattern = new CodeCompletionString;
1297 Pattern->AddTypedTextChunk("throw");
1298 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1299 Pattern->AddPlaceholderChunk("expression");
1300 Results.AddResult(Result(Pattern));
1301 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001302 }
1303
1304 if (SemaRef.getLangOptions().ObjC1) {
1305 // Add "super", if we're in an Objective-C class with a superclass.
1306 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1307 if (Method->getClassInterface()->getSuperClass())
Douglas Gregor78a21012010-01-14 16:01:26 +00001308 Results.AddResult(Result("super"));
Douglas Gregorf1934162010-01-13 21:24:21 +00001309
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001310 AddObjCExpressionResults(Results, true);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001311 }
1312
Douglas Gregorf64acca2010-05-25 21:41:55 +00001313 if (Results.includeCodePatterns()) {
1314 // sizeof expression
1315 Pattern = new CodeCompletionString;
1316 Pattern->AddTypedTextChunk("sizeof");
1317 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1318 Pattern->AddPlaceholderChunk("expression-or-type");
1319 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1320 Results.AddResult(Result(Pattern));
1321 }
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001322 break;
1323 }
1324 }
1325
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001326 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001327
1328 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregor78a21012010-01-14 16:01:26 +00001329 Results.AddResult(Result("operator"));
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001330}
1331
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001332/// \brief If the given declaration has an associated type, add it as a result
1333/// type chunk.
1334static void AddResultTypeChunk(ASTContext &Context,
1335 NamedDecl *ND,
1336 CodeCompletionString *Result) {
1337 if (!ND)
1338 return;
1339
1340 // Determine the type of the declaration (if it has a type).
1341 QualType T;
1342 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1343 T = Function->getResultType();
1344 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1345 T = Method->getResultType();
1346 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1347 T = FunTmpl->getTemplatedDecl()->getResultType();
1348 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1349 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1350 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1351 /* Do nothing: ignore unresolved using declarations*/
1352 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1353 T = Value->getType();
1354 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1355 T = Property->getType();
1356
1357 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1358 return;
1359
Douglas Gregorcf04b022010-04-05 21:25:31 +00001360 PrintingPolicy Policy(Context.PrintingPolicy);
1361 Policy.AnonymousTagLocations = false;
1362
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001363 std::string TypeStr;
Douglas Gregorcf04b022010-04-05 21:25:31 +00001364 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001365 Result->AddResultTypeChunk(TypeStr);
1366}
1367
Douglas Gregor3545ff42009-09-21 16:56:56 +00001368/// \brief Add function parameter chunks to the given code completion string.
1369static void AddFunctionParameterChunks(ASTContext &Context,
1370 FunctionDecl *Function,
1371 CodeCompletionString *Result) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001372 typedef CodeCompletionString::Chunk Chunk;
1373
Douglas Gregor3545ff42009-09-21 16:56:56 +00001374 CodeCompletionString *CCStr = Result;
1375
1376 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1377 ParmVarDecl *Param = Function->getParamDecl(P);
1378
1379 if (Param->hasDefaultArg()) {
1380 // When we see an optional default argument, put that argument and
1381 // the remaining default arguments into a new, optional string.
1382 CodeCompletionString *Opt = new CodeCompletionString;
1383 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1384 CCStr = Opt;
1385 }
1386
1387 if (P != 0)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001388 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001389
1390 // Format the placeholder string.
1391 std::string PlaceholderStr;
1392 if (Param->getIdentifier())
1393 PlaceholderStr = Param->getIdentifier()->getName();
1394
1395 Param->getType().getAsStringInternal(PlaceholderStr,
1396 Context.PrintingPolicy);
1397
1398 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001399 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001400 }
Douglas Gregorba449032009-09-22 21:42:17 +00001401
1402 if (const FunctionProtoType *Proto
1403 = Function->getType()->getAs<FunctionProtoType>())
1404 if (Proto->isVariadic())
1405 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001406}
1407
1408/// \brief Add template parameter chunks to the given code completion string.
1409static void AddTemplateParameterChunks(ASTContext &Context,
1410 TemplateDecl *Template,
1411 CodeCompletionString *Result,
1412 unsigned MaxParameters = 0) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001413 typedef CodeCompletionString::Chunk Chunk;
1414
Douglas Gregor3545ff42009-09-21 16:56:56 +00001415 CodeCompletionString *CCStr = Result;
1416 bool FirstParameter = true;
1417
1418 TemplateParameterList *Params = Template->getTemplateParameters();
1419 TemplateParameterList::iterator PEnd = Params->end();
1420 if (MaxParameters)
1421 PEnd = Params->begin() + MaxParameters;
1422 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1423 bool HasDefaultArg = false;
1424 std::string PlaceholderStr;
1425 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1426 if (TTP->wasDeclaredWithTypename())
1427 PlaceholderStr = "typename";
1428 else
1429 PlaceholderStr = "class";
1430
1431 if (TTP->getIdentifier()) {
1432 PlaceholderStr += ' ';
1433 PlaceholderStr += TTP->getIdentifier()->getName();
1434 }
1435
1436 HasDefaultArg = TTP->hasDefaultArgument();
1437 } else if (NonTypeTemplateParmDecl *NTTP
1438 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1439 if (NTTP->getIdentifier())
1440 PlaceholderStr = NTTP->getIdentifier()->getName();
1441 NTTP->getType().getAsStringInternal(PlaceholderStr,
1442 Context.PrintingPolicy);
1443 HasDefaultArg = NTTP->hasDefaultArgument();
1444 } else {
1445 assert(isa<TemplateTemplateParmDecl>(*P));
1446 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1447
1448 // Since putting the template argument list into the placeholder would
1449 // be very, very long, we just use an abbreviation.
1450 PlaceholderStr = "template<...> class";
1451 if (TTP->getIdentifier()) {
1452 PlaceholderStr += ' ';
1453 PlaceholderStr += TTP->getIdentifier()->getName();
1454 }
1455
1456 HasDefaultArg = TTP->hasDefaultArgument();
1457 }
1458
1459 if (HasDefaultArg) {
1460 // When we see an optional default argument, put that argument and
1461 // the remaining default arguments into a new, optional string.
1462 CodeCompletionString *Opt = new CodeCompletionString;
1463 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1464 CCStr = Opt;
1465 }
1466
1467 if (FirstParameter)
1468 FirstParameter = false;
1469 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001470 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001471
1472 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001473 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001474 }
1475}
1476
Douglas Gregorf2510672009-09-21 19:57:38 +00001477/// \brief Add a qualifier to the given code-completion string, if the
1478/// provided nested-name-specifier is non-NULL.
Douglas Gregor0f622362009-12-11 18:44:16 +00001479static void
1480AddQualifierToCompletionString(CodeCompletionString *Result,
1481 NestedNameSpecifier *Qualifier,
1482 bool QualifierIsInformative,
1483 ASTContext &Context) {
Douglas Gregorf2510672009-09-21 19:57:38 +00001484 if (!Qualifier)
1485 return;
1486
1487 std::string PrintedNNS;
1488 {
1489 llvm::raw_string_ostream OS(PrintedNNS);
1490 Qualifier->print(OS, Context.PrintingPolicy);
1491 }
Douglas Gregor5bf52692009-09-22 23:15:58 +00001492 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001493 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +00001494 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001495 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +00001496}
1497
Douglas Gregor0f622362009-12-11 18:44:16 +00001498static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1499 FunctionDecl *Function) {
1500 const FunctionProtoType *Proto
1501 = Function->getType()->getAs<FunctionProtoType>();
1502 if (!Proto || !Proto->getTypeQuals())
1503 return;
1504
1505 std::string QualsStr;
1506 if (Proto->getTypeQuals() & Qualifiers::Const)
1507 QualsStr += " const";
1508 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1509 QualsStr += " volatile";
1510 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1511 QualsStr += " restrict";
1512 Result->AddInformativeChunk(QualsStr);
1513}
1514
Douglas Gregor3545ff42009-09-21 16:56:56 +00001515/// \brief If possible, create a new code completion string for the given
1516/// result.
1517///
1518/// \returns Either a new, heap-allocated code completion string describing
1519/// how to use this result, or NULL to indicate that the string or name of the
1520/// result is all that is needed.
1521CodeCompletionString *
1522CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001523 typedef CodeCompletionString::Chunk Chunk;
1524
Douglas Gregorf09935f2009-12-01 05:55:20 +00001525 if (Kind == RK_Pattern)
1526 return Pattern->Clone();
1527
1528 CodeCompletionString *Result = new CodeCompletionString;
1529
1530 if (Kind == RK_Keyword) {
1531 Result->AddTypedTextChunk(Keyword);
1532 return Result;
1533 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001534
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001535 if (Kind == RK_Macro) {
1536 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001537 assert(MI && "Not a macro?");
1538
1539 Result->AddTypedTextChunk(Macro->getName());
1540
1541 if (!MI->isFunctionLike())
1542 return Result;
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001543
1544 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001545 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001546 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1547 A != AEnd; ++A) {
1548 if (A != MI->arg_begin())
Douglas Gregor9eb77012009-11-07 00:00:49 +00001549 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001550
1551 if (!MI->isVariadic() || A != AEnd - 1) {
1552 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001553 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001554 continue;
1555 }
1556
1557 // Variadic argument; cope with the different between GNU and C99
1558 // variadic macros, providing a single placeholder for the rest of the
1559 // arguments.
1560 if ((*A)->isStr("__VA_ARGS__"))
1561 Result->AddPlaceholderChunk("...");
1562 else {
1563 std::string Arg = (*A)->getName();
1564 Arg += "...";
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001565 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001566 }
1567 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001568 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001569 return Result;
1570 }
1571
Douglas Gregorf64acca2010-05-25 21:41:55 +00001572 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001573 NamedDecl *ND = Declaration;
1574
Douglas Gregor9eb77012009-11-07 00:00:49 +00001575 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001576 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001577 Result->AddTextChunk("::");
1578 return Result;
1579 }
1580
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001581 AddResultTypeChunk(S.Context, ND, Result);
1582
Douglas Gregor3545ff42009-09-21 16:56:56 +00001583 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001584 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1585 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001586 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001587 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001588 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001589 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001590 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001591 return Result;
1592 }
1593
1594 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001595 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1596 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001597 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001598 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-09-21 16:56:56 +00001599
1600 // Figure out which template parameters are deduced (or have default
1601 // arguments).
1602 llvm::SmallVector<bool, 16> Deduced;
1603 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1604 unsigned LastDeducibleArgument;
1605 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1606 --LastDeducibleArgument) {
1607 if (!Deduced[LastDeducibleArgument - 1]) {
1608 // C++0x: Figure out if the template argument has a default. If so,
1609 // the user doesn't need to type this argument.
1610 // FIXME: We need to abstract template parameters better!
1611 bool HasDefaultArg = false;
1612 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1613 LastDeducibleArgument - 1);
1614 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1615 HasDefaultArg = TTP->hasDefaultArgument();
1616 else if (NonTypeTemplateParmDecl *NTTP
1617 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1618 HasDefaultArg = NTTP->hasDefaultArgument();
1619 else {
1620 assert(isa<TemplateTemplateParmDecl>(Param));
1621 HasDefaultArg
Douglas Gregor9eb77012009-11-07 00:00:49 +00001622 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001623 }
1624
1625 if (!HasDefaultArg)
1626 break;
1627 }
1628 }
1629
1630 if (LastDeducibleArgument) {
1631 // Some of the function template arguments cannot be deduced from a
1632 // function call, so we introduce an explicit template argument list
1633 // containing all of the arguments up to the first deducible argument.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001634 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001635 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1636 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001637 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001638 }
1639
1640 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00001641 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001642 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001643 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001644 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001645 return Result;
1646 }
1647
1648 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001649 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1650 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001651 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001652 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001653 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001654 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001655 return Result;
1656 }
1657
Douglas Gregord3c5d792009-11-17 16:44:22 +00001658 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-11-17 16:44:22 +00001659 Selector Sel = Method->getSelector();
1660 if (Sel.isUnarySelector()) {
1661 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1662 return Result;
1663 }
1664
Douglas Gregor1b605f72009-11-19 01:08:35 +00001665 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1666 SelName += ':';
1667 if (StartParameter == 0)
1668 Result->AddTypedTextChunk(SelName);
1669 else {
1670 Result->AddInformativeChunk(SelName);
1671
1672 // If there is only one parameter, and we're past it, add an empty
1673 // typed-text chunk since there is nothing to type.
1674 if (Method->param_size() == 1)
1675 Result->AddTypedTextChunk("");
1676 }
Douglas Gregord3c5d792009-11-17 16:44:22 +00001677 unsigned Idx = 0;
1678 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1679 PEnd = Method->param_end();
1680 P != PEnd; (void)++P, ++Idx) {
1681 if (Idx > 0) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001682 std::string Keyword;
1683 if (Idx > StartParameter)
Douglas Gregor6a803932010-01-12 06:38:28 +00001684 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001685 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1686 Keyword += II->getName().str();
1687 Keyword += ":";
Douglas Gregorc8537c52009-11-19 07:41:15 +00001688 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00001689 Result->AddInformativeChunk(Keyword);
1690 } else if (Idx == StartParameter)
1691 Result->AddTypedTextChunk(Keyword);
1692 else
1693 Result->AddTextChunk(Keyword);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001694 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00001695
1696 // If we're before the starting parameter, skip the placeholder.
1697 if (Idx < StartParameter)
1698 continue;
Douglas Gregord3c5d792009-11-17 16:44:22 +00001699
1700 std::string Arg;
1701 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1702 Arg = "(" + Arg + ")";
1703 if (IdentifierInfo *II = (*P)->getIdentifier())
1704 Arg += II->getName().str();
Douglas Gregorc8537c52009-11-19 07:41:15 +00001705 if (AllParametersAreInformative)
1706 Result->AddInformativeChunk(Arg);
1707 else
1708 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001709 }
1710
Douglas Gregor04c5f972009-12-23 00:21:46 +00001711 if (Method->isVariadic()) {
1712 if (AllParametersAreInformative)
1713 Result->AddInformativeChunk(", ...");
1714 else
1715 Result->AddPlaceholderChunk(", ...");
1716 }
1717
Douglas Gregord3c5d792009-11-17 16:44:22 +00001718 return Result;
1719 }
1720
Douglas Gregorf09935f2009-12-01 05:55:20 +00001721 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00001722 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1723 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001724
1725 Result->AddTypedTextChunk(ND->getNameAsString());
1726 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001727}
1728
Douglas Gregorf0f51982009-09-23 00:34:09 +00001729CodeCompletionString *
1730CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1731 unsigned CurrentArg,
1732 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001733 typedef CodeCompletionString::Chunk Chunk;
1734
Douglas Gregorf0f51982009-09-23 00:34:09 +00001735 CodeCompletionString *Result = new CodeCompletionString;
1736 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001737 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001738 const FunctionProtoType *Proto
1739 = dyn_cast<FunctionProtoType>(getFunctionType());
1740 if (!FDecl && !Proto) {
1741 // Function without a prototype. Just give the return type and a
1742 // highlighted ellipsis.
1743 const FunctionType *FT = getFunctionType();
1744 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001745 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00001746 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1747 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1748 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001749 return Result;
1750 }
1751
1752 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001753 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00001754 else
1755 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001756 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001757
Douglas Gregor9eb77012009-11-07 00:00:49 +00001758 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001759 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1760 for (unsigned I = 0; I != NumParams; ++I) {
1761 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001762 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001763
1764 std::string ArgString;
1765 QualType ArgType;
1766
1767 if (FDecl) {
1768 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1769 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1770 } else {
1771 ArgType = Proto->getArgType(I);
1772 }
1773
1774 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1775
1776 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001777 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001778 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001779 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001780 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001781 }
1782
1783 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001784 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001785 if (CurrentArg < NumParams)
1786 Result->AddTextChunk("...");
1787 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001788 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001789 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001790 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001791
1792 return Result;
1793}
1794
Douglas Gregor3545ff42009-09-21 16:56:56 +00001795namespace {
1796 struct SortCodeCompleteResult {
1797 typedef CodeCompleteConsumer::Result Result;
1798
Douglas Gregore6688e62009-09-28 03:51:44 +00001799 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor249d6822009-12-05 09:08:56 +00001800 Selector XSel = X.getObjCSelector();
1801 Selector YSel = Y.getObjCSelector();
1802 if (!XSel.isNull() && !YSel.isNull()) {
1803 // We are comparing two selectors.
1804 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1805 if (N == 0)
1806 ++N;
1807 for (unsigned I = 0; I != N; ++I) {
1808 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1809 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1810 if (!XId || !YId)
1811 return XId && !YId;
1812
1813 switch (XId->getName().compare_lower(YId->getName())) {
1814 case -1: return true;
1815 case 1: return false;
1816 default: break;
1817 }
1818 }
1819
1820 return XSel.getNumArgs() < YSel.getNumArgs();
1821 }
1822
1823 // For non-selectors, order by kind.
1824 if (X.getNameKind() != Y.getNameKind())
Douglas Gregore6688e62009-09-28 03:51:44 +00001825 return X.getNameKind() < Y.getNameKind();
1826
Douglas Gregor249d6822009-12-05 09:08:56 +00001827 // Order identifiers by comparison of their lowercased names.
1828 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1829 return XId->getName().compare_lower(
1830 Y.getAsIdentifierInfo()->getName()) < 0;
1831
1832 // Order overloaded operators by the order in which they appear
1833 // in our list of operators.
1834 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1835 return XOp < Y.getCXXOverloadedOperator();
1836
1837 // Order C++0x user-defined literal operators lexically by their
1838 // lowercased suffixes.
1839 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1840 return XLit->getName().compare_lower(
1841 Y.getCXXLiteralIdentifier()->getName()) < 0;
1842
1843 // The only stable ordering we have is to turn the name into a
1844 // string and then compare the lower-case strings. This is
1845 // inefficient, but thankfully does not happen too often.
Benjamin Kramer4053e5d2009-12-05 10:22:15 +00001846 return llvm::StringRef(X.getAsString()).compare_lower(
1847 Y.getAsString()) < 0;
Douglas Gregore6688e62009-09-28 03:51:44 +00001848 }
1849
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001850 /// \brief Retrieve the name that should be used to order a result.
1851 ///
1852 /// If the name needs to be constructed as a string, that string will be
1853 /// saved into Saved and the returned StringRef will refer to it.
1854 static llvm::StringRef getOrderedName(const Result &R,
1855 std::string &Saved) {
1856 switch (R.Kind) {
1857 case Result::RK_Keyword:
1858 return R.Keyword;
1859
1860 case Result::RK_Pattern:
1861 return R.Pattern->getTypedText();
1862
1863 case Result::RK_Macro:
1864 return R.Macro->getName();
1865
1866 case Result::RK_Declaration:
1867 // Handle declarations below.
1868 break;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001869 }
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001870
1871 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001872
Douglas Gregor52ce62f2010-01-13 23:24:38 +00001873 // If the name is a simple identifier (by far the common case), or a
1874 // zero-argument selector, just return a reference to that identifier.
1875 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
1876 return Id->getName();
1877 if (Name.isObjCZeroArgSelector())
1878 if (IdentifierInfo *Id
1879 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
1880 return Id->getName();
1881
1882 Saved = Name.getAsString();
1883 return Saved;
1884 }
1885
1886 bool operator()(const Result &X, const Result &Y) const {
1887 std::string XSaved, YSaved;
1888 llvm::StringRef XStr = getOrderedName(X, XSaved);
1889 llvm::StringRef YStr = getOrderedName(Y, YSaved);
1890 int cmp = XStr.compare_lower(YStr);
1891 if (cmp)
1892 return cmp < 0;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001893
1894 // Non-hidden names precede hidden names.
1895 if (X.Hidden != Y.Hidden)
1896 return !X.Hidden;
1897
Douglas Gregore412a5a2009-09-23 22:26:46 +00001898 // Non-nested-name-specifiers precede nested-name-specifiers.
1899 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1900 return !X.StartsNestedNameSpecifier;
1901
Douglas Gregor3545ff42009-09-21 16:56:56 +00001902 return false;
1903 }
1904 };
1905}
1906
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001907static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001908 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00001909 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1910 MEnd = PP.macro_end();
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001911 M != MEnd; ++M)
Douglas Gregor78a21012010-01-14 16:01:26 +00001912 Results.AddResult(M->first);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001913 Results.ExitScope();
1914}
1915
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001916static void HandleCodeCompleteResults(Sema *S,
1917 CodeCompleteConsumer *CodeCompleter,
1918 CodeCompleteConsumer::Result *Results,
1919 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00001920 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1921
1922 if (CodeCompleter)
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001923 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001924
1925 for (unsigned I = 0; I != NumResults; ++I)
1926 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001927}
1928
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001929void Sema::CodeCompleteOrdinaryName(Scope *S,
1930 CodeCompletionContext CompletionContext) {
Douglas Gregor92253692009-12-07 09:54:55 +00001931 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001932 ResultBuilder Results(*this);
1933
1934 // Determine how to filter results, e.g., so that the names of
1935 // values (functions, enumerators, function templates, etc.) are
1936 // only allowed where we can have an expression.
1937 switch (CompletionContext) {
1938 case CCC_Namespace:
1939 case CCC_Class:
Douglas Gregorf1934162010-01-13 21:24:21 +00001940 case CCC_ObjCInterface:
1941 case CCC_ObjCImplementation:
Douglas Gregor48d46252010-01-13 21:54:15 +00001942 case CCC_ObjCInstanceVariableList:
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001943 case CCC_Template:
1944 case CCC_MemberTemplate:
1945 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
1946 break;
1947
1948 case CCC_Expression:
1949 case CCC_Statement:
1950 case CCC_ForInit:
1951 case CCC_Condition:
1952 Results.setFilter(&ResultBuilder::IsOrdinaryName);
1953 break;
Douglas Gregor6da3db42010-05-25 05:58:43 +00001954
1955 case CCC_RecoveryInFunction:
1956 // Unfiltered
1957 break;
Douglas Gregor504a6ae2010-01-10 23:08:15 +00001958 }
1959
Douglas Gregorc580c522010-01-14 01:09:38 +00001960 CodeCompletionDeclConsumer Consumer(Results, CurContext);
1961 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor92253692009-12-07 09:54:55 +00001962
1963 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001964 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00001965 Results.ExitScope();
1966
Douglas Gregor9eb77012009-11-07 00:00:49 +00001967 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00001968 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001969 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00001970}
1971
Douglas Gregor9291bad2009-11-18 01:29:26 +00001972static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00001973 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00001974 DeclContext *CurContext,
1975 ResultBuilder &Results) {
1976 typedef CodeCompleteConsumer::Result Result;
1977
1978 // Add properties in this container.
1979 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1980 PEnd = Container->prop_end();
1981 P != PEnd;
1982 ++P)
1983 Results.MaybeAddResult(Result(*P, 0), CurContext);
1984
1985 // Add properties in referenced protocols.
1986 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1987 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1988 PEnd = Protocol->protocol_end();
1989 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00001990 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001991 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00001992 if (AllowCategories) {
1993 // Look through categories.
1994 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1995 Category; Category = Category->getNextClassCategory())
1996 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1997 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00001998
1999 // Look through protocols.
2000 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2001 E = IFace->protocol_end();
2002 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002003 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002004
2005 // Look in the superclass.
2006 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00002007 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2008 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002009 } else if (const ObjCCategoryDecl *Category
2010 = dyn_cast<ObjCCategoryDecl>(Container)) {
2011 // Look through protocols.
2012 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2013 PEnd = Category->protocol_end();
2014 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00002015 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002016 }
2017}
2018
Douglas Gregor2436e712009-09-17 21:32:03 +00002019void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2020 SourceLocation OpLoc,
2021 bool IsArrow) {
2022 if (!BaseE || !CodeCompleter)
2023 return;
2024
Douglas Gregor3545ff42009-09-21 16:56:56 +00002025 typedef CodeCompleteConsumer::Result Result;
2026
Douglas Gregor2436e712009-09-17 21:32:03 +00002027 Expr *Base = static_cast<Expr *>(BaseE);
2028 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002029
2030 if (IsArrow) {
2031 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2032 BaseType = Ptr->getPointeeType();
2033 else if (BaseType->isObjCObjectPointerType())
2034 /*Do nothing*/ ;
2035 else
2036 return;
2037 }
2038
Douglas Gregore412a5a2009-09-23 22:26:46 +00002039 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002040 Results.EnterNewScope();
2041 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2042 // Access to a C/C++ class, struct, or union.
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002043 Results.allowNestedNameSpecifiers();
Douglas Gregor09bbc652010-01-14 15:47:35 +00002044 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2045 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002046
Douglas Gregor9291bad2009-11-18 01:29:26 +00002047 if (getLangOptions().CPlusPlus) {
2048 if (!Results.empty()) {
2049 // The "template" keyword can follow "->" or "." in the grammar.
2050 // However, we only want to suggest the template keyword if something
2051 // is dependent.
2052 bool IsDependent = BaseType->isDependentType();
2053 if (!IsDependent) {
2054 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2055 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2056 IsDependent = Ctx->isDependentContext();
2057 break;
2058 }
2059 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002060
Douglas Gregor9291bad2009-11-18 01:29:26 +00002061 if (IsDependent)
Douglas Gregor78a21012010-01-14 16:01:26 +00002062 Results.AddResult(Result("template"));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002063 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002064 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002065 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2066 // Objective-C property reference.
2067
2068 // Add property results based on our interface.
2069 const ObjCObjectPointerType *ObjCPtr
2070 = BaseType->getAsObjCInterfacePointerType();
2071 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00002072 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002073
2074 // Add properties from the protocols in a qualified interface.
2075 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2076 E = ObjCPtr->qual_end();
2077 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00002078 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002079 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCall8b07ec22010-05-15 11:32:37 +00002080 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor9291bad2009-11-18 01:29:26 +00002081 // Objective-C instance variable access.
2082 ObjCInterfaceDecl *Class = 0;
2083 if (const ObjCObjectPointerType *ObjCPtr
2084 = BaseType->getAs<ObjCObjectPointerType>())
2085 Class = ObjCPtr->getInterfaceDecl();
2086 else
John McCall8b07ec22010-05-15 11:32:37 +00002087 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor9291bad2009-11-18 01:29:26 +00002088
2089 // Add all ivars from this class and its superclasses.
Douglas Gregor2b8162b2010-01-14 16:08:12 +00002090 if (Class) {
2091 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2092 Results.setFilter(&ResultBuilder::IsObjCIvar);
2093 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor9291bad2009-11-18 01:29:26 +00002094 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002095 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00002096
2097 // FIXME: How do we cope with isa?
2098
2099 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002100
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002101 // Hand off the results found for code completion.
2102 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002103}
2104
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002105void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2106 if (!CodeCompleter)
2107 return;
2108
Douglas Gregor3545ff42009-09-21 16:56:56 +00002109 typedef CodeCompleteConsumer::Result Result;
2110 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002111 switch ((DeclSpec::TST)TagSpec) {
2112 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002113 Filter = &ResultBuilder::IsEnum;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002114 break;
2115
2116 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002117 Filter = &ResultBuilder::IsUnion;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002118 break;
2119
2120 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002121 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00002122 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002123 break;
2124
2125 default:
2126 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2127 return;
2128 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00002129
John McCalle87beb22010-04-23 18:46:30 +00002130 ResultBuilder Results(*this);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002131 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCalle87beb22010-04-23 18:46:30 +00002132
2133 // First pass: look for tags.
2134 Results.setFilter(Filter);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002135 LookupVisibleDecls(S, LookupTagName, Consumer);
John McCalle87beb22010-04-23 18:46:30 +00002136
2137 // Second pass: look for nested name specifiers.
2138 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2139 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002140
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002141 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00002142}
2143
Douglas Gregord328d572009-09-21 18:10:23 +00002144void Sema::CodeCompleteCase(Scope *S) {
2145 if (getSwitchStack().empty() || !CodeCompleter)
2146 return;
2147
2148 SwitchStmt *Switch = getSwitchStack().back();
2149 if (!Switch->getCond()->getType()->isEnumeralType())
2150 return;
2151
2152 // Code-complete the cases of a switch statement over an enumeration type
2153 // by providing the list of
2154 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2155
2156 // Determine which enumerators we have already seen in the switch statement.
2157 // FIXME: Ideally, we would also be able to look *past* the code-completion
2158 // token, in case we are code-completing in the middle of the switch and not
2159 // at the end. However, we aren't able to do so at the moment.
2160 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00002161 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00002162 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2163 SC = SC->getNextSwitchCase()) {
2164 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2165 if (!Case)
2166 continue;
2167
2168 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2169 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2170 if (EnumConstantDecl *Enumerator
2171 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2172 // We look into the AST of the case statement to determine which
2173 // enumerator was named. Alternatively, we could compute the value of
2174 // the integral constant expression, then compare it against the
2175 // values of each enumerator. However, value-based approach would not
2176 // work as well with C++ templates where enumerators declared within a
2177 // template are type- and value-dependent.
2178 EnumeratorsSeen.insert(Enumerator);
2179
Douglas Gregorf2510672009-09-21 19:57:38 +00002180 // If this is a qualified-id, keep track of the nested-name-specifier
2181 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00002182 //
2183 // switch (TagD.getKind()) {
2184 // case TagDecl::TK_enum:
2185 // break;
2186 // case XXX
2187 //
Douglas Gregorf2510672009-09-21 19:57:38 +00002188 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00002189 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2190 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00002191 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00002192 }
2193 }
2194
Douglas Gregorf2510672009-09-21 19:57:38 +00002195 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2196 // If there are no prior enumerators in C++, check whether we have to
2197 // qualify the names of the enumerators that we suggest, because they
2198 // may not be visible in this scope.
2199 Qualifier = getRequiredQualification(Context, CurContext,
2200 Enum->getDeclContext());
2201
2202 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2203 }
2204
Douglas Gregord328d572009-09-21 18:10:23 +00002205 // Add any enumerators that have not yet been mentioned.
2206 ResultBuilder Results(*this);
2207 Results.EnterNewScope();
2208 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2209 EEnd = Enum->enumerator_end();
2210 E != EEnd; ++E) {
2211 if (EnumeratorsSeen.count(*E))
2212 continue;
2213
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002214 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2215 CurContext, 0, false);
Douglas Gregord328d572009-09-21 18:10:23 +00002216 }
2217 Results.ExitScope();
Douglas Gregor285560922010-04-06 20:02:15 +00002218
Douglas Gregor9eb77012009-11-07 00:00:49 +00002219 if (CodeCompleter->includeMacros())
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002220 AddMacroResults(PP, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002221 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00002222}
2223
Douglas Gregorcabea402009-09-22 15:41:20 +00002224namespace {
2225 struct IsBetterOverloadCandidate {
2226 Sema &S;
John McCallbc077cf2010-02-08 23:07:23 +00002227 SourceLocation Loc;
Douglas Gregorcabea402009-09-22 15:41:20 +00002228
2229 public:
John McCallbc077cf2010-02-08 23:07:23 +00002230 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2231 : S(S), Loc(Loc) { }
Douglas Gregorcabea402009-09-22 15:41:20 +00002232
2233 bool
2234 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCallbc077cf2010-02-08 23:07:23 +00002235 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregorcabea402009-09-22 15:41:20 +00002236 }
2237 };
2238}
2239
2240void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2241 ExprTy **ArgsIn, unsigned NumArgs) {
2242 if (!CodeCompleter)
2243 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002244
2245 // When we're code-completing for a call, we fall back to ordinary
2246 // name code-completion whenever we can't produce specific
2247 // results. We may want to revisit this strategy in the future,
2248 // e.g., by merging the two kinds of results.
2249
Douglas Gregorcabea402009-09-22 15:41:20 +00002250 Expr *Fn = (Expr *)FnIn;
2251 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002252
Douglas Gregorcabea402009-09-22 15:41:20 +00002253 // Ignore type-dependent call expressions entirely.
2254 if (Fn->isTypeDependent() ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00002255 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor504a6ae2010-01-10 23:08:15 +00002256 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregorcabea402009-09-22 15:41:20 +00002257 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00002258 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002259
John McCall57500772009-12-16 12:17:52 +00002260 // Build an overload candidate set based on the functions we find.
John McCallbc077cf2010-02-08 23:07:23 +00002261 SourceLocation Loc = Fn->getExprLoc();
2262 OverloadCandidateSet CandidateSet(Loc);
John McCall57500772009-12-16 12:17:52 +00002263
Douglas Gregorcabea402009-09-22 15:41:20 +00002264 // FIXME: What if we're calling something that isn't a function declaration?
2265 // FIXME: What if we're calling a pseudo-destructor?
2266 // FIXME: What if we're calling a member function?
2267
Douglas Gregorff59f672010-01-21 15:46:19 +00002268 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2269 llvm::SmallVector<ResultCandidate, 8> Results;
2270
John McCall57500772009-12-16 12:17:52 +00002271 Expr *NakedFn = Fn->IgnoreParenCasts();
2272 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2273 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2274 /*PartialOverloading=*/ true);
2275 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2276 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorff59f672010-01-21 15:46:19 +00002277 if (FDecl) {
2278 if (!FDecl->getType()->getAs<FunctionProtoType>())
2279 Results.push_back(ResultCandidate(FDecl));
2280 else
John McCallb89836b2010-01-26 01:37:31 +00002281 // FIXME: access?
John McCalla0296f72010-03-19 07:35:19 +00002282 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2283 Args, NumArgs, CandidateSet,
Douglas Gregorb05275a2010-04-16 17:41:49 +00002284 false, /*PartialOverloading*/true);
Douglas Gregorff59f672010-01-21 15:46:19 +00002285 }
John McCall57500772009-12-16 12:17:52 +00002286 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002287
Douglas Gregorff59f672010-01-21 15:46:19 +00002288 if (!CandidateSet.empty()) {
2289 // Sort the overload candidate set by placing the best overloads first.
2290 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCallbc077cf2010-02-08 23:07:23 +00002291 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregorcabea402009-09-22 15:41:20 +00002292
Douglas Gregorff59f672010-01-21 15:46:19 +00002293 // Add the remaining viable overload candidates as code-completion reslults.
2294 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2295 CandEnd = CandidateSet.end();
2296 Cand != CandEnd; ++Cand) {
2297 if (Cand->Viable)
2298 Results.push_back(ResultCandidate(Cand->Function));
2299 }
Douglas Gregorcabea402009-09-22 15:41:20 +00002300 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00002301
Douglas Gregorc01890e2010-04-06 20:19:47 +00002302 CodeCompleteOrdinaryName(S, CCC_Expression);
2303 if (!Results.empty())
Douglas Gregor3ef59522009-12-11 19:06:04 +00002304 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2305 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00002306}
2307
Jeffrey Yasskinc76498d2010-04-08 16:38:48 +00002308void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor2436e712009-09-17 21:32:03 +00002309 bool EnteringContext) {
2310 if (!SS.getScopeRep() || !CodeCompleter)
2311 return;
2312
Douglas Gregor3545ff42009-09-21 16:56:56 +00002313 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2314 if (!Ctx)
2315 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00002316
2317 // Try to instantiate any non-dependent declaration contexts before
2318 // we look in them.
John McCall0b66eb32010-05-01 00:40:08 +00002319 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregor800f2f02009-12-11 18:28:39 +00002320 return;
2321
Douglas Gregor3545ff42009-09-21 16:56:56 +00002322 ResultBuilder Results(*this);
Douglas Gregor200c99d2010-01-14 03:35:48 +00002323 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2324 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002325
2326 // The "template" keyword can follow "::" in the grammar, but only
2327 // put it into the grammar if the nested-name-specifier is dependent.
2328 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2329 if (!Results.empty() && NNS->isDependent())
Douglas Gregor78a21012010-01-14 16:01:26 +00002330 Results.AddResult("template");
Douglas Gregor3545ff42009-09-21 16:56:56 +00002331
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002332 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00002333}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002334
2335void Sema::CodeCompleteUsing(Scope *S) {
2336 if (!CodeCompleter)
2337 return;
2338
Douglas Gregor3545ff42009-09-21 16:56:56 +00002339 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002340 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002341
2342 // If we aren't in class scope, we could see the "namespace" keyword.
2343 if (!S->isClassScope())
Douglas Gregor78a21012010-01-14 16:01:26 +00002344 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002345
2346 // After "using", we can see anything that would start a
2347 // nested-name-specifier.
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002348 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2349 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002350 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002351
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002352 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002353}
2354
2355void Sema::CodeCompleteUsingDirective(Scope *S) {
2356 if (!CodeCompleter)
2357 return;
2358
Douglas Gregor3545ff42009-09-21 16:56:56 +00002359 // After "using namespace", we expect to see a namespace name or namespace
2360 // alias.
2361 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002362 Results.EnterNewScope();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002363 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2364 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002365 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002366 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002367}
2368
2369void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2370 if (!CodeCompleter)
2371 return;
2372
Douglas Gregor3545ff42009-09-21 16:56:56 +00002373 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2374 DeclContext *Ctx = (DeclContext *)S->getEntity();
2375 if (!S->getParent())
2376 Ctx = Context.getTranslationUnitDecl();
2377
2378 if (Ctx && Ctx->isFileContext()) {
2379 // We only want to see those namespaces that have already been defined
2380 // within this scope, because its likely that the user is creating an
2381 // extended namespace declaration. Keep track of the most recent
2382 // definition of each namespace.
2383 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2384 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2385 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2386 NS != NSEnd; ++NS)
2387 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2388
2389 // Add the most recent definition (or extended definition) of each
2390 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00002391 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002392 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2393 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2394 NS != NSEnd; ++NS)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00002395 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2396 CurContext, 0, false);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002397 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002398 }
2399
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002400 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002401}
2402
2403void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2404 if (!CodeCompleter)
2405 return;
2406
Douglas Gregor3545ff42009-09-21 16:56:56 +00002407 // After "namespace", we expect to see a namespace or alias.
2408 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002409 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2410 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002411 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002412}
2413
Douglas Gregorc811ede2009-09-18 20:05:18 +00002414void Sema::CodeCompleteOperatorName(Scope *S) {
2415 if (!CodeCompleter)
2416 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00002417
2418 typedef CodeCompleteConsumer::Result Result;
2419 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002420 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00002421
Douglas Gregor3545ff42009-09-21 16:56:56 +00002422 // Add the names of overloadable operators.
2423#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2424 if (std::strcmp(Spelling, "?")) \
Douglas Gregor78a21012010-01-14 16:01:26 +00002425 Results.AddResult(Result(Spelling));
Douglas Gregor3545ff42009-09-21 16:56:56 +00002426#include "clang/Basic/OperatorKinds.def"
2427
2428 // Add any type names visible from the current scope
Douglas Gregor6ae4c522010-01-14 03:21:49 +00002429 Results.allowNestedNameSpecifiers();
Douglas Gregora6e2edc2010-01-14 03:27:13 +00002430 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2431 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor3545ff42009-09-21 16:56:56 +00002432
2433 // Add any type specifiers
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002434 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00002435 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00002436
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002437 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00002438}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00002439
Douglas Gregorf1934162010-01-13 21:24:21 +00002440// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2441// true or false.
2442#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002443static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002444 ResultBuilder &Results,
2445 bool NeedAt) {
Douglas Gregorf64acca2010-05-25 21:41:55 +00002446 if (!Results.includeCodePatterns())
2447 return;
2448
Douglas Gregorf1934162010-01-13 21:24:21 +00002449 typedef CodeCompleteConsumer::Result Result;
2450 // Since we have an implementation, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002451 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002452
2453 CodeCompletionString *Pattern = 0;
2454 if (LangOpts.ObjC2) {
2455 // @dynamic
2456 Pattern = new CodeCompletionString;
2457 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2458 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2459 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002460 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002461
2462 // @synthesize
2463 Pattern = new CodeCompletionString;
2464 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2465 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2466 Pattern->AddPlaceholderChunk("property");
Douglas Gregor78a21012010-01-14 16:01:26 +00002467 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002468 }
2469}
2470
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002471static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorf1934162010-01-13 21:24:21 +00002472 ResultBuilder &Results,
2473 bool NeedAt) {
Douglas Gregorf64acca2010-05-25 21:41:55 +00002474 if (!Results.includeCodePatterns())
2475 return;
2476
Douglas Gregorf1934162010-01-13 21:24:21 +00002477 typedef CodeCompleteConsumer::Result Result;
2478
2479 // Since we have an interface or protocol, we can end it.
Douglas Gregor78a21012010-01-14 16:01:26 +00002480 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002481
2482 if (LangOpts.ObjC2) {
2483 // @property
Douglas Gregor78a21012010-01-14 16:01:26 +00002484 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002485
2486 // @required
Douglas Gregor78a21012010-01-14 16:01:26 +00002487 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002488
2489 // @optional
Douglas Gregor78a21012010-01-14 16:01:26 +00002490 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorf1934162010-01-13 21:24:21 +00002491 }
2492}
2493
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002494static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf64acca2010-05-25 21:41:55 +00002495 if (!Results.includeCodePatterns())
2496 return;
2497
Douglas Gregorf1934162010-01-13 21:24:21 +00002498 typedef CodeCompleteConsumer::Result Result;
2499 CodeCompletionString *Pattern = 0;
2500
2501 // @class name ;
2502 Pattern = new CodeCompletionString;
2503 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2504 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2505 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregor78a21012010-01-14 16:01:26 +00002506 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002507
2508 // @interface name
2509 // FIXME: Could introduce the whole pattern, including superclasses and
2510 // such.
2511 Pattern = new CodeCompletionString;
2512 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2513 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2514 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002515 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002516
2517 // @protocol name
2518 Pattern = new CodeCompletionString;
2519 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2520 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2521 Pattern->AddPlaceholderChunk("protocol");
Douglas Gregor78a21012010-01-14 16:01:26 +00002522 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002523
2524 // @implementation name
2525 Pattern = new CodeCompletionString;
2526 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2527 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2528 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002529 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002530
2531 // @compatibility_alias name
2532 Pattern = new CodeCompletionString;
2533 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2534 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2535 Pattern->AddPlaceholderChunk("alias");
2536 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2537 Pattern->AddPlaceholderChunk("class");
Douglas Gregor78a21012010-01-14 16:01:26 +00002538 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002539}
2540
Douglas Gregorf48706c2009-12-07 09:27:33 +00002541void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2542 bool InInterface) {
2543 typedef CodeCompleteConsumer::Result Result;
2544 ResultBuilder Results(*this);
2545 Results.EnterNewScope();
Douglas Gregorf1934162010-01-13 21:24:21 +00002546 if (ObjCImpDecl)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002547 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002548 else if (InInterface)
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002549 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorf1934162010-01-13 21:24:21 +00002550 else
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002551 AddObjCTopLevelResults(Results, false);
Douglas Gregorf48706c2009-12-07 09:27:33 +00002552 Results.ExitScope();
2553 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2554}
2555
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002556static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf64acca2010-05-25 21:41:55 +00002557 if (!Results.includeCodePatterns())
2558 return;
2559
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002560 typedef CodeCompleteConsumer::Result Result;
2561 CodeCompletionString *Pattern = 0;
2562
2563 // @encode ( type-name )
2564 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002565 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002566 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2567 Pattern->AddPlaceholderChunk("type-name");
2568 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002569 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002570
2571 // @protocol ( protocol-name )
2572 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002573 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002574 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2575 Pattern->AddPlaceholderChunk("protocol-name");
2576 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002577 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002578
2579 // @selector ( selector )
2580 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002581 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002582 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2583 Pattern->AddPlaceholderChunk("selector");
2584 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregor78a21012010-01-14 16:01:26 +00002585 Results.AddResult(Result(Pattern));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002586}
2587
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002588static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorf64acca2010-05-25 21:41:55 +00002589 if (!Results.includeCodePatterns())
2590 return;
2591
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002592 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002593 CodeCompletionString *Pattern = 0;
Douglas Gregorf1934162010-01-13 21:24:21 +00002594
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002595 // @try { statements } @catch ( declaration ) { statements } @finally
2596 // { statements }
2597 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002598 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002599 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2600 Pattern->AddPlaceholderChunk("statements");
2601 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2602 Pattern->AddTextChunk("@catch");
2603 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2604 Pattern->AddPlaceholderChunk("parameter");
2605 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2606 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2607 Pattern->AddPlaceholderChunk("statements");
2608 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2609 Pattern->AddTextChunk("@finally");
2610 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2611 Pattern->AddPlaceholderChunk("statements");
2612 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00002613 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002614
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002615 // @throw
2616 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002617 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor6a803932010-01-12 06:38:28 +00002618 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002619 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor78a21012010-01-14 16:01:26 +00002620 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002621
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002622 // @synchronized ( expression ) { statements }
2623 Pattern = new CodeCompletionString;
Douglas Gregorf1934162010-01-13 21:24:21 +00002624 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
Douglas Gregor6a803932010-01-12 06:38:28 +00002625 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002626 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2627 Pattern->AddPlaceholderChunk("expression");
2628 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2629 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2630 Pattern->AddPlaceholderChunk("statements");
2631 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregor78a21012010-01-14 16:01:26 +00002632 Results.AddResult(Result(Pattern));
Douglas Gregorf1934162010-01-13 21:24:21 +00002633}
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002634
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002635static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregor48d46252010-01-13 21:54:15 +00002636 ResultBuilder &Results,
2637 bool NeedAt) {
Douglas Gregorf64acca2010-05-25 21:41:55 +00002638 if (!Results.includeCodePatterns())
2639 return;
2640
Douglas Gregorf1934162010-01-13 21:24:21 +00002641 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor78a21012010-01-14 16:01:26 +00002642 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2643 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2644 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002645 if (LangOpts.ObjC2)
Douglas Gregor78a21012010-01-14 16:01:26 +00002646 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregor48d46252010-01-13 21:54:15 +00002647}
2648
2649void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2650 ResultBuilder Results(*this);
2651 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002652 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregor48d46252010-01-13 21:54:15 +00002653 Results.ExitScope();
2654 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2655}
2656
2657void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorf1934162010-01-13 21:24:21 +00002658 ResultBuilder Results(*this);
2659 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002660 AddObjCStatementResults(Results, false);
2661 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002662 Results.ExitScope();
2663 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2664}
2665
2666void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2667 ResultBuilder Results(*this);
2668 Results.EnterNewScope();
Douglas Gregorf98e6a22010-01-13 23:51:12 +00002669 AddObjCExpressionResults(Results, false);
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002670 Results.ExitScope();
2671 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2672}
2673
Douglas Gregore6078da2009-11-19 00:14:45 +00002674/// \brief Determine whether the addition of the given flag to an Objective-C
2675/// property's attributes will cause a conflict.
2676static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2677 // Check if we've already added this flag.
2678 if (Attributes & NewFlag)
2679 return true;
2680
2681 Attributes |= NewFlag;
2682
2683 // Check for collisions with "readonly".
2684 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2685 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2686 ObjCDeclSpec::DQ_PR_assign |
2687 ObjCDeclSpec::DQ_PR_copy |
2688 ObjCDeclSpec::DQ_PR_retain)))
2689 return true;
2690
2691 // Check for more than one of { assign, copy, retain }.
2692 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2693 ObjCDeclSpec::DQ_PR_copy |
2694 ObjCDeclSpec::DQ_PR_retain);
2695 if (AssignCopyRetMask &&
2696 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2697 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2698 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2699 return true;
2700
2701 return false;
2702}
2703
Douglas Gregor36029f42009-11-18 23:08:07 +00002704void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00002705 if (!CodeCompleter)
2706 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00002707
Steve Naroff936354c2009-10-08 21:55:05 +00002708 unsigned Attributes = ODS.getPropertyAttributes();
2709
2710 typedef CodeCompleteConsumer::Result Result;
2711 ResultBuilder Results(*this);
2712 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00002713 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregor78a21012010-01-14 16:01:26 +00002714 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002715 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregor78a21012010-01-14 16:01:26 +00002716 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002717 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregor78a21012010-01-14 16:01:26 +00002718 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002719 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregor78a21012010-01-14 16:01:26 +00002720 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002721 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregor78a21012010-01-14 16:01:26 +00002722 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002723 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregor78a21012010-01-14 16:01:26 +00002724 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregore6078da2009-11-19 00:14:45 +00002725 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002726 CodeCompletionString *Setter = new CodeCompletionString;
2727 Setter->AddTypedTextChunk("setter");
2728 Setter->AddTextChunk(" = ");
2729 Setter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002730 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002731 }
Douglas Gregore6078da2009-11-19 00:14:45 +00002732 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002733 CodeCompletionString *Getter = new CodeCompletionString;
2734 Getter->AddTypedTextChunk("getter");
2735 Getter->AddTextChunk(" = ");
2736 Getter->AddPlaceholderChunk("method");
Douglas Gregor78a21012010-01-14 16:01:26 +00002737 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002738 }
Steve Naroff936354c2009-10-08 21:55:05 +00002739 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002740 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00002741}
Steve Naroffeae65032009-11-07 02:08:14 +00002742
Douglas Gregorc8537c52009-11-19 07:41:15 +00002743/// \brief Descripts the kind of Objective-C method that we want to find
2744/// via code completion.
2745enum ObjCMethodKind {
2746 MK_Any, //< Any kind of method, provided it means other specified criteria.
2747 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2748 MK_OneArgSelector //< One-argument selector.
2749};
2750
2751static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2752 ObjCMethodKind WantKind,
2753 IdentifierInfo **SelIdents,
2754 unsigned NumSelIdents) {
2755 Selector Sel = Method->getSelector();
2756 if (NumSelIdents > Sel.getNumArgs())
2757 return false;
2758
2759 switch (WantKind) {
2760 case MK_Any: break;
2761 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2762 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2763 }
2764
2765 for (unsigned I = 0; I != NumSelIdents; ++I)
2766 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2767 return false;
2768
2769 return true;
2770}
2771
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002772/// \brief Add all of the Objective-C methods in the given Objective-C
2773/// container to the set of results.
2774///
2775/// The container will be a class, protocol, category, or implementation of
2776/// any of the above. This mether will recurse to include methods from
2777/// the superclasses of classes along with their categories, protocols, and
2778/// implementations.
2779///
2780/// \param Container the container in which we'll look to find methods.
2781///
2782/// \param WantInstance whether to add instance methods (only); if false, this
2783/// routine will add factory methods (only).
2784///
2785/// \param CurContext the context in which we're performing the lookup that
2786/// finds methods.
2787///
2788/// \param Results the structure into which we'll add results.
2789static void AddObjCMethods(ObjCContainerDecl *Container,
2790 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00002791 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002792 IdentifierInfo **SelIdents,
2793 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002794 DeclContext *CurContext,
2795 ResultBuilder &Results) {
2796 typedef CodeCompleteConsumer::Result Result;
2797 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2798 MEnd = Container->meth_end();
2799 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002800 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2801 // Check whether the selector identifiers we've been given are a
2802 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00002803 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00002804 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002805
Douglas Gregor1b605f72009-11-19 01:08:35 +00002806 Result R = Result(*M, 0);
2807 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002808 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00002809 Results.MaybeAddResult(R, CurContext);
2810 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002811 }
2812
2813 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2814 if (!IFace)
2815 return;
2816
2817 // Add methods in protocols.
2818 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2819 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2820 E = Protocols.end();
2821 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002822 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002823 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002824
2825 // Add methods in categories.
2826 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2827 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00002828 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2829 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002830
2831 // Add a categories protocol methods.
2832 const ObjCList<ObjCProtocolDecl> &Protocols
2833 = CatDecl->getReferencedProtocols();
2834 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2835 E = Protocols.end();
2836 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002837 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2838 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002839
2840 // Add methods in category implementations.
2841 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002842 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2843 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002844 }
2845
2846 // Add methods in superclass.
2847 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002848 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2849 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002850
2851 // Add methods in our implementation, if any.
2852 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002853 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2854 NumSelIdents, CurContext, Results);
2855}
2856
2857
2858void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2859 DeclPtrTy *Methods,
2860 unsigned NumMethods) {
2861 typedef CodeCompleteConsumer::Result Result;
2862
2863 // Try to find the interface where getters might live.
2864 ObjCInterfaceDecl *Class
2865 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2866 if (!Class) {
2867 if (ObjCCategoryDecl *Category
2868 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2869 Class = Category->getClassInterface();
2870
2871 if (!Class)
2872 return;
2873 }
2874
2875 // Find all of the potential getters.
2876 ResultBuilder Results(*this);
2877 Results.EnterNewScope();
2878
2879 // FIXME: We need to do this because Objective-C methods don't get
2880 // pushed into DeclContexts early enough. Argh!
2881 for (unsigned I = 0; I != NumMethods; ++I) {
2882 if (ObjCMethodDecl *Method
2883 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2884 if (Method->isInstanceMethod() &&
2885 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2886 Result R = Result(Method, 0);
2887 R.AllParametersAreInformative = true;
2888 Results.MaybeAddResult(R, CurContext);
2889 }
2890 }
2891
2892 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2893 Results.ExitScope();
2894 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2895}
2896
2897void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2898 DeclPtrTy *Methods,
2899 unsigned NumMethods) {
2900 typedef CodeCompleteConsumer::Result Result;
2901
2902 // Try to find the interface where setters might live.
2903 ObjCInterfaceDecl *Class
2904 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2905 if (!Class) {
2906 if (ObjCCategoryDecl *Category
2907 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2908 Class = Category->getClassInterface();
2909
2910 if (!Class)
2911 return;
2912 }
2913
2914 // Find all of the potential getters.
2915 ResultBuilder Results(*this);
2916 Results.EnterNewScope();
2917
2918 // FIXME: We need to do this because Objective-C methods don't get
2919 // pushed into DeclContexts early enough. Argh!
2920 for (unsigned I = 0; I != NumMethods; ++I) {
2921 if (ObjCMethodDecl *Method
2922 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2923 if (Method->isInstanceMethod() &&
2924 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2925 Result R = Result(Method, 0);
2926 R.AllParametersAreInformative = true;
2927 Results.MaybeAddResult(R, CurContext);
2928 }
2929 }
2930
2931 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2932
2933 Results.ExitScope();
2934 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002935}
2936
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00002937/// \brief When we have an expression with type "id", we may assume
2938/// that it has some more-specific class type based on knowledge of
2939/// common uses of Objective-C. This routine returns that class type,
2940/// or NULL if no better result could be determined.
2941static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
2942 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
2943 if (!Msg)
2944 return 0;
2945
2946 Selector Sel = Msg->getSelector();
2947 if (Sel.isNull())
2948 return 0;
2949
2950 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
2951 if (!Id)
2952 return 0;
2953
2954 ObjCMethodDecl *Method = Msg->getMethodDecl();
2955 if (!Method)
2956 return 0;
2957
2958 // Determine the class that we're sending the message to.
Douglas Gregor9a129192010-04-21 00:45:42 +00002959 ObjCInterfaceDecl *IFace = 0;
2960 switch (Msg->getReceiverKind()) {
2961 case ObjCMessageExpr::Class:
John McCall8b07ec22010-05-15 11:32:37 +00002962 if (const ObjCObjectType *ObjType
2963 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
2964 IFace = ObjType->getInterface();
Douglas Gregor9a129192010-04-21 00:45:42 +00002965 break;
2966
2967 case ObjCMessageExpr::Instance: {
2968 QualType T = Msg->getInstanceReceiver()->getType();
2969 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
2970 IFace = Ptr->getInterfaceDecl();
2971 break;
2972 }
2973
2974 case ObjCMessageExpr::SuperInstance:
2975 case ObjCMessageExpr::SuperClass:
2976 break;
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00002977 }
2978
2979 if (!IFace)
2980 return 0;
2981
2982 ObjCInterfaceDecl *Super = IFace->getSuperClass();
2983 if (Method->isInstanceMethod())
2984 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2985 .Case("retain", IFace)
2986 .Case("autorelease", IFace)
2987 .Case("copy", IFace)
2988 .Case("copyWithZone", IFace)
2989 .Case("mutableCopy", IFace)
2990 .Case("mutableCopyWithZone", IFace)
2991 .Case("awakeFromCoder", IFace)
2992 .Case("replacementObjectFromCoder", IFace)
2993 .Case("class", IFace)
2994 .Case("classForCoder", IFace)
2995 .Case("superclass", Super)
2996 .Default(0);
2997
2998 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
2999 .Case("new", IFace)
3000 .Case("alloc", IFace)
3001 .Case("allocWithZone", IFace)
3002 .Case("class", IFace)
3003 .Case("superclass", Super)
3004 .Default(0);
3005}
3006
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003007void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3008 IdentifierInfo **SelIdents,
3009 unsigned NumSelIdents) {
3010 ObjCInterfaceDecl *CDecl = 0;
3011 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3012 // Figure out which interface we're in.
3013 CDecl = CurMethod->getClassInterface();
3014 if (!CDecl)
3015 return;
3016
3017 // Find the superclass of this class.
3018 CDecl = CDecl->getSuperClass();
3019 if (!CDecl)
3020 return;
3021
3022 if (CurMethod->isInstanceMethod()) {
3023 // We are inside an instance method, which means that the message
3024 // send [super ...] is actually calling an instance method on the
3025 // current object. Build the super expression and handle this like
3026 // an instance method.
3027 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3028 SuperTy = Context.getObjCObjectPointerType(SuperTy);
3029 OwningExprResult Super
3030 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3031 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3032 SelIdents, NumSelIdents);
3033 }
3034
3035 // Fall through to send to the superclass in CDecl.
3036 } else {
3037 // "super" may be the name of a type or variable. Figure out which
3038 // it is.
3039 IdentifierInfo *Super = &Context.Idents.get("super");
3040 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3041 LookupOrdinaryName);
3042 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3043 // "super" names an interface. Use it.
3044 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCall8b07ec22010-05-15 11:32:37 +00003045 if (const ObjCObjectType *Iface
3046 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3047 CDecl = Iface->getInterface();
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003048 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3049 // "super" names an unresolved type; we can't be more specific.
3050 } else {
3051 // Assume that "super" names some kind of value and parse that way.
3052 CXXScopeSpec SS;
3053 UnqualifiedId id;
3054 id.setIdentifier(Super, SuperLoc);
3055 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
3056 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3057 SelIdents, NumSelIdents);
3058 }
3059
3060 // Fall through
3061 }
3062
3063 TypeTy *Receiver = 0;
3064 if (CDecl)
3065 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3066 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3067 NumSelIdents);
3068}
3069
3070void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregor1b605f72009-11-19 01:08:35 +00003071 IdentifierInfo **SelIdents,
3072 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003073 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00003074 ObjCInterfaceDecl *CDecl = 0;
3075
Douglas Gregor8ce33212009-11-17 17:59:40 +00003076 // If the given name refers to an interface type, retrieve the
3077 // corresponding declaration.
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003078 if (Receiver) {
3079 QualType T = GetTypeFromParser(Receiver, 0);
3080 if (!T.isNull())
John McCall8b07ec22010-05-15 11:32:37 +00003081 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3082 CDecl = Interface->getInterface();
Douglas Gregor8ce33212009-11-17 17:59:40 +00003083 }
3084
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003085 // Add all of the factory methods in this Objective-C class, its protocols,
3086 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00003087 ResultBuilder Results(*this);
3088 Results.EnterNewScope();
Douglas Gregor6285f752010-04-06 16:40:00 +00003089
3090 if (CDecl)
3091 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3092 Results);
Douglas Gregor0c78ad92010-04-21 19:57:20 +00003093 else {
Douglas Gregor6285f752010-04-06 16:40:00 +00003094 // We're messaging "id" as a type; provide all class/factory methods.
3095
Douglas Gregord720daf2010-04-06 17:30:22 +00003096 // If we have an external source, load the entire class method
3097 // pool from the PCH file.
3098 if (ExternalSource) {
3099 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3100 ++I) {
3101 Selector Sel = ExternalSource->GetSelector(I);
3102 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3103 InstanceMethodPool.count(Sel))
3104 continue;
3105
3106 ReadMethodPool(Sel, /*isInstance=*/false);
3107 }
3108 }
3109
Douglas Gregor6285f752010-04-06 16:40:00 +00003110 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3111 M = FactoryMethodPool.begin(),
3112 MEnd = FactoryMethodPool.end();
3113 M != MEnd;
3114 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003115 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003116 MethList = MethList->Next) {
3117 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3118 NumSelIdents))
3119 continue;
3120
3121 Result R(MethList->Method, 0);
3122 R.StartParameter = NumSelIdents;
3123 R.AllParametersAreInformative = false;
3124 Results.MaybeAddResult(R, CurContext);
3125 }
3126 }
3127 }
3128
Steve Naroffeae65032009-11-07 02:08:14 +00003129 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003130 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003131}
3132
Douglas Gregor1b605f72009-11-19 01:08:35 +00003133void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3134 IdentifierInfo **SelIdents,
3135 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00003136 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00003137
3138 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffeae65032009-11-07 02:08:14 +00003139
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003140 // If necessary, apply function/array conversion to the receiver.
3141 // C99 6.7.5.3p[7,8].
Douglas Gregorb92a1562010-02-03 00:27:59 +00003142 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003143 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00003144
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003145 // Build the set of methods we can see.
3146 ResultBuilder Results(*this);
3147 Results.EnterNewScope();
Douglas Gregor9d2ddb22010-04-06 19:22:33 +00003148
3149 // If we're messaging an expression with type "id" or "Class", check
3150 // whether we know something special about the receiver that allows
3151 // us to assume a more-specific receiver type.
3152 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3153 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3154 ReceiverType = Context.getObjCObjectPointerType(
3155 Context.getObjCInterfaceType(IFace));
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00003156
Douglas Gregora3329fa2009-11-18 00:06:18 +00003157 // Handle messages to Class. This really isn't a message to an instance
3158 // method, so we treat it the same way we would treat a message send to a
3159 // class method.
3160 if (ReceiverType->isObjCClassType() ||
3161 ReceiverType->isObjCQualifiedClassType()) {
3162 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3163 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00003164 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3165 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003166 }
3167 }
3168 // Handle messages to a qualified ID ("id<foo>").
3169 else if (const ObjCObjectPointerType *QualID
3170 = ReceiverType->getAsObjCQualifiedIdType()) {
3171 // Search protocols for instance methods.
3172 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3173 E = QualID->qual_end();
3174 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003175 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3176 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003177 }
3178 // Handle messages to a pointer to interface type.
3179 else if (const ObjCObjectPointerType *IFacePtr
3180 = ReceiverType->getAsObjCInterfacePointerType()) {
3181 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00003182 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3183 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003184
3185 // Search protocols for instance methods.
3186 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3187 E = IFacePtr->qual_end();
3188 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00003189 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3190 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00003191 }
Douglas Gregor6285f752010-04-06 16:40:00 +00003192 // Handle messages to "id".
3193 else if (ReceiverType->isObjCIdType()) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003194 // We're messaging "id", so provide all instance methods we know
3195 // about as code-completion results.
3196
3197 // If we have an external source, load the entire class method
3198 // pool from the PCH file.
3199 if (ExternalSource) {
3200 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3201 ++I) {
3202 Selector Sel = ExternalSource->GetSelector(I);
3203 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3204 FactoryMethodPool.count(Sel))
3205 continue;
3206
3207 ReadMethodPool(Sel, /*isInstance=*/true);
3208 }
3209 }
3210
Douglas Gregor6285f752010-04-06 16:40:00 +00003211 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3212 M = InstanceMethodPool.begin(),
3213 MEnd = InstanceMethodPool.end();
3214 M != MEnd;
3215 ++M) {
Douglas Gregord720daf2010-04-06 17:30:22 +00003216 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor6285f752010-04-06 16:40:00 +00003217 MethList = MethList->Next) {
3218 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3219 NumSelIdents))
3220 continue;
3221
3222 Result R(MethList->Method, 0);
3223 R.StartParameter = NumSelIdents;
3224 R.AllParametersAreInformative = false;
3225 Results.MaybeAddResult(R, CurContext);
3226 }
3227 }
3228 }
3229
Steve Naroffeae65032009-11-07 02:08:14 +00003230 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00003231 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00003232}
Douglas Gregorbaf69612009-11-18 04:19:12 +00003233
3234/// \brief Add all of the protocol declarations that we find in the given
3235/// (translation unit) context.
3236static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003237 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00003238 ResultBuilder &Results) {
3239 typedef CodeCompleteConsumer::Result Result;
3240
3241 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3242 DEnd = Ctx->decls_end();
3243 D != DEnd; ++D) {
3244 // Record any protocols we find.
3245 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003246 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003247 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003248
3249 // Record any forward-declared protocols we find.
3250 if (ObjCForwardProtocolDecl *Forward
3251 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3252 for (ObjCForwardProtocolDecl::protocol_iterator
3253 P = Forward->protocol_begin(),
3254 PEnd = Forward->protocol_end();
3255 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003256 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003257 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003258 }
3259 }
3260}
3261
3262void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3263 unsigned NumProtocols) {
3264 ResultBuilder Results(*this);
3265 Results.EnterNewScope();
3266
3267 // Tell the result set to ignore all of the protocols we have
3268 // already seen.
3269 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003270 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3271 Protocols[I].second))
Douglas Gregorbaf69612009-11-18 04:19:12 +00003272 Results.Ignore(Protocol);
3273
3274 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00003275 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3276 Results);
3277
3278 Results.ExitScope();
3279 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3280}
3281
3282void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3283 ResultBuilder Results(*this);
3284 Results.EnterNewScope();
3285
3286 // Add all protocols.
3287 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3288 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00003289
3290 Results.ExitScope();
3291 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3292}
Douglas Gregor49c22a72009-11-18 16:26:39 +00003293
3294/// \brief Add all of the Objective-C interface declarations that we find in
3295/// the given (translation unit) context.
3296static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3297 bool OnlyForwardDeclarations,
3298 bool OnlyUnimplemented,
3299 ResultBuilder &Results) {
3300 typedef CodeCompleteConsumer::Result Result;
3301
3302 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3303 DEnd = Ctx->decls_end();
3304 D != DEnd; ++D) {
3305 // Record any interfaces we find.
3306 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3307 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3308 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003309 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003310
3311 // Record any forward-declared interfaces we find.
3312 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3313 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3314 C != CEnd; ++C)
3315 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3316 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003317 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3318 0, false);
Douglas Gregor49c22a72009-11-18 16:26:39 +00003319 }
3320 }
3321}
3322
3323void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3324 ResultBuilder Results(*this);
3325 Results.EnterNewScope();
3326
3327 // Add all classes.
3328 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3329 false, Results);
3330
3331 Results.ExitScope();
3332 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3333}
3334
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003335void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3336 SourceLocation ClassNameLoc) {
Douglas Gregor49c22a72009-11-18 16:26:39 +00003337 ResultBuilder Results(*this);
3338 Results.EnterNewScope();
3339
3340 // Make sure that we ignore the class we're currently defining.
3341 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003342 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003343 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00003344 Results.Ignore(CurClass);
3345
3346 // Add all classes.
3347 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3348 false, Results);
3349
3350 Results.ExitScope();
3351 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3352}
3353
3354void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3355 ResultBuilder Results(*this);
3356 Results.EnterNewScope();
3357
3358 // Add all unimplemented classes.
3359 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3360 true, Results);
3361
3362 Results.ExitScope();
3363 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3364}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003365
3366void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003367 IdentifierInfo *ClassName,
3368 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003369 typedef CodeCompleteConsumer::Result Result;
3370
3371 ResultBuilder Results(*this);
3372
3373 // Ignore any categories we find that have already been implemented by this
3374 // interface.
3375 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3376 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003377 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003378 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3379 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3380 Category = Category->getNextClassCategory())
3381 CategoryNames.insert(Category->getIdentifier());
3382
3383 // Add all of the categories we know about.
3384 Results.EnterNewScope();
3385 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3386 for (DeclContext::decl_iterator D = TU->decls_begin(),
3387 DEnd = TU->decls_end();
3388 D != DEnd; ++D)
3389 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3390 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003391 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003392 Results.ExitScope();
3393
3394 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3395}
3396
3397void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003398 IdentifierInfo *ClassName,
3399 SourceLocation ClassNameLoc) {
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003400 typedef CodeCompleteConsumer::Result Result;
3401
3402 // Find the corresponding interface. If we couldn't find the interface, the
3403 // program itself is ill-formed. However, we'll try to be helpful still by
3404 // providing the list of all of the categories we know about.
3405 NamedDecl *CurClass
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003406 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003407 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3408 if (!Class)
Douglas Gregorb2ccf012010-04-15 22:33:43 +00003409 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003410
3411 ResultBuilder Results(*this);
3412
3413 // Add all of the categories that have have corresponding interface
3414 // declarations in this class and any of its superclasses, except for
3415 // already-implemented categories in the class itself.
3416 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3417 Results.EnterNewScope();
3418 bool IgnoreImplemented = true;
3419 while (Class) {
3420 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3421 Category = Category->getNextClassCategory())
3422 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3423 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003424 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00003425
3426 Class = Class->getSuperClass();
3427 IgnoreImplemented = false;
3428 }
3429 Results.ExitScope();
3430
3431 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3432}
Douglas Gregor5d649882009-11-18 22:32:06 +00003433
Douglas Gregor52e78bd2009-11-18 22:56:13 +00003434void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00003435 typedef CodeCompleteConsumer::Result Result;
3436 ResultBuilder Results(*this);
3437
3438 // Figure out where this @synthesize lives.
3439 ObjCContainerDecl *Container
3440 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3441 if (!Container ||
3442 (!isa<ObjCImplementationDecl>(Container) &&
3443 !isa<ObjCCategoryImplDecl>(Container)))
3444 return;
3445
3446 // Ignore any properties that have already been implemented.
3447 for (DeclContext::decl_iterator D = Container->decls_begin(),
3448 DEnd = Container->decls_end();
3449 D != DEnd; ++D)
3450 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3451 Results.Ignore(PropertyImpl->getPropertyDecl());
3452
3453 // Add any properties that we find.
3454 Results.EnterNewScope();
3455 if (ObjCImplementationDecl *ClassImpl
3456 = dyn_cast<ObjCImplementationDecl>(Container))
3457 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3458 Results);
3459 else
3460 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3461 false, CurContext, Results);
3462 Results.ExitScope();
3463
3464 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3465}
3466
3467void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3468 IdentifierInfo *PropertyName,
3469 DeclPtrTy ObjCImpDecl) {
3470 typedef CodeCompleteConsumer::Result Result;
3471 ResultBuilder Results(*this);
3472
3473 // Figure out where this @synthesize lives.
3474 ObjCContainerDecl *Container
3475 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3476 if (!Container ||
3477 (!isa<ObjCImplementationDecl>(Container) &&
3478 !isa<ObjCCategoryImplDecl>(Container)))
3479 return;
3480
3481 // Figure out which interface we're looking into.
3482 ObjCInterfaceDecl *Class = 0;
3483 if (ObjCImplementationDecl *ClassImpl
3484 = dyn_cast<ObjCImplementationDecl>(Container))
3485 Class = ClassImpl->getClassInterface();
3486 else
3487 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3488 ->getClassInterface();
3489
3490 // Add all of the instance variables in this class and its superclasses.
3491 Results.EnterNewScope();
3492 for(; Class; Class = Class->getSuperClass()) {
3493 // FIXME: We could screen the type of each ivar for compatibility with
3494 // the property, but is that being too paternal?
3495 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3496 IVarEnd = Class->ivar_end();
3497 IVar != IVarEnd; ++IVar)
Douglas Gregorfc59ce12010-01-14 16:14:35 +00003498 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor5d649882009-11-18 22:32:06 +00003499 }
3500 Results.ExitScope();
3501
3502 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3503}
Douglas Gregor636a61e2010-04-07 00:21:17 +00003504
3505typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
3506
3507/// \brief Find all of the methods that reside in the given container
3508/// (and its superclasses, protocols, etc.) that meet the given
3509/// criteria. Insert those methods into the map of known methods,
3510/// indexed by selector so they can be easily found.
3511static void FindImplementableMethods(ASTContext &Context,
3512 ObjCContainerDecl *Container,
3513 bool WantInstanceMethods,
3514 QualType ReturnType,
3515 bool IsInImplementation,
3516 KnownMethodsMap &KnownMethods) {
3517 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
3518 // Recurse into protocols.
3519 const ObjCList<ObjCProtocolDecl> &Protocols
3520 = IFace->getReferencedProtocols();
3521 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3522 E = Protocols.end();
3523 I != E; ++I)
3524 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3525 IsInImplementation, KnownMethods);
3526
3527 // If we're not in the implementation of a class, also visit the
3528 // superclass.
3529 if (!IsInImplementation && IFace->getSuperClass())
3530 FindImplementableMethods(Context, IFace->getSuperClass(),
3531 WantInstanceMethods, ReturnType,
3532 IsInImplementation, KnownMethods);
3533
3534 // Add methods from any class extensions (but not from categories;
3535 // those should go into category implementations).
3536 for (ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
3537 Cat = Cat->getNextClassCategory()) {
3538 if (!Cat->IsClassExtension())
3539 continue;
3540
3541 FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
3542 IsInImplementation, KnownMethods);
3543 }
3544 }
3545
3546 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
3547 // Recurse into protocols.
3548 const ObjCList<ObjCProtocolDecl> &Protocols
3549 = Category->getReferencedProtocols();
3550 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3551 E = Protocols.end();
3552 I != E; ++I)
3553 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3554 IsInImplementation, KnownMethods);
3555 }
3556
3557 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3558 // Recurse into protocols.
3559 const ObjCList<ObjCProtocolDecl> &Protocols
3560 = Protocol->getReferencedProtocols();
3561 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3562 E = Protocols.end();
3563 I != E; ++I)
3564 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3565 IsInImplementation, KnownMethods);
3566 }
3567
3568 // Add methods in this container. This operation occurs last because
3569 // we want the methods from this container to override any methods
3570 // we've previously seen with the same selector.
3571 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3572 MEnd = Container->meth_end();
3573 M != MEnd; ++M) {
3574 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3575 if (!ReturnType.isNull() &&
3576 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
3577 continue;
3578
3579 KnownMethods[(*M)->getSelector()] = *M;
3580 }
3581 }
3582}
3583
3584void Sema::CodeCompleteObjCMethodDecl(Scope *S,
3585 bool IsInstanceMethod,
3586 TypeTy *ReturnTy,
3587 DeclPtrTy IDecl) {
3588 // Determine the return type of the method we're declaring, if
3589 // provided.
3590 QualType ReturnType = GetTypeFromParser(ReturnTy);
3591
3592 // Determine where we should start searching for methods, and where we
3593 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
3594 bool IsInImplementation = false;
3595 if (Decl *D = IDecl.getAs<Decl>()) {
3596 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
3597 SearchDecl = Impl->getClassInterface();
3598 CurrentDecl = Impl;
3599 IsInImplementation = true;
3600 } else if (ObjCCategoryImplDecl *CatImpl
3601 = dyn_cast<ObjCCategoryImplDecl>(D)) {
3602 SearchDecl = CatImpl->getCategoryDecl();
3603 CurrentDecl = CatImpl;
3604 IsInImplementation = true;
3605 } else {
3606 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
3607 CurrentDecl = SearchDecl;
3608 }
3609 }
3610
3611 if (!SearchDecl && S) {
3612 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
3613 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
3614 CurrentDecl = SearchDecl;
3615 }
3616 }
3617
3618 if (!SearchDecl || !CurrentDecl) {
3619 HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
3620 return;
3621 }
3622
3623 // Find all of the methods that we could declare/implement here.
3624 KnownMethodsMap KnownMethods;
3625 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
3626 ReturnType, IsInImplementation, KnownMethods);
3627
3628 // Erase any methods that have already been declared or
3629 // implemented here.
3630 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
3631 MEnd = CurrentDecl->meth_end();
3632 M != MEnd; ++M) {
3633 if ((*M)->isInstanceMethod() != IsInstanceMethod)
3634 continue;
3635
3636 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
3637 if (Pos != KnownMethods.end())
3638 KnownMethods.erase(Pos);
3639 }
3640
3641 // Add declarations or definitions for each of the known methods.
3642 typedef CodeCompleteConsumer::Result Result;
3643 ResultBuilder Results(*this);
3644 Results.EnterNewScope();
3645 PrintingPolicy Policy(Context.PrintingPolicy);
3646 Policy.AnonymousTagLocations = false;
3647 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
3648 MEnd = KnownMethods.end();
3649 M != MEnd; ++M) {
3650 ObjCMethodDecl *Method = M->second;
3651 CodeCompletionString *Pattern = new CodeCompletionString;
3652
3653 // If the result type was not already provided, add it to the
3654 // pattern as (type).
3655 if (ReturnType.isNull()) {
3656 std::string TypeStr;
3657 Method->getResultType().getAsStringInternal(TypeStr, Policy);
3658 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3659 Pattern->AddTextChunk(TypeStr);
3660 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3661 }
3662
3663 Selector Sel = Method->getSelector();
3664
3665 // Add the first part of the selector to the pattern.
3666 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
3667
3668 // Add parameters to the pattern.
3669 unsigned I = 0;
3670 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
3671 PEnd = Method->param_end();
3672 P != PEnd; (void)++P, ++I) {
3673 // Add the part of the selector name.
3674 if (I == 0)
3675 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3676 else if (I < Sel.getNumArgs()) {
3677 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3678 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
3679 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3680 } else
3681 break;
3682
3683 // Add the parameter type.
3684 std::string TypeStr;
3685 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
3686 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3687 Pattern->AddTextChunk(TypeStr);
3688 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3689
3690 if (IdentifierInfo *Id = (*P)->getIdentifier())
3691 Pattern->AddTextChunk(Id->getName());
3692 }
3693
3694 if (Method->isVariadic()) {
3695 if (Method->param_size() > 0)
3696 Pattern->AddChunk(CodeCompletionString::CK_Comma);
3697 Pattern->AddTextChunk("...");
3698 }
3699
3700 if (IsInImplementation) {
3701 // We will be defining the method here, so add a compound statement.
3702 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3703 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3704 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3705 if (!Method->getResultType()->isVoidType()) {
3706 // If the result type is not void, add a return clause.
3707 Pattern->AddTextChunk("return");
3708 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3709 Pattern->AddPlaceholderChunk("expression");
3710 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
3711 } else
3712 Pattern->AddPlaceholderChunk("statements");
3713
3714 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3715 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3716 }
3717
3718 Results.AddResult(Result(Pattern));
3719 }
3720
3721 Results.ExitScope();
3722
3723 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3724}