blob: a455e6115f085c629da99b9cc61bf1e07a71619a [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
13#include "Sema.h"
Douglas Gregor1ca6ae82010-01-14 01:09:38 +000014#include "Lookup.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregor719770d2010-04-06 17:30:22 +000016#include "clang/Sema/ExternalSemaSource.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000017#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000018#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000019#include "clang/Lex/MacroInfo.h"
20#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000021#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000022#include "llvm/ADT/StringExtras.h"
Douglas Gregor22f56992010-04-06 19:22:33 +000023#include "llvm/ADT/StringSwitch.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000024#include <list>
25#include <map>
26#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000027
28using namespace clang;
29
Douglas Gregor86d9a522009-09-21 16:56:56 +000030namespace {
31 /// \brief A container of code-completion results.
32 class ResultBuilder {
33 public:
34 /// \brief The type of a name-lookup filter, which can be provided to the
35 /// name-lookup routines to specify which declarations should be included in
36 /// the result set (when it returns true) and which declarations should be
37 /// filtered out (returns false).
38 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
39
40 typedef CodeCompleteConsumer::Result Result;
41
42 private:
43 /// \brief The actual results we have found.
44 std::vector<Result> Results;
45
46 /// \brief A record of all of the declarations we have found and placed
47 /// into the result set, used to ensure that no declaration ever gets into
48 /// the result set twice.
49 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
50
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000051 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
52
53 /// \brief An entry in the shadow map, which is optimized to store
54 /// a single (declaration, index) mapping (the common case) but
55 /// can also store a list of (declaration, index) mappings.
56 class ShadowMapEntry {
57 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
58
59 /// \brief Contains either the solitary NamedDecl * or a vector
60 /// of (declaration, index) pairs.
61 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
62
63 /// \brief When the entry contains a single declaration, this is
64 /// the index associated with that entry.
65 unsigned SingleDeclIndex;
66
67 public:
68 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
69
70 void Add(NamedDecl *ND, unsigned Index) {
71 if (DeclOrVector.isNull()) {
72 // 0 - > 1 elements: just set the single element information.
73 DeclOrVector = ND;
74 SingleDeclIndex = Index;
75 return;
76 }
77
78 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
79 // 1 -> 2 elements: create the vector of results and push in the
80 // existing declaration.
81 DeclIndexPairVector *Vec = new DeclIndexPairVector;
82 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
83 DeclOrVector = Vec;
84 }
85
86 // Add the new element to the end of the vector.
87 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
88 DeclIndexPair(ND, Index));
89 }
90
91 void Destroy() {
92 if (DeclIndexPairVector *Vec
93 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
94 delete Vec;
95 DeclOrVector = ((NamedDecl *)0);
96 }
97 }
98
99 // Iteration.
100 class iterator;
101 iterator begin() const;
102 iterator end() const;
103 };
104
Douglas Gregor86d9a522009-09-21 16:56:56 +0000105 /// \brief A mapping from declaration names to the declarations that have
106 /// this name within a particular scope and their index within the list of
107 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000108 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000109
110 /// \brief The semantic analysis object for which results are being
111 /// produced.
112 Sema &SemaRef;
113
114 /// \brief If non-NULL, a filter function used to remove any code-completion
115 /// results that are not desirable.
116 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000117
118 /// \brief Whether we should allow declarations as
119 /// nested-name-specifiers that would otherwise be filtered out.
120 bool AllowNestedNameSpecifiers;
121
Douglas Gregor86d9a522009-09-21 16:56:56 +0000122 /// \brief A list of shadow maps, which is used to model name hiding at
123 /// different levels of, e.g., the inheritance hierarchy.
124 std::list<ShadowMap> ShadowMaps;
125
126 public:
127 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor45bcd432010-01-14 03:21:49 +0000128 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000129
Douglas Gregord8e8a582010-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 Gregor86d9a522009-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 Gregor45bcd432010-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 Gregore495b7f2010-01-14 00:20:49 +0000155 /// \brief Determine whether the given declaration is at all interesting
156 /// as a code-completion result.
Douglas Gregor45bcd432010-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 Gregor6660d842010-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 Gregor86d9a522009-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 Gregor456c4a12009-09-21 20:12:40 +0000176 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000177 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-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 Gregor86d9a522009-09-21 16:56:56 +0000181
Douglas Gregor1ca6ae82010-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 Gregor0cc84042010-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 Gregor1ca6ae82010-01-14 01:09:38 +0000195
Douglas Gregora4477812010-01-14 16:01:26 +0000196 /// \brief Add a new non-declaration result to this result set.
197 void AddResult(Result R);
198
Douglas Gregor86d9a522009-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 Gregor55385fe2009-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 Gregor86d9a522009-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 Gregor791215b2009-09-21 20:51:25 +0000214 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000215 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-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 Gregoreb5758b2009-09-23 22:26:46 +0000223 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000224 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000225 bool IsObjCMessageReceiver(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000226 //@}
227 };
228}
229
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000230class ResultBuilder::ShadowMapEntry::iterator {
231 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
232 unsigned SingleDeclIndex;
233
234public:
235 typedef DeclIndexPair value_type;
236 typedef value_type reference;
237 typedef std::ptrdiff_t difference_type;
238 typedef std::input_iterator_tag iterator_category;
239
240 class pointer {
241 DeclIndexPair Value;
242
243 public:
244 pointer(const DeclIndexPair &Value) : Value(Value) { }
245
246 const DeclIndexPair *operator->() const {
247 return &Value;
248 }
249 };
250
251 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
252
253 iterator(NamedDecl *SingleDecl, unsigned Index)
254 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
255
256 iterator(const DeclIndexPair *Iterator)
257 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
258
259 iterator &operator++() {
260 if (DeclOrIterator.is<NamedDecl *>()) {
261 DeclOrIterator = (NamedDecl *)0;
262 SingleDeclIndex = 0;
263 return *this;
264 }
265
266 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
267 ++I;
268 DeclOrIterator = I;
269 return *this;
270 }
271
272 iterator operator++(int) {
273 iterator tmp(*this);
274 ++(*this);
275 return tmp;
276 }
277
278 reference operator*() const {
279 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
280 return reference(ND, SingleDeclIndex);
281
Douglas Gregord490f952009-12-06 21:27:58 +0000282 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000283 }
284
285 pointer operator->() const {
286 return pointer(**this);
287 }
288
289 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000290 return X.DeclOrIterator.getOpaqueValue()
291 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000292 X.SingleDeclIndex == Y.SingleDeclIndex;
293 }
294
295 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000296 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000297 }
298};
299
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000300ResultBuilder::ShadowMapEntry::iterator
301ResultBuilder::ShadowMapEntry::begin() const {
302 if (DeclOrVector.isNull())
303 return iterator();
304
305 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
306 return iterator(ND, SingleDeclIndex);
307
308 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
309}
310
311ResultBuilder::ShadowMapEntry::iterator
312ResultBuilder::ShadowMapEntry::end() const {
313 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
314 return iterator();
315
316 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
317}
318
Douglas Gregor456c4a12009-09-21 20:12:40 +0000319/// \brief Compute the qualification required to get from the current context
320/// (\p CurContext) to the target context (\p TargetContext).
321///
322/// \param Context the AST context in which the qualification will be used.
323///
324/// \param CurContext the context where an entity is being named, which is
325/// typically based on the current scope.
326///
327/// \param TargetContext the context in which the named entity actually
328/// resides.
329///
330/// \returns a nested name specifier that refers into the target context, or
331/// NULL if no qualification is needed.
332static NestedNameSpecifier *
333getRequiredQualification(ASTContext &Context,
334 DeclContext *CurContext,
335 DeclContext *TargetContext) {
336 llvm::SmallVector<DeclContext *, 4> TargetParents;
337
338 for (DeclContext *CommonAncestor = TargetContext;
339 CommonAncestor && !CommonAncestor->Encloses(CurContext);
340 CommonAncestor = CommonAncestor->getLookupParent()) {
341 if (CommonAncestor->isTransparentContext() ||
342 CommonAncestor->isFunctionOrMethod())
343 continue;
344
345 TargetParents.push_back(CommonAncestor);
346 }
347
348 NestedNameSpecifier *Result = 0;
349 while (!TargetParents.empty()) {
350 DeclContext *Parent = TargetParents.back();
351 TargetParents.pop_back();
352
353 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
354 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
355 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
356 Result = NestedNameSpecifier::Create(Context, Result,
357 false,
358 Context.getTypeDeclType(TD).getTypePtr());
359 else
360 assert(Parent->isTranslationUnit());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000361 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000362 return Result;
363}
364
Douglas Gregor45bcd432010-01-14 03:21:49 +0000365bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
366 bool &AsNestedNameSpecifier) const {
367 AsNestedNameSpecifier = false;
368
Douglas Gregore495b7f2010-01-14 00:20:49 +0000369 ND = ND->getUnderlyingDecl();
370 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000371
372 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000373 if (!ND->getDeclName())
374 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000375
376 // Friend declarations and declarations introduced due to friends are never
377 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000378 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000379 return false;
380
Douglas Gregor76282942009-12-11 17:31:05 +0000381 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000382 if (isa<ClassTemplateSpecializationDecl>(ND) ||
383 isa<ClassTemplatePartialSpecializationDecl>(ND))
384 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000385
Douglas Gregor76282942009-12-11 17:31:05 +0000386 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000387 if (isa<UsingDecl>(ND))
388 return false;
389
390 // Some declarations have reserved names that we don't want to ever show.
391 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000392 // __va_list_tag is a freak of nature. Find it and skip it.
393 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000394 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000395
Douglas Gregorf52cede2009-10-09 22:16:47 +0000396 // Filter out names reserved for the implementation (C99 7.1.3,
397 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbare013d682009-10-18 20:26:12 +0000398 //
399 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000400 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000401 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000402 if (Name[0] == '_' &&
403 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000404 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000405 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000406 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000407
Douglas Gregor86d9a522009-09-21 16:56:56 +0000408 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000409 if (isa<CXXConstructorDecl>(ND))
410 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000411
412 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000413 if (Filter && !(this->*Filter)(ND)) {
414 // Check whether it is interesting as a nested-name-specifier.
415 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
416 IsNestedNameSpecifier(ND) &&
417 (Filter != &ResultBuilder::IsMember ||
418 (isa<CXXRecordDecl>(ND) &&
419 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
420 AsNestedNameSpecifier = true;
421 return true;
422 }
423
Douglas Gregore495b7f2010-01-14 00:20:49 +0000424 return false;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000425 }
John McCall0d6b1642010-04-23 18:46:30 +0000426
427 if (Filter == &ResultBuilder::IsNestedNameSpecifier)
428 AsNestedNameSpecifier = true;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000429
Douglas Gregore495b7f2010-01-14 00:20:49 +0000430 // ... then it must be interesting!
431 return true;
432}
433
Douglas Gregor6660d842010-01-14 00:41:07 +0000434bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
435 NamedDecl *Hiding) {
436 // In C, there is no way to refer to a hidden name.
437 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
438 // name if we introduce the tag type.
439 if (!SemaRef.getLangOptions().CPlusPlus)
440 return true;
441
442 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
443
444 // There is no way to qualify a name declared in a function or method.
445 if (HiddenCtx->isFunctionOrMethod())
446 return true;
447
448 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
449 return true;
450
451 // We can refer to the result with the appropriate qualification. Do it.
452 R.Hidden = true;
453 R.QualifierIsInformative = false;
454
455 if (!R.Qualifier)
456 R.Qualifier = getRequiredQualification(SemaRef.Context,
457 CurContext,
458 R.Declaration->getDeclContext());
459 return false;
460}
461
Douglas Gregore495b7f2010-01-14 00:20:49 +0000462void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
463 assert(!ShadowMaps.empty() && "Must enter into a results scope");
464
465 if (R.Kind != Result::RK_Declaration) {
466 // For non-declaration results, just add the result.
467 Results.push_back(R);
468 return;
469 }
470
471 // Look through using declarations.
472 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
473 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
474 return;
475 }
476
477 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
478 unsigned IDNS = CanonDecl->getIdentifierNamespace();
479
Douglas Gregor45bcd432010-01-14 03:21:49 +0000480 bool AsNestedNameSpecifier = false;
481 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000482 return;
483
Douglas Gregor86d9a522009-09-21 16:56:56 +0000484 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000485 ShadowMapEntry::iterator I, IEnd;
486 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
487 if (NamePos != SMap.end()) {
488 I = NamePos->second.begin();
489 IEnd = NamePos->second.end();
490 }
491
492 for (; I != IEnd; ++I) {
493 NamedDecl *ND = I->first;
494 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000495 if (ND->getCanonicalDecl() == CanonDecl) {
496 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000497 Results[Index].Declaration = R.Declaration;
498
Douglas Gregor86d9a522009-09-21 16:56:56 +0000499 // We're done.
500 return;
501 }
502 }
503
504 // This is a new declaration in this scope. However, check whether this
505 // declaration name is hidden by a similarly-named declaration in an outer
506 // scope.
507 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
508 --SMEnd;
509 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000510 ShadowMapEntry::iterator I, IEnd;
511 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
512 if (NamePos != SM->end()) {
513 I = NamePos->second.begin();
514 IEnd = NamePos->second.end();
515 }
516 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000517 // A tag declaration does not hide a non-tag declaration.
John McCall0d6b1642010-04-23 18:46:30 +0000518 if (I->first->hasTagIdentifierNamespace() &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000519 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
520 Decl::IDNS_ObjCProtocol)))
521 continue;
522
523 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000524 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000525 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000526 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000527 continue;
528
529 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000530 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000531 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000532
533 break;
534 }
535 }
536
537 // Make sure that any given declaration only shows up in the result set once.
538 if (!AllDeclsFound.insert(CanonDecl))
539 return;
540
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000541 // If the filter is for nested-name-specifiers, then this result starts a
542 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000543 if (AsNestedNameSpecifier) {
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000544 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000545 R.Priority = CCP_NestedNameSpecifier;
546 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000547
Douglas Gregor0563c262009-09-22 23:15:58 +0000548 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000549 if (R.QualifierIsInformative && !R.Qualifier &&
550 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000551 DeclContext *Ctx = R.Declaration->getDeclContext();
552 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
553 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
554 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
555 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
556 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
557 else
558 R.QualifierIsInformative = false;
559 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000560
Douglas Gregor86d9a522009-09-21 16:56:56 +0000561 // Insert this result into the set of results and into the current shadow
562 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000563 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000564 Results.push_back(R);
565}
566
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000567void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000568 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000569 if (R.Kind != Result::RK_Declaration) {
570 // For non-declaration results, just add the result.
571 Results.push_back(R);
572 return;
573 }
574
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000575 // Look through using declarations.
576 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
577 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
578 return;
579 }
580
Douglas Gregor45bcd432010-01-14 03:21:49 +0000581 bool AsNestedNameSpecifier = false;
582 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000583 return;
584
585 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
586 return;
587
588 // Make sure that any given declaration only shows up in the result set once.
589 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
590 return;
591
592 // If the filter is for nested-name-specifiers, then this result starts a
593 // nested-name-specifier.
Douglas Gregor12e13132010-05-26 22:00:08 +0000594 if (AsNestedNameSpecifier) {
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000595 R.StartsNestedNameSpecifier = true;
Douglas Gregor12e13132010-05-26 22:00:08 +0000596 R.Priority = CCP_NestedNameSpecifier;
597 }
Douglas Gregor0cc84042010-01-14 15:47:35 +0000598 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
599 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
600 ->getLookupContext()))
601 R.QualifierIsInformative = true;
602
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000603 // If this result is supposed to have an informative qualifier, add one.
604 if (R.QualifierIsInformative && !R.Qualifier &&
605 !R.StartsNestedNameSpecifier) {
606 DeclContext *Ctx = R.Declaration->getDeclContext();
607 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
608 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
609 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
610 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000611 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000612 else
613 R.QualifierIsInformative = false;
614 }
615
Douglas Gregor12e13132010-05-26 22:00:08 +0000616 // Adjust the priority if this result comes from a base class.
617 if (InBaseClass)
618 R.Priority += CCD_InBaseClass;
619
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000620 // Insert this result into the set of results.
621 Results.push_back(R);
622}
623
Douglas Gregora4477812010-01-14 16:01:26 +0000624void ResultBuilder::AddResult(Result R) {
625 assert(R.Kind != Result::RK_Declaration &&
626 "Declaration results need more context");
627 Results.push_back(R);
628}
629
Douglas Gregor86d9a522009-09-21 16:56:56 +0000630/// \brief Enter into a new scope.
631void ResultBuilder::EnterNewScope() {
632 ShadowMaps.push_back(ShadowMap());
633}
634
635/// \brief Exit from the current scope.
636void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000637 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
638 EEnd = ShadowMaps.back().end();
639 E != EEnd;
640 ++E)
641 E->second.Destroy();
642
Douglas Gregor86d9a522009-09-21 16:56:56 +0000643 ShadowMaps.pop_back();
644}
645
Douglas Gregor791215b2009-09-21 20:51:25 +0000646/// \brief Determines whether this given declaration will be found by
647/// ordinary name lookup.
648bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
649 unsigned IDNS = Decl::IDNS_Ordinary;
650 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000651 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000652 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
653 return true;
654
Douglas Gregor791215b2009-09-21 20:51:25 +0000655 return ND->getIdentifierNamespace() & IDNS;
656}
657
Douglas Gregor01dfea02010-01-10 23:08:15 +0000658/// \brief Determines whether this given declaration will be found by
659/// ordinary name lookup.
660bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
661 unsigned IDNS = Decl::IDNS_Ordinary;
662 if (SemaRef.getLangOptions().CPlusPlus)
John McCall0d6b1642010-04-23 18:46:30 +0000663 IDNS |= Decl::IDNS_Tag | Decl::IDNS_Namespace;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000664
665 return (ND->getIdentifierNamespace() & IDNS) &&
666 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
667}
668
Douglas Gregor86d9a522009-09-21 16:56:56 +0000669/// \brief Determines whether the given declaration is suitable as the
670/// start of a C++ nested-name-specifier, e.g., a class or namespace.
671bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
672 // Allow us to find class templates, too.
673 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
674 ND = ClassTemplate->getTemplatedDecl();
675
676 return SemaRef.isAcceptableNestedNameSpecifier(ND);
677}
678
679/// \brief Determines whether the given declaration is an enumeration.
680bool ResultBuilder::IsEnum(NamedDecl *ND) const {
681 return isa<EnumDecl>(ND);
682}
683
684/// \brief Determines whether the given declaration is a class or struct.
685bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
686 // Allow us to find class templates, too.
687 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
688 ND = ClassTemplate->getTemplatedDecl();
689
690 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000691 return RD->getTagKind() == TTK_Class ||
692 RD->getTagKind() == TTK_Struct;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000693
694 return false;
695}
696
697/// \brief Determines whether the given declaration is a union.
698bool ResultBuilder::IsUnion(NamedDecl *ND) const {
699 // Allow us to find class templates, too.
700 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
701 ND = ClassTemplate->getTemplatedDecl();
702
703 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
Abramo Bagnara465d41b2010-05-11 21:36:43 +0000704 return RD->getTagKind() == TTK_Union;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000705
706 return false;
707}
708
709/// \brief Determines whether the given declaration is a namespace.
710bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
711 return isa<NamespaceDecl>(ND);
712}
713
714/// \brief Determines whether the given declaration is a namespace or
715/// namespace alias.
716bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
717 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
718}
719
Douglas Gregor76282942009-12-11 17:31:05 +0000720/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000721bool ResultBuilder::IsType(NamedDecl *ND) const {
722 return isa<TypeDecl>(ND);
723}
724
Douglas Gregor76282942009-12-11 17:31:05 +0000725/// \brief Determines which members of a class should be visible via
726/// "." or "->". Only value declarations, nested name specifiers, and
727/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000728bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000729 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
730 ND = Using->getTargetDecl();
731
Douglas Gregorce821962009-12-11 18:14:22 +0000732 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
733 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000734}
735
Douglas Gregor8e254cf2010-05-27 23:06:34 +0000736/// \brief Get the type that a given expression will have if this declaration
737/// is used as an expression in its "typical" code-completion form.
738static QualType getDeclUsageType(ASTContext &C, NamedDecl *ND) {
739 ND = cast<NamedDecl>(ND->getUnderlyingDecl());
740
741 if (TypeDecl *Type = dyn_cast<TypeDecl>(ND))
742 return C.getTypeDeclType(Type);
743 if (ObjCInterfaceDecl *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
744 return C.getObjCInterfaceType(Iface);
745
746 QualType T;
747 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
748 T = Function->getResultType();
749 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
750 T = Method->getResultType();
751 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
752 T = FunTmpl->getTemplatedDecl()->getResultType();
753 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
754 T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
755 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
756 T = Property->getType();
757 else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
758 T = Value->getType();
759 else
760 return QualType();
761
762 return T.getNonReferenceType();
763}
764
765static bool isObjCReceiverType(ASTContext &C, QualType T) {
766 T = C.getCanonicalType(T);
767 switch (T->getTypeClass()) {
768 case Type::ObjCObject:
769 case Type::ObjCInterface:
770 case Type::ObjCObjectPointer:
771 return true;
772
773 case Type::Builtin:
774 switch (cast<BuiltinType>(T)->getKind()) {
775 case BuiltinType::ObjCId:
776 case BuiltinType::ObjCClass:
777 case BuiltinType::ObjCSel:
778 return true;
779
780 default:
781 break;
782 }
783 return false;
784
785 default:
786 break;
787 }
788
789 if (!C.getLangOptions().CPlusPlus)
790 return false;
791
792 // FIXME: We could perform more analysis here to determine whether a
793 // particular class type has any conversions to Objective-C types. For now,
794 // just accept all class types.
795 return T->isDependentType() || T->isRecordType();
796}
797
798bool ResultBuilder::IsObjCMessageReceiver(NamedDecl *ND) const {
799 QualType T = getDeclUsageType(SemaRef.Context, ND);
800 if (T.isNull())
801 return false;
802
803 T = SemaRef.Context.getBaseElementType(T);
804 return isObjCReceiverType(SemaRef.Context, T);
805}
806
807
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000808/// \rief Determines whether the given declaration is an Objective-C
809/// instance variable.
810bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
811 return isa<ObjCIvarDecl>(ND);
812}
813
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000814namespace {
815 /// \brief Visible declaration consumer that adds a code-completion result
816 /// for each visible declaration.
817 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
818 ResultBuilder &Results;
819 DeclContext *CurContext;
820
821 public:
822 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
823 : Results(Results), CurContext(CurContext) { }
824
Douglas Gregor0cc84042010-01-14 15:47:35 +0000825 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
826 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000827 }
828 };
829}
830
Douglas Gregor86d9a522009-09-21 16:56:56 +0000831/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000832static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000833 ResultBuilder &Results) {
834 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor12e13132010-05-26 22:00:08 +0000835 Results.AddResult(Result("short", CCP_Type));
836 Results.AddResult(Result("long", CCP_Type));
837 Results.AddResult(Result("signed", CCP_Type));
838 Results.AddResult(Result("unsigned", CCP_Type));
839 Results.AddResult(Result("void", CCP_Type));
840 Results.AddResult(Result("char", CCP_Type));
841 Results.AddResult(Result("int", CCP_Type));
842 Results.AddResult(Result("float", CCP_Type));
843 Results.AddResult(Result("double", CCP_Type));
844 Results.AddResult(Result("enum", CCP_Type));
845 Results.AddResult(Result("struct", CCP_Type));
846 Results.AddResult(Result("union", CCP_Type));
847 Results.AddResult(Result("const", CCP_Type));
848 Results.AddResult(Result("volatile", CCP_Type));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000849
Douglas Gregor86d9a522009-09-21 16:56:56 +0000850 if (LangOpts.C99) {
851 // C99-specific
Douglas Gregor12e13132010-05-26 22:00:08 +0000852 Results.AddResult(Result("_Complex", CCP_Type));
853 Results.AddResult(Result("_Imaginary", CCP_Type));
854 Results.AddResult(Result("_Bool", CCP_Type));
855 Results.AddResult(Result("restrict", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000856 }
857
858 if (LangOpts.CPlusPlus) {
859 // C++-specific
Douglas Gregor12e13132010-05-26 22:00:08 +0000860 Results.AddResult(Result("bool", CCP_Type));
861 Results.AddResult(Result("class", CCP_Type));
862 Results.AddResult(Result("wchar_t", CCP_Type));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000863
Douglas Gregord8e8a582010-05-25 21:41:55 +0000864 if (Results.includeCodePatterns()) {
865 // typename qualified-id
866 CodeCompletionString *Pattern = new CodeCompletionString;
867 Pattern->AddTypedTextChunk("typename");
868 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
869 Pattern->AddPlaceholderChunk("qualified-id");
870 Results.AddResult(Result(Pattern));
871 }
872
Douglas Gregor86d9a522009-09-21 16:56:56 +0000873 if (LangOpts.CPlusPlus0x) {
Douglas Gregor12e13132010-05-26 22:00:08 +0000874 Results.AddResult(Result("auto", CCP_Type));
875 Results.AddResult(Result("char16_t", CCP_Type));
876 Results.AddResult(Result("char32_t", CCP_Type));
877 if (Results.includeCodePatterns()) {
878 CodeCompletionString *Pattern = new CodeCompletionString;
879 Pattern->AddTypedTextChunk("decltype");
880 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
881 Pattern->AddPlaceholderChunk("expression-or-type");
882 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
883 Results.AddResult(Result(Pattern));
884 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000885 }
886 }
887
888 // GNU extensions
889 if (LangOpts.GNUMode) {
890 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +0000891 // Results.AddResult(Result("_Decimal32"));
892 // Results.AddResult(Result("_Decimal64"));
893 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000894
Douglas Gregord8e8a582010-05-25 21:41:55 +0000895 if (Results.includeCodePatterns()) {
896 CodeCompletionString *Pattern = new CodeCompletionString;
897 Pattern->AddTypedTextChunk("typeof");
898 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
899 Pattern->AddPlaceholderChunk("expression-or-type");
900 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
901 Results.AddResult(Result(Pattern));
902 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000903 }
904}
905
Douglas Gregor01dfea02010-01-10 23:08:15 +0000906static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
907 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000908 ResultBuilder &Results) {
909 typedef CodeCompleteConsumer::Result Result;
910 // Note: we don't suggest either "auto" or "register", because both
911 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
912 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +0000913 Results.AddResult(Result("extern"));
914 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000915}
916
917static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
918 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000919 ResultBuilder &Results) {
920 typedef CodeCompleteConsumer::Result Result;
921 switch (CCC) {
922 case Action::CCC_Class:
923 case Action::CCC_MemberTemplate:
924 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +0000925 Results.AddResult(Result("explicit"));
926 Results.AddResult(Result("friend"));
927 Results.AddResult(Result("mutable"));
928 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000929 }
930 // Fall through
931
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000932 case Action::CCC_ObjCInterface:
933 case Action::CCC_ObjCImplementation:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000934 case Action::CCC_Namespace:
935 case Action::CCC_Template:
936 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +0000937 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000938 break;
939
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000940 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000941 case Action::CCC_Expression:
942 case Action::CCC_Statement:
943 case Action::CCC_ForInit:
944 case Action::CCC_Condition:
Douglas Gregordc845342010-05-25 05:58:43 +0000945 case Action::CCC_RecoveryInFunction:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000946 break;
947 }
948}
949
Douglas Gregorbca403c2010-01-13 23:51:12 +0000950static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
951static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
952static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000953 ResultBuilder &Results,
954 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000955static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000956 ResultBuilder &Results,
957 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000958static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000959 ResultBuilder &Results,
960 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000961static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000962
Douglas Gregor01dfea02010-01-10 23:08:15 +0000963/// \brief Add language constructs that show up for "ordinary" names.
964static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
965 Scope *S,
966 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000967 ResultBuilder &Results) {
968 typedef CodeCompleteConsumer::Result Result;
969 switch (CCC) {
970 case Action::CCC_Namespace:
Douglas Gregord8e8a582010-05-25 21:41:55 +0000971 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +0000972 // namespace <identifier> { }
973 CodeCompletionString *Pattern = new CodeCompletionString;
974 Pattern->AddTypedTextChunk("namespace");
975 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
976 Pattern->AddPlaceholderChunk("identifier");
977 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
978 Pattern->AddPlaceholderChunk("declarations");
979 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
980 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +0000981 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000982
983 // namespace identifier = identifier ;
984 Pattern = new CodeCompletionString;
985 Pattern->AddTypedTextChunk("namespace");
986 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
987 Pattern->AddPlaceholderChunk("identifier");
988 Pattern->AddChunk(CodeCompletionString::CK_Equal);
989 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +0000990 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000991
992 // Using directives
993 Pattern = new CodeCompletionString;
994 Pattern->AddTypedTextChunk("using");
995 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
996 Pattern->AddTextChunk("namespace");
997 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
998 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +0000999 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001000
1001 // asm(string-literal)
1002 Pattern = new CodeCompletionString;
1003 Pattern->AddTypedTextChunk("asm");
1004 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1005 Pattern->AddPlaceholderChunk("string-literal");
1006 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001007 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001008
1009 // Explicit template instantiation
1010 Pattern = new CodeCompletionString;
1011 Pattern->AddTypedTextChunk("template");
1012 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1013 Pattern->AddPlaceholderChunk("declaration");
Douglas Gregora4477812010-01-14 16:01:26 +00001014 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001015 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001016
1017 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001018 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001019
Douglas Gregor01dfea02010-01-10 23:08:15 +00001020 // Fall through
1021
1022 case Action::CCC_Class:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001023 if (Results.includeCodePatterns())
1024 Results.AddResult(Result("typedef"));
1025
1026 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001027 // Using declaration
1028 CodeCompletionString *Pattern = new CodeCompletionString;
1029 Pattern->AddTypedTextChunk("using");
1030 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1031 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregora4477812010-01-14 16:01:26 +00001032 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001033
1034 // using typename qualified-id; (only in a dependent context)
1035 if (SemaRef.CurContext->isDependentContext()) {
1036 Pattern = new CodeCompletionString;
1037 Pattern->AddTypedTextChunk("using");
1038 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1039 Pattern->AddTextChunk("typename");
1040 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1041 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregora4477812010-01-14 16:01:26 +00001042 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001043 }
1044
1045 if (CCC == Action::CCC_Class) {
1046 // public:
1047 Pattern = new CodeCompletionString;
1048 Pattern->AddTypedTextChunk("public");
1049 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001050 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001051
1052 // protected:
1053 Pattern = new CodeCompletionString;
1054 Pattern->AddTypedTextChunk("protected");
1055 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001056 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001057
1058 // private:
1059 Pattern = new CodeCompletionString;
1060 Pattern->AddTypedTextChunk("private");
1061 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001062 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001063 }
1064 }
1065 // Fall through
1066
1067 case Action::CCC_Template:
1068 case Action::CCC_MemberTemplate:
Douglas Gregord8e8a582010-05-25 21:41:55 +00001069 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001070 // template < parameters >
1071 CodeCompletionString *Pattern = new CodeCompletionString;
1072 Pattern->AddTypedTextChunk("template");
1073 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1074 Pattern->AddPlaceholderChunk("parameters");
1075 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +00001076 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001077 }
1078
Douglas Gregorbca403c2010-01-13 23:51:12 +00001079 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1080 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001081 break;
1082
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001083 case Action::CCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001084 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1085 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1086 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001087 break;
1088
1089 case Action::CCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001090 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1091 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1092 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001093 break;
1094
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001095 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001096 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001097 break;
1098
Douglas Gregordc845342010-05-25 05:58:43 +00001099 case Action::CCC_RecoveryInFunction:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001100 case Action::CCC_Statement: {
Douglas Gregord8e8a582010-05-25 21:41:55 +00001101 if (Results.includeCodePatterns())
1102 Results.AddResult(Result("typedef"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001103
1104 CodeCompletionString *Pattern = 0;
Douglas Gregord8e8a582010-05-25 21:41:55 +00001105 if (SemaRef.getLangOptions().CPlusPlus && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001106 Pattern = new CodeCompletionString;
1107 Pattern->AddTypedTextChunk("try");
1108 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1109 Pattern->AddPlaceholderChunk("statements");
1110 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1111 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1112 Pattern->AddTextChunk("catch");
1113 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1114 Pattern->AddPlaceholderChunk("declaration");
1115 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1116 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1117 Pattern->AddPlaceholderChunk("statements");
1118 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1119 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001120 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001121 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001122 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001123 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001124
Douglas Gregord8e8a582010-05-25 21:41:55 +00001125 if (Results.includeCodePatterns()) {
1126 // if (condition) { statements }
1127 Pattern = new CodeCompletionString;
1128 Pattern->AddTypedTextChunk("if");
1129 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1130 if (SemaRef.getLangOptions().CPlusPlus)
1131 Pattern->AddPlaceholderChunk("condition");
1132 else
1133 Pattern->AddPlaceholderChunk("expression");
1134 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1135 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1136 Pattern->AddPlaceholderChunk("statements");
1137 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1138 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1139 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001140
Douglas Gregord8e8a582010-05-25 21:41:55 +00001141 // switch (condition) { }
1142 Pattern = new CodeCompletionString;
1143 Pattern->AddTypedTextChunk("switch");
1144 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1145 if (SemaRef.getLangOptions().CPlusPlus)
1146 Pattern->AddPlaceholderChunk("condition");
1147 else
1148 Pattern->AddPlaceholderChunk("expression");
1149 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1150 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1151 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1152 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1153 Results.AddResult(Result(Pattern));
1154 }
1155
Douglas Gregor01dfea02010-01-10 23:08:15 +00001156 // Switch-specific statements.
Douglas Gregord8e8a582010-05-25 21:41:55 +00001157 if (!SemaRef.getSwitchStack().empty() && Results.includeCodePatterns()) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00001158 // case expression:
1159 Pattern = new CodeCompletionString;
1160 Pattern->AddTypedTextChunk("case");
1161 Pattern->AddPlaceholderChunk("expression");
1162 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001163 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001164
1165 // default:
1166 Pattern = new CodeCompletionString;
1167 Pattern->AddTypedTextChunk("default");
1168 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001169 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001170 }
1171
Douglas Gregord8e8a582010-05-25 21:41:55 +00001172 if (Results.includeCodePatterns()) {
1173 /// while (condition) { statements }
1174 Pattern = new CodeCompletionString;
1175 Pattern->AddTypedTextChunk("while");
1176 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1177 if (SemaRef.getLangOptions().CPlusPlus)
1178 Pattern->AddPlaceholderChunk("condition");
1179 else
1180 Pattern->AddPlaceholderChunk("expression");
1181 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1182 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1183 Pattern->AddPlaceholderChunk("statements");
1184 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1185 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1186 Results.AddResult(Result(Pattern));
1187
1188 // do { statements } while ( expression );
1189 Pattern = new CodeCompletionString;
1190 Pattern->AddTypedTextChunk("do");
1191 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1192 Pattern->AddPlaceholderChunk("statements");
1193 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1194 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1195 Pattern->AddTextChunk("while");
1196 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001197 Pattern->AddPlaceholderChunk("expression");
Douglas Gregord8e8a582010-05-25 21:41:55 +00001198 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1199 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001200
Douglas Gregord8e8a582010-05-25 21:41:55 +00001201 // for ( for-init-statement ; condition ; expression ) { statements }
1202 Pattern = new CodeCompletionString;
1203 Pattern->AddTypedTextChunk("for");
1204 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1205 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1206 Pattern->AddPlaceholderChunk("init-statement");
1207 else
1208 Pattern->AddPlaceholderChunk("init-expression");
1209 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1210 Pattern->AddPlaceholderChunk("condition");
1211 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1212 Pattern->AddPlaceholderChunk("inc-expression");
1213 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1214 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1215 Pattern->AddPlaceholderChunk("statements");
1216 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1217 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1218 Results.AddResult(Result(Pattern));
1219 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001220
1221 if (S->getContinueParent()) {
1222 // continue ;
1223 Pattern = new CodeCompletionString;
1224 Pattern->AddTypedTextChunk("continue");
Douglas Gregora4477812010-01-14 16:01:26 +00001225 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001226 }
1227
1228 if (S->getBreakParent()) {
1229 // break ;
1230 Pattern = new CodeCompletionString;
1231 Pattern->AddTypedTextChunk("break");
Douglas Gregora4477812010-01-14 16:01:26 +00001232 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001233 }
1234
1235 // "return expression ;" or "return ;", depending on whether we
1236 // know the function is void or not.
1237 bool isVoid = false;
1238 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1239 isVoid = Function->getResultType()->isVoidType();
1240 else if (ObjCMethodDecl *Method
1241 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1242 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001243 else if (SemaRef.getCurBlock() &&
1244 !SemaRef.getCurBlock()->ReturnType.isNull())
1245 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001246 Pattern = new CodeCompletionString;
1247 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001248 if (!isVoid) {
1249 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001250 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001251 }
Douglas Gregora4477812010-01-14 16:01:26 +00001252 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001253
Douglas Gregord8e8a582010-05-25 21:41:55 +00001254 if (Results.includeCodePatterns()) {
1255 // goto identifier ;
1256 Pattern = new CodeCompletionString;
1257 Pattern->AddTypedTextChunk("goto");
1258 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1259 Pattern->AddPlaceholderChunk("identifier");
1260 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001261
Douglas Gregord8e8a582010-05-25 21:41:55 +00001262 // Using directives
1263 Pattern = new CodeCompletionString;
1264 Pattern->AddTypedTextChunk("using");
1265 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1266 Pattern->AddTextChunk("namespace");
1267 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1268 Pattern->AddPlaceholderChunk("identifier");
1269 Results.AddResult(Result(Pattern));
1270 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001271 }
1272
1273 // Fall through (for statement expressions).
1274 case Action::CCC_ForInit:
1275 case Action::CCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001276 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001277 // Fall through: conditions and statements can have expressions.
1278
1279 case Action::CCC_Expression: {
1280 CodeCompletionString *Pattern = 0;
1281 if (SemaRef.getLangOptions().CPlusPlus) {
1282 // 'this', if we're in a non-static member function.
1283 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1284 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001285 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001286
1287 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001288 Results.AddResult(Result("true"));
1289 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001290
Douglas Gregord8e8a582010-05-25 21:41:55 +00001291 if (Results.includeCodePatterns()) {
1292 // dynamic_cast < type-id > ( expression )
1293 Pattern = new CodeCompletionString;
1294 Pattern->AddTypedTextChunk("dynamic_cast");
1295 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1296 Pattern->AddPlaceholderChunk("type-id");
1297 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1298 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1299 Pattern->AddPlaceholderChunk("expression");
1300 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1301 Results.AddResult(Result(Pattern));
1302
1303 // static_cast < type-id > ( expression )
1304 Pattern = new CodeCompletionString;
1305 Pattern->AddTypedTextChunk("static_cast");
1306 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1307 Pattern->AddPlaceholderChunk("type-id");
1308 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1309 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1310 Pattern->AddPlaceholderChunk("expression");
1311 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1312 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001313
Douglas Gregord8e8a582010-05-25 21:41:55 +00001314 // reinterpret_cast < type-id > ( expression )
1315 Pattern = new CodeCompletionString;
1316 Pattern->AddTypedTextChunk("reinterpret_cast");
1317 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1318 Pattern->AddPlaceholderChunk("type-id");
1319 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1320 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1321 Pattern->AddPlaceholderChunk("expression");
1322 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1323 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001324
Douglas Gregord8e8a582010-05-25 21:41:55 +00001325 // const_cast < type-id > ( expression )
1326 Pattern = new CodeCompletionString;
1327 Pattern->AddTypedTextChunk("const_cast");
1328 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1329 Pattern->AddPlaceholderChunk("type-id");
1330 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1331 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1332 Pattern->AddPlaceholderChunk("expression");
1333 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1334 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001335
Douglas Gregord8e8a582010-05-25 21:41:55 +00001336 // typeid ( expression-or-type )
1337 Pattern = new CodeCompletionString;
1338 Pattern->AddTypedTextChunk("typeid");
1339 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1340 Pattern->AddPlaceholderChunk("expression-or-type");
1341 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1342 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001343
Douglas Gregord8e8a582010-05-25 21:41:55 +00001344 // new T ( ... )
1345 Pattern = new CodeCompletionString;
1346 Pattern->AddTypedTextChunk("new");
1347 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1348 Pattern->AddPlaceholderChunk("type-id");
1349 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1350 Pattern->AddPlaceholderChunk("expressions");
1351 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1352 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001353
Douglas Gregord8e8a582010-05-25 21:41:55 +00001354 // new T [ ] ( ... )
1355 Pattern = new CodeCompletionString;
1356 Pattern->AddTypedTextChunk("new");
1357 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1358 Pattern->AddPlaceholderChunk("type-id");
1359 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1360 Pattern->AddPlaceholderChunk("size");
1361 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1362 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1363 Pattern->AddPlaceholderChunk("expressions");
1364 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1365 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001366
Douglas Gregord8e8a582010-05-25 21:41:55 +00001367 // delete expression
1368 Pattern = new CodeCompletionString;
1369 Pattern->AddTypedTextChunk("delete");
1370 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1371 Pattern->AddPlaceholderChunk("expression");
1372 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001373
Douglas Gregord8e8a582010-05-25 21:41:55 +00001374 // delete [] expression
1375 Pattern = new CodeCompletionString;
1376 Pattern->AddTypedTextChunk("delete");
1377 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1378 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1379 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1380 Pattern->AddPlaceholderChunk("expression");
1381 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001382
Douglas Gregord8e8a582010-05-25 21:41:55 +00001383 // throw expression
1384 Pattern = new CodeCompletionString;
1385 Pattern->AddTypedTextChunk("throw");
1386 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1387 Pattern->AddPlaceholderChunk("expression");
1388 Results.AddResult(Result(Pattern));
1389 }
Douglas Gregor12e13132010-05-26 22:00:08 +00001390
1391 // FIXME: Rethrow?
Douglas Gregor01dfea02010-01-10 23:08:15 +00001392 }
1393
1394 if (SemaRef.getLangOptions().ObjC1) {
1395 // Add "super", if we're in an Objective-C class with a superclass.
1396 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1397 if (Method->getClassInterface()->getSuperClass())
Douglas Gregora4477812010-01-14 16:01:26 +00001398 Results.AddResult(Result("super"));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001399
Douglas Gregorbca403c2010-01-13 23:51:12 +00001400 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001401 }
1402
Douglas Gregord8e8a582010-05-25 21:41:55 +00001403 if (Results.includeCodePatterns()) {
1404 // sizeof expression
1405 Pattern = new CodeCompletionString;
1406 Pattern->AddTypedTextChunk("sizeof");
1407 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1408 Pattern->AddPlaceholderChunk("expression-or-type");
1409 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1410 Results.AddResult(Result(Pattern));
1411 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001412 break;
1413 }
1414 }
1415
Douglas Gregorbca403c2010-01-13 23:51:12 +00001416 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001417
1418 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregora4477812010-01-14 16:01:26 +00001419 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001420}
1421
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001422/// \brief If the given declaration has an associated type, add it as a result
1423/// type chunk.
1424static void AddResultTypeChunk(ASTContext &Context,
1425 NamedDecl *ND,
1426 CodeCompletionString *Result) {
1427 if (!ND)
1428 return;
1429
1430 // Determine the type of the declaration (if it has a type).
1431 QualType T;
1432 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1433 T = Function->getResultType();
1434 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1435 T = Method->getResultType();
1436 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1437 T = FunTmpl->getTemplatedDecl()->getResultType();
1438 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1439 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1440 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1441 /* Do nothing: ignore unresolved using declarations*/
1442 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1443 T = Value->getType();
1444 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1445 T = Property->getType();
1446
1447 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1448 return;
1449
Douglas Gregor84139d62010-04-05 21:25:31 +00001450 PrintingPolicy Policy(Context.PrintingPolicy);
1451 Policy.AnonymousTagLocations = false;
1452
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001453 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001454 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001455 Result->AddResultTypeChunk(TypeStr);
1456}
1457
Douglas Gregor86d9a522009-09-21 16:56:56 +00001458/// \brief Add function parameter chunks to the given code completion string.
1459static void AddFunctionParameterChunks(ASTContext &Context,
1460 FunctionDecl *Function,
1461 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001462 typedef CodeCompletionString::Chunk Chunk;
1463
Douglas Gregor86d9a522009-09-21 16:56:56 +00001464 CodeCompletionString *CCStr = Result;
1465
1466 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1467 ParmVarDecl *Param = Function->getParamDecl(P);
1468
1469 if (Param->hasDefaultArg()) {
1470 // When we see an optional default argument, put that argument and
1471 // the remaining default arguments into a new, optional string.
1472 CodeCompletionString *Opt = new CodeCompletionString;
1473 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1474 CCStr = Opt;
1475 }
1476
1477 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001478 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001479
1480 // Format the placeholder string.
1481 std::string PlaceholderStr;
1482 if (Param->getIdentifier())
1483 PlaceholderStr = Param->getIdentifier()->getName();
1484
1485 Param->getType().getAsStringInternal(PlaceholderStr,
1486 Context.PrintingPolicy);
1487
1488 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001489 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001490 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001491
1492 if (const FunctionProtoType *Proto
1493 = Function->getType()->getAs<FunctionProtoType>())
1494 if (Proto->isVariadic())
1495 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001496}
1497
1498/// \brief Add template parameter chunks to the given code completion string.
1499static void AddTemplateParameterChunks(ASTContext &Context,
1500 TemplateDecl *Template,
1501 CodeCompletionString *Result,
1502 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001503 typedef CodeCompletionString::Chunk Chunk;
1504
Douglas Gregor86d9a522009-09-21 16:56:56 +00001505 CodeCompletionString *CCStr = Result;
1506 bool FirstParameter = true;
1507
1508 TemplateParameterList *Params = Template->getTemplateParameters();
1509 TemplateParameterList::iterator PEnd = Params->end();
1510 if (MaxParameters)
1511 PEnd = Params->begin() + MaxParameters;
1512 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1513 bool HasDefaultArg = false;
1514 std::string PlaceholderStr;
1515 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1516 if (TTP->wasDeclaredWithTypename())
1517 PlaceholderStr = "typename";
1518 else
1519 PlaceholderStr = "class";
1520
1521 if (TTP->getIdentifier()) {
1522 PlaceholderStr += ' ';
1523 PlaceholderStr += TTP->getIdentifier()->getName();
1524 }
1525
1526 HasDefaultArg = TTP->hasDefaultArgument();
1527 } else if (NonTypeTemplateParmDecl *NTTP
1528 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1529 if (NTTP->getIdentifier())
1530 PlaceholderStr = NTTP->getIdentifier()->getName();
1531 NTTP->getType().getAsStringInternal(PlaceholderStr,
1532 Context.PrintingPolicy);
1533 HasDefaultArg = NTTP->hasDefaultArgument();
1534 } else {
1535 assert(isa<TemplateTemplateParmDecl>(*P));
1536 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1537
1538 // Since putting the template argument list into the placeholder would
1539 // be very, very long, we just use an abbreviation.
1540 PlaceholderStr = "template<...> class";
1541 if (TTP->getIdentifier()) {
1542 PlaceholderStr += ' ';
1543 PlaceholderStr += TTP->getIdentifier()->getName();
1544 }
1545
1546 HasDefaultArg = TTP->hasDefaultArgument();
1547 }
1548
1549 if (HasDefaultArg) {
1550 // When we see an optional default argument, put that argument and
1551 // the remaining default arguments into a new, optional string.
1552 CodeCompletionString *Opt = new CodeCompletionString;
1553 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1554 CCStr = Opt;
1555 }
1556
1557 if (FirstParameter)
1558 FirstParameter = false;
1559 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001560 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001561
1562 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001563 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001564 }
1565}
1566
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001567/// \brief Add a qualifier to the given code-completion string, if the
1568/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001569static void
1570AddQualifierToCompletionString(CodeCompletionString *Result,
1571 NestedNameSpecifier *Qualifier,
1572 bool QualifierIsInformative,
1573 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001574 if (!Qualifier)
1575 return;
1576
1577 std::string PrintedNNS;
1578 {
1579 llvm::raw_string_ostream OS(PrintedNNS);
1580 Qualifier->print(OS, Context.PrintingPolicy);
1581 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001582 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001583 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001584 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001585 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001586}
1587
Douglas Gregora61a8792009-12-11 18:44:16 +00001588static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1589 FunctionDecl *Function) {
1590 const FunctionProtoType *Proto
1591 = Function->getType()->getAs<FunctionProtoType>();
1592 if (!Proto || !Proto->getTypeQuals())
1593 return;
1594
1595 std::string QualsStr;
1596 if (Proto->getTypeQuals() & Qualifiers::Const)
1597 QualsStr += " const";
1598 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1599 QualsStr += " volatile";
1600 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1601 QualsStr += " restrict";
1602 Result->AddInformativeChunk(QualsStr);
1603}
1604
Douglas Gregor86d9a522009-09-21 16:56:56 +00001605/// \brief If possible, create a new code completion string for the given
1606/// result.
1607///
1608/// \returns Either a new, heap-allocated code completion string describing
1609/// how to use this result, or NULL to indicate that the string or name of the
1610/// result is all that is needed.
1611CodeCompletionString *
1612CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001613 typedef CodeCompletionString::Chunk Chunk;
1614
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001615 if (Kind == RK_Pattern)
1616 return Pattern->Clone();
1617
1618 CodeCompletionString *Result = new CodeCompletionString;
1619
1620 if (Kind == RK_Keyword) {
1621 Result->AddTypedTextChunk(Keyword);
1622 return Result;
1623 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001624
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001625 if (Kind == RK_Macro) {
1626 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001627 assert(MI && "Not a macro?");
1628
1629 Result->AddTypedTextChunk(Macro->getName());
1630
1631 if (!MI->isFunctionLike())
1632 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001633
1634 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001635 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001636 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1637 A != AEnd; ++A) {
1638 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001639 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001640
1641 if (!MI->isVariadic() || A != AEnd - 1) {
1642 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001643 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001644 continue;
1645 }
1646
1647 // Variadic argument; cope with the different between GNU and C99
1648 // variadic macros, providing a single placeholder for the rest of the
1649 // arguments.
1650 if ((*A)->isStr("__VA_ARGS__"))
1651 Result->AddPlaceholderChunk("...");
1652 else {
1653 std::string Arg = (*A)->getName();
1654 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001655 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001656 }
1657 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001658 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001659 return Result;
1660 }
1661
Douglas Gregord8e8a582010-05-25 21:41:55 +00001662 assert(Kind == RK_Declaration && "Missed a result kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001663 NamedDecl *ND = Declaration;
1664
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001665 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001666 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001667 Result->AddTextChunk("::");
1668 return Result;
1669 }
1670
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001671 AddResultTypeChunk(S.Context, ND, Result);
1672
Douglas Gregor86d9a522009-09-21 16:56:56 +00001673 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001674 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1675 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001676 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001677 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001678 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001679 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001680 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001681 return Result;
1682 }
1683
1684 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001685 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1686 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001687 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001688 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001689
1690 // Figure out which template parameters are deduced (or have default
1691 // arguments).
1692 llvm::SmallVector<bool, 16> Deduced;
1693 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1694 unsigned LastDeducibleArgument;
1695 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1696 --LastDeducibleArgument) {
1697 if (!Deduced[LastDeducibleArgument - 1]) {
1698 // C++0x: Figure out if the template argument has a default. If so,
1699 // the user doesn't need to type this argument.
1700 // FIXME: We need to abstract template parameters better!
1701 bool HasDefaultArg = false;
1702 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1703 LastDeducibleArgument - 1);
1704 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1705 HasDefaultArg = TTP->hasDefaultArgument();
1706 else if (NonTypeTemplateParmDecl *NTTP
1707 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1708 HasDefaultArg = NTTP->hasDefaultArgument();
1709 else {
1710 assert(isa<TemplateTemplateParmDecl>(Param));
1711 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001712 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001713 }
1714
1715 if (!HasDefaultArg)
1716 break;
1717 }
1718 }
1719
1720 if (LastDeducibleArgument) {
1721 // Some of the function template arguments cannot be deduced from a
1722 // function call, so we introduce an explicit template argument list
1723 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001724 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001725 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1726 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001727 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001728 }
1729
1730 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001731 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001732 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001733 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001734 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001735 return Result;
1736 }
1737
1738 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001739 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1740 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001741 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001742 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001743 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001744 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001745 return Result;
1746 }
1747
Douglas Gregor9630eb62009-11-17 16:44:22 +00001748 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001749 Selector Sel = Method->getSelector();
1750 if (Sel.isUnarySelector()) {
1751 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1752 return Result;
1753 }
1754
Douglas Gregord3c68542009-11-19 01:08:35 +00001755 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1756 SelName += ':';
1757 if (StartParameter == 0)
1758 Result->AddTypedTextChunk(SelName);
1759 else {
1760 Result->AddInformativeChunk(SelName);
1761
1762 // If there is only one parameter, and we're past it, add an empty
1763 // typed-text chunk since there is nothing to type.
1764 if (Method->param_size() == 1)
1765 Result->AddTypedTextChunk("");
1766 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001767 unsigned Idx = 0;
1768 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1769 PEnd = Method->param_end();
1770 P != PEnd; (void)++P, ++Idx) {
1771 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001772 std::string Keyword;
1773 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00001774 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001775 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1776 Keyword += II->getName().str();
1777 Keyword += ":";
Douglas Gregor4ad96852009-11-19 07:41:15 +00001778 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001779 Result->AddInformativeChunk(Keyword);
1780 } else if (Idx == StartParameter)
1781 Result->AddTypedTextChunk(Keyword);
1782 else
1783 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001784 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001785
1786 // If we're before the starting parameter, skip the placeholder.
1787 if (Idx < StartParameter)
1788 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001789
1790 std::string Arg;
1791 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1792 Arg = "(" + Arg + ")";
1793 if (IdentifierInfo *II = (*P)->getIdentifier())
1794 Arg += II->getName().str();
Douglas Gregor4ad96852009-11-19 07:41:15 +00001795 if (AllParametersAreInformative)
1796 Result->AddInformativeChunk(Arg);
1797 else
1798 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001799 }
1800
Douglas Gregor2a17af02009-12-23 00:21:46 +00001801 if (Method->isVariadic()) {
1802 if (AllParametersAreInformative)
1803 Result->AddInformativeChunk(", ...");
1804 else
1805 Result->AddPlaceholderChunk(", ...");
1806 }
1807
Douglas Gregor9630eb62009-11-17 16:44:22 +00001808 return Result;
1809 }
1810
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001811 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00001812 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1813 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001814
1815 Result->AddTypedTextChunk(ND->getNameAsString());
1816 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001817}
1818
Douglas Gregor86d802e2009-09-23 00:34:09 +00001819CodeCompletionString *
1820CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1821 unsigned CurrentArg,
1822 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001823 typedef CodeCompletionString::Chunk Chunk;
1824
Douglas Gregor86d802e2009-09-23 00:34:09 +00001825 CodeCompletionString *Result = new CodeCompletionString;
1826 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001827 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001828 const FunctionProtoType *Proto
1829 = dyn_cast<FunctionProtoType>(getFunctionType());
1830 if (!FDecl && !Proto) {
1831 // Function without a prototype. Just give the return type and a
1832 // highlighted ellipsis.
1833 const FunctionType *FT = getFunctionType();
1834 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001835 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001836 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1837 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1838 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001839 return Result;
1840 }
1841
1842 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001843 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00001844 else
1845 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001846 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001847
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001848 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001849 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1850 for (unsigned I = 0; I != NumParams; ++I) {
1851 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001852 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001853
1854 std::string ArgString;
1855 QualType ArgType;
1856
1857 if (FDecl) {
1858 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1859 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1860 } else {
1861 ArgType = Proto->getArgType(I);
1862 }
1863
1864 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1865
1866 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001867 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00001868 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001869 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001870 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001871 }
1872
1873 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001874 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001875 if (CurrentArg < NumParams)
1876 Result->AddTextChunk("...");
1877 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001878 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001879 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001880 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001881
1882 return Result;
1883}
1884
Douglas Gregor86d9a522009-09-21 16:56:56 +00001885namespace {
1886 struct SortCodeCompleteResult {
1887 typedef CodeCompleteConsumer::Result Result;
1888
Douglas Gregor6a684032009-09-28 03:51:44 +00001889 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001890 Selector XSel = X.getObjCSelector();
1891 Selector YSel = Y.getObjCSelector();
1892 if (!XSel.isNull() && !YSel.isNull()) {
1893 // We are comparing two selectors.
1894 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1895 if (N == 0)
1896 ++N;
1897 for (unsigned I = 0; I != N; ++I) {
1898 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1899 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1900 if (!XId || !YId)
1901 return XId && !YId;
1902
1903 switch (XId->getName().compare_lower(YId->getName())) {
1904 case -1: return true;
1905 case 1: return false;
1906 default: break;
1907 }
1908 }
1909
1910 return XSel.getNumArgs() < YSel.getNumArgs();
1911 }
1912
1913 // For non-selectors, order by kind.
1914 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00001915 return X.getNameKind() < Y.getNameKind();
1916
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001917 // Order identifiers by comparison of their lowercased names.
1918 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1919 return XId->getName().compare_lower(
1920 Y.getAsIdentifierInfo()->getName()) < 0;
1921
1922 // Order overloaded operators by the order in which they appear
1923 // in our list of operators.
1924 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1925 return XOp < Y.getCXXOverloadedOperator();
1926
1927 // Order C++0x user-defined literal operators lexically by their
1928 // lowercased suffixes.
1929 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1930 return XLit->getName().compare_lower(
1931 Y.getCXXLiteralIdentifier()->getName()) < 0;
1932
1933 // The only stable ordering we have is to turn the name into a
1934 // string and then compare the lower-case strings. This is
1935 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00001936 return llvm::StringRef(X.getAsString()).compare_lower(
1937 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00001938 }
1939
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001940 /// \brief Retrieve the name that should be used to order a result.
1941 ///
1942 /// If the name needs to be constructed as a string, that string will be
1943 /// saved into Saved and the returned StringRef will refer to it.
1944 static llvm::StringRef getOrderedName(const Result &R,
1945 std::string &Saved) {
1946 switch (R.Kind) {
1947 case Result::RK_Keyword:
1948 return R.Keyword;
1949
1950 case Result::RK_Pattern:
1951 return R.Pattern->getTypedText();
1952
1953 case Result::RK_Macro:
1954 return R.Macro->getName();
1955
1956 case Result::RK_Declaration:
1957 // Handle declarations below.
1958 break;
Douglas Gregor54f01612009-11-19 00:01:57 +00001959 }
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001960
1961 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor54f01612009-11-19 00:01:57 +00001962
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001963 // If the name is a simple identifier (by far the common case), or a
1964 // zero-argument selector, just return a reference to that identifier.
1965 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
1966 return Id->getName();
1967 if (Name.isObjCZeroArgSelector())
1968 if (IdentifierInfo *Id
1969 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
1970 return Id->getName();
1971
1972 Saved = Name.getAsString();
1973 return Saved;
1974 }
1975
1976 bool operator()(const Result &X, const Result &Y) const {
1977 std::string XSaved, YSaved;
1978 llvm::StringRef XStr = getOrderedName(X, XSaved);
1979 llvm::StringRef YStr = getOrderedName(Y, YSaved);
1980 int cmp = XStr.compare_lower(YStr);
1981 if (cmp)
1982 return cmp < 0;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001983
1984 // Non-hidden names precede hidden names.
1985 if (X.Hidden != Y.Hidden)
1986 return !X.Hidden;
1987
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001988 // Non-nested-name-specifiers precede nested-name-specifiers.
1989 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1990 return !X.StartsNestedNameSpecifier;
1991
Douglas Gregor86d9a522009-09-21 16:56:56 +00001992 return false;
1993 }
1994 };
1995}
1996
Douglas Gregorbca403c2010-01-13 23:51:12 +00001997static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001998 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001999 for (Preprocessor::macro_iterator M = PP.macro_begin(),
2000 MEnd = PP.macro_end();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002001 M != MEnd; ++M)
Douglas Gregora4477812010-01-14 16:01:26 +00002002 Results.AddResult(M->first);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00002003 Results.ExitScope();
2004}
2005
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002006static void HandleCodeCompleteResults(Sema *S,
2007 CodeCompleteConsumer *CodeCompleter,
2008 CodeCompleteConsumer::Result *Results,
2009 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00002010 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
2011
2012 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002013 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00002014
2015 for (unsigned I = 0; I != NumResults; ++I)
2016 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002017}
2018
Douglas Gregor01dfea02010-01-10 23:08:15 +00002019void Sema::CodeCompleteOrdinaryName(Scope *S,
2020 CodeCompletionContext CompletionContext) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002021 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002022 ResultBuilder Results(*this);
2023
2024 // Determine how to filter results, e.g., so that the names of
2025 // values (functions, enumerators, function templates, etc.) are
2026 // only allowed where we can have an expression.
2027 switch (CompletionContext) {
2028 case CCC_Namespace:
2029 case CCC_Class:
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002030 case CCC_ObjCInterface:
2031 case CCC_ObjCImplementation:
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002032 case CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +00002033 case CCC_Template:
2034 case CCC_MemberTemplate:
2035 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
2036 break;
2037
2038 case CCC_Expression:
2039 case CCC_Statement:
2040 case CCC_ForInit:
2041 case CCC_Condition:
2042 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2043 break;
Douglas Gregordc845342010-05-25 05:58:43 +00002044
2045 case CCC_RecoveryInFunction:
2046 // Unfiltered
2047 break;
Douglas Gregor01dfea02010-01-10 23:08:15 +00002048 }
2049
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002050 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2051 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002052
2053 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002054 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002055 Results.ExitScope();
2056
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002057 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002058 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002059 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002060}
2061
Douglas Gregor95ac6552009-11-18 01:29:26 +00002062static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002063 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002064 DeclContext *CurContext,
2065 ResultBuilder &Results) {
2066 typedef CodeCompleteConsumer::Result Result;
2067
2068 // Add properties in this container.
2069 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2070 PEnd = Container->prop_end();
2071 P != PEnd;
2072 ++P)
2073 Results.MaybeAddResult(Result(*P, 0), CurContext);
2074
2075 // Add properties in referenced protocols.
2076 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2077 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2078 PEnd = Protocol->protocol_end();
2079 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002080 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002081 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002082 if (AllowCategories) {
2083 // Look through categories.
2084 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2085 Category; Category = Category->getNextClassCategory())
2086 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2087 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002088
2089 // Look through protocols.
2090 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2091 E = IFace->protocol_end();
2092 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002093 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002094
2095 // Look in the superclass.
2096 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002097 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2098 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002099 } else if (const ObjCCategoryDecl *Category
2100 = dyn_cast<ObjCCategoryDecl>(Container)) {
2101 // Look through protocols.
2102 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2103 PEnd = Category->protocol_end();
2104 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002105 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002106 }
2107}
2108
Douglas Gregor81b747b2009-09-17 21:32:03 +00002109void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2110 SourceLocation OpLoc,
2111 bool IsArrow) {
2112 if (!BaseE || !CodeCompleter)
2113 return;
2114
Douglas Gregor86d9a522009-09-21 16:56:56 +00002115 typedef CodeCompleteConsumer::Result Result;
2116
Douglas Gregor81b747b2009-09-17 21:32:03 +00002117 Expr *Base = static_cast<Expr *>(BaseE);
2118 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002119
2120 if (IsArrow) {
2121 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2122 BaseType = Ptr->getPointeeType();
2123 else if (BaseType->isObjCObjectPointerType())
2124 /*Do nothing*/ ;
2125 else
2126 return;
2127 }
2128
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002129 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002130 Results.EnterNewScope();
2131 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2132 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002133 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002134 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2135 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002136
Douglas Gregor95ac6552009-11-18 01:29:26 +00002137 if (getLangOptions().CPlusPlus) {
2138 if (!Results.empty()) {
2139 // The "template" keyword can follow "->" or "." in the grammar.
2140 // However, we only want to suggest the template keyword if something
2141 // is dependent.
2142 bool IsDependent = BaseType->isDependentType();
2143 if (!IsDependent) {
2144 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2145 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2146 IsDependent = Ctx->isDependentContext();
2147 break;
2148 }
2149 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002150
Douglas Gregor95ac6552009-11-18 01:29:26 +00002151 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002152 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002153 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002154 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002155 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2156 // Objective-C property reference.
2157
2158 // Add property results based on our interface.
2159 const ObjCObjectPointerType *ObjCPtr
2160 = BaseType->getAsObjCInterfacePointerType();
2161 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002162 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002163
2164 // Add properties from the protocols in a qualified interface.
2165 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2166 E = ObjCPtr->qual_end();
2167 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002168 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002169 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
John McCallc12c5bb2010-05-15 11:32:37 +00002170 (!IsArrow && BaseType->isObjCObjectType())) {
Douglas Gregor95ac6552009-11-18 01:29:26 +00002171 // Objective-C instance variable access.
2172 ObjCInterfaceDecl *Class = 0;
2173 if (const ObjCObjectPointerType *ObjCPtr
2174 = BaseType->getAs<ObjCObjectPointerType>())
2175 Class = ObjCPtr->getInterfaceDecl();
2176 else
John McCallc12c5bb2010-05-15 11:32:37 +00002177 Class = BaseType->getAs<ObjCObjectType>()->getInterface();
Douglas Gregor95ac6552009-11-18 01:29:26 +00002178
2179 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002180 if (Class) {
2181 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2182 Results.setFilter(&ResultBuilder::IsObjCIvar);
2183 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002184 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002185 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002186
2187 // FIXME: How do we cope with isa?
2188
2189 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002190
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002191 // Hand off the results found for code completion.
2192 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002193}
2194
Douglas Gregor374929f2009-09-18 15:37:17 +00002195void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2196 if (!CodeCompleter)
2197 return;
2198
Douglas Gregor86d9a522009-09-21 16:56:56 +00002199 typedef CodeCompleteConsumer::Result Result;
2200 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00002201 switch ((DeclSpec::TST)TagSpec) {
2202 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002203 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00002204 break;
2205
2206 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002207 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00002208 break;
2209
2210 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002211 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002212 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00002213 break;
2214
2215 default:
2216 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2217 return;
2218 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002219
John McCall0d6b1642010-04-23 18:46:30 +00002220 ResultBuilder Results(*this);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002221 CodeCompletionDeclConsumer Consumer(Results, CurContext);
John McCall0d6b1642010-04-23 18:46:30 +00002222
2223 // First pass: look for tags.
2224 Results.setFilter(Filter);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002225 LookupVisibleDecls(S, LookupTagName, Consumer);
John McCall0d6b1642010-04-23 18:46:30 +00002226
2227 // Second pass: look for nested name specifiers.
2228 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
2229 LookupVisibleDecls(S, LookupNestedNameSpecifierName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002230
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002231 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002232}
2233
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002234void Sema::CodeCompleteCase(Scope *S) {
2235 if (getSwitchStack().empty() || !CodeCompleter)
2236 return;
2237
2238 SwitchStmt *Switch = getSwitchStack().back();
2239 if (!Switch->getCond()->getType()->isEnumeralType())
2240 return;
2241
2242 // Code-complete the cases of a switch statement over an enumeration type
2243 // by providing the list of
2244 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2245
2246 // Determine which enumerators we have already seen in the switch statement.
2247 // FIXME: Ideally, we would also be able to look *past* the code-completion
2248 // token, in case we are code-completing in the middle of the switch and not
2249 // at the end. However, we aren't able to do so at the moment.
2250 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002251 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002252 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2253 SC = SC->getNextSwitchCase()) {
2254 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2255 if (!Case)
2256 continue;
2257
2258 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2259 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2260 if (EnumConstantDecl *Enumerator
2261 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2262 // We look into the AST of the case statement to determine which
2263 // enumerator was named. Alternatively, we could compute the value of
2264 // the integral constant expression, then compare it against the
2265 // values of each enumerator. However, value-based approach would not
2266 // work as well with C++ templates where enumerators declared within a
2267 // template are type- and value-dependent.
2268 EnumeratorsSeen.insert(Enumerator);
2269
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002270 // If this is a qualified-id, keep track of the nested-name-specifier
2271 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002272 //
2273 // switch (TagD.getKind()) {
2274 // case TagDecl::TK_enum:
2275 // break;
2276 // case XXX
2277 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002278 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002279 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2280 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002281 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002282 }
2283 }
2284
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002285 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2286 // If there are no prior enumerators in C++, check whether we have to
2287 // qualify the names of the enumerators that we suggest, because they
2288 // may not be visible in this scope.
2289 Qualifier = getRequiredQualification(Context, CurContext,
2290 Enum->getDeclContext());
2291
2292 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2293 }
2294
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002295 // Add any enumerators that have not yet been mentioned.
2296 ResultBuilder Results(*this);
2297 Results.EnterNewScope();
2298 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2299 EEnd = Enum->enumerator_end();
2300 E != EEnd; ++E) {
2301 if (EnumeratorsSeen.count(*E))
2302 continue;
2303
Douglas Gregor608300b2010-01-14 16:14:35 +00002304 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2305 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002306 }
2307 Results.ExitScope();
Douglas Gregor2f880e42010-04-06 20:02:15 +00002308
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002309 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002310 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002311 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002312}
2313
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002314namespace {
2315 struct IsBetterOverloadCandidate {
2316 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002317 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002318
2319 public:
John McCall5769d612010-02-08 23:07:23 +00002320 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2321 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002322
2323 bool
2324 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5769d612010-02-08 23:07:23 +00002325 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002326 }
2327 };
2328}
2329
2330void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2331 ExprTy **ArgsIn, unsigned NumArgs) {
2332 if (!CodeCompleter)
2333 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002334
2335 // When we're code-completing for a call, we fall back to ordinary
2336 // name code-completion whenever we can't produce specific
2337 // results. We may want to revisit this strategy in the future,
2338 // e.g., by merging the two kinds of results.
2339
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002340 Expr *Fn = (Expr *)FnIn;
2341 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002342
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002343 // Ignore type-dependent call expressions entirely.
2344 if (Fn->isTypeDependent() ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002345 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00002346 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002347 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002348 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002349
John McCall3b4294e2009-12-16 12:17:52 +00002350 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002351 SourceLocation Loc = Fn->getExprLoc();
2352 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002353
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002354 // FIXME: What if we're calling something that isn't a function declaration?
2355 // FIXME: What if we're calling a pseudo-destructor?
2356 // FIXME: What if we're calling a member function?
2357
Douglas Gregorc0265402010-01-21 15:46:19 +00002358 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2359 llvm::SmallVector<ResultCandidate, 8> Results;
2360
John McCall3b4294e2009-12-16 12:17:52 +00002361 Expr *NakedFn = Fn->IgnoreParenCasts();
2362 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2363 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2364 /*PartialOverloading=*/ true);
2365 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2366 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002367 if (FDecl) {
2368 if (!FDecl->getType()->getAs<FunctionProtoType>())
2369 Results.push_back(ResultCandidate(FDecl));
2370 else
John McCall86820f52010-01-26 01:37:31 +00002371 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002372 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2373 Args, NumArgs, CandidateSet,
Douglas Gregorc27d6c52010-04-16 17:41:49 +00002374 false, /*PartialOverloading*/true);
Douglas Gregorc0265402010-01-21 15:46:19 +00002375 }
John McCall3b4294e2009-12-16 12:17:52 +00002376 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002377
Douglas Gregorc0265402010-01-21 15:46:19 +00002378 if (!CandidateSet.empty()) {
2379 // Sort the overload candidate set by placing the best overloads first.
2380 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002381 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002382
Douglas Gregorc0265402010-01-21 15:46:19 +00002383 // Add the remaining viable overload candidates as code-completion reslults.
2384 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2385 CandEnd = CandidateSet.end();
2386 Cand != CandEnd; ++Cand) {
2387 if (Cand->Viable)
2388 Results.push_back(ResultCandidate(Cand->Function));
2389 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002390 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002391
Douglas Gregor2e4c7a52010-04-06 20:19:47 +00002392 CodeCompleteOrdinaryName(S, CCC_Expression);
2393 if (!Results.empty())
Douglas Gregoref96eac2009-12-11 19:06:04 +00002394 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2395 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002396}
2397
Jeffrey Yasskin9ab14542010-04-08 16:38:48 +00002398void Sema::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
Douglas Gregor81b747b2009-09-17 21:32:03 +00002399 bool EnteringContext) {
2400 if (!SS.getScopeRep() || !CodeCompleter)
2401 return;
2402
Douglas Gregor86d9a522009-09-21 16:56:56 +00002403 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2404 if (!Ctx)
2405 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002406
2407 // Try to instantiate any non-dependent declaration contexts before
2408 // we look in them.
John McCall77bb1aa2010-05-01 00:40:08 +00002409 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS, Ctx))
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002410 return;
2411
Douglas Gregor86d9a522009-09-21 16:56:56 +00002412 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002413 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2414 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002415
2416 // The "template" keyword can follow "::" in the grammar, but only
2417 // put it into the grammar if the nested-name-specifier is dependent.
2418 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2419 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00002420 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002421
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002422 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002423}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002424
2425void Sema::CodeCompleteUsing(Scope *S) {
2426 if (!CodeCompleter)
2427 return;
2428
Douglas Gregor86d9a522009-09-21 16:56:56 +00002429 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002430 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002431
2432 // If we aren't in class scope, we could see the "namespace" keyword.
2433 if (!S->isClassScope())
Douglas Gregora4477812010-01-14 16:01:26 +00002434 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002435
2436 // After "using", we can see anything that would start a
2437 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002438 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2439 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002440 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002441
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002442 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002443}
2444
2445void Sema::CodeCompleteUsingDirective(Scope *S) {
2446 if (!CodeCompleter)
2447 return;
2448
Douglas Gregor86d9a522009-09-21 16:56:56 +00002449 // After "using namespace", we expect to see a namespace name or namespace
2450 // alias.
2451 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002452 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002453 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2454 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002455 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002456 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002457}
2458
2459void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2460 if (!CodeCompleter)
2461 return;
2462
Douglas Gregor86d9a522009-09-21 16:56:56 +00002463 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2464 DeclContext *Ctx = (DeclContext *)S->getEntity();
2465 if (!S->getParent())
2466 Ctx = Context.getTranslationUnitDecl();
2467
2468 if (Ctx && Ctx->isFileContext()) {
2469 // We only want to see those namespaces that have already been defined
2470 // within this scope, because its likely that the user is creating an
2471 // extended namespace declaration. Keep track of the most recent
2472 // definition of each namespace.
2473 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2474 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2475 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2476 NS != NSEnd; ++NS)
2477 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2478
2479 // Add the most recent definition (or extended definition) of each
2480 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002481 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002482 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2483 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2484 NS != NSEnd; ++NS)
Douglas Gregor608300b2010-01-14 16:14:35 +00002485 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2486 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002487 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002488 }
2489
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002490 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002491}
2492
2493void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2494 if (!CodeCompleter)
2495 return;
2496
Douglas Gregor86d9a522009-09-21 16:56:56 +00002497 // After "namespace", we expect to see a namespace or alias.
2498 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002499 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2500 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002501 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002502}
2503
Douglas Gregored8d3222009-09-18 20:05:18 +00002504void Sema::CodeCompleteOperatorName(Scope *S) {
2505 if (!CodeCompleter)
2506 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002507
2508 typedef CodeCompleteConsumer::Result Result;
2509 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002510 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00002511
Douglas Gregor86d9a522009-09-21 16:56:56 +00002512 // Add the names of overloadable operators.
2513#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2514 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00002515 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002516#include "clang/Basic/OperatorKinds.def"
2517
2518 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00002519 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002520 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2521 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002522
2523 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00002524 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002525 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002526
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002527 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00002528}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002529
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002530// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2531// true or false.
2532#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00002533static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002534 ResultBuilder &Results,
2535 bool NeedAt) {
Douglas Gregord8e8a582010-05-25 21:41:55 +00002536 if (!Results.includeCodePatterns())
2537 return;
2538
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002539 typedef CodeCompleteConsumer::Result Result;
2540 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00002541 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002542
2543 CodeCompletionString *Pattern = 0;
2544 if (LangOpts.ObjC2) {
2545 // @dynamic
2546 Pattern = new CodeCompletionString;
2547 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2548 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2549 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002550 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002551
2552 // @synthesize
2553 Pattern = new CodeCompletionString;
2554 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2555 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2556 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002557 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002558 }
2559}
2560
Douglas Gregorbca403c2010-01-13 23:51:12 +00002561static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002562 ResultBuilder &Results,
2563 bool NeedAt) {
Douglas Gregord8e8a582010-05-25 21:41:55 +00002564 if (!Results.includeCodePatterns())
2565 return;
2566
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002567 typedef CodeCompleteConsumer::Result Result;
2568
2569 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00002570 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002571
2572 if (LangOpts.ObjC2) {
2573 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00002574 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002575
2576 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00002577 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002578
2579 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00002580 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002581 }
2582}
2583
Douglas Gregorbca403c2010-01-13 23:51:12 +00002584static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregord8e8a582010-05-25 21:41:55 +00002585 if (!Results.includeCodePatterns())
2586 return;
2587
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002588 typedef CodeCompleteConsumer::Result Result;
2589 CodeCompletionString *Pattern = 0;
2590
2591 // @class name ;
2592 Pattern = new CodeCompletionString;
2593 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2594 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2595 Pattern->AddPlaceholderChunk("identifier");
Douglas Gregora4477812010-01-14 16:01:26 +00002596 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002597
2598 // @interface name
2599 // FIXME: Could introduce the whole pattern, including superclasses and
2600 // such.
2601 Pattern = new CodeCompletionString;
2602 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2603 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2604 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002605 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002606
2607 // @protocol name
2608 Pattern = new CodeCompletionString;
2609 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2610 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2611 Pattern->AddPlaceholderChunk("protocol");
Douglas Gregora4477812010-01-14 16:01:26 +00002612 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002613
2614 // @implementation name
2615 Pattern = new CodeCompletionString;
2616 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2617 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2618 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002619 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002620
2621 // @compatibility_alias name
2622 Pattern = new CodeCompletionString;
2623 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2624 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2625 Pattern->AddPlaceholderChunk("alias");
2626 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2627 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002628 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002629}
2630
Douglas Gregorc464ae82009-12-07 09:27:33 +00002631void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2632 bool InInterface) {
2633 typedef CodeCompleteConsumer::Result Result;
2634 ResultBuilder Results(*this);
2635 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002636 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002637 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002638 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002639 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002640 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00002641 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00002642 Results.ExitScope();
2643 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2644}
2645
Douglas Gregorbca403c2010-01-13 23:51:12 +00002646static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregord8e8a582010-05-25 21:41:55 +00002647 if (!Results.includeCodePatterns())
2648 return;
2649
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002650 typedef CodeCompleteConsumer::Result Result;
2651 CodeCompletionString *Pattern = 0;
2652
2653 // @encode ( type-name )
2654 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002655 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002656 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2657 Pattern->AddPlaceholderChunk("type-name");
2658 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002659 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002660
2661 // @protocol ( protocol-name )
2662 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002663 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002664 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2665 Pattern->AddPlaceholderChunk("protocol-name");
2666 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002667 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002668
2669 // @selector ( selector )
2670 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002671 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002672 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2673 Pattern->AddPlaceholderChunk("selector");
2674 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002675 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002676}
2677
Douglas Gregorbca403c2010-01-13 23:51:12 +00002678static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregord8e8a582010-05-25 21:41:55 +00002679 if (!Results.includeCodePatterns())
2680 return;
2681
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002682 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002683 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002684
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002685 // @try { statements } @catch ( declaration ) { statements } @finally
2686 // { statements }
2687 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002688 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002689 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2690 Pattern->AddPlaceholderChunk("statements");
2691 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2692 Pattern->AddTextChunk("@catch");
2693 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2694 Pattern->AddPlaceholderChunk("parameter");
2695 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2696 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2697 Pattern->AddPlaceholderChunk("statements");
2698 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2699 Pattern->AddTextChunk("@finally");
2700 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2701 Pattern->AddPlaceholderChunk("statements");
2702 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00002703 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002704
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002705 // @throw
2706 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002707 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00002708 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002709 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00002710 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002711
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002712 // @synchronized ( expression ) { statements }
2713 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002714 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
Douglas Gregor834389b2010-01-12 06:38:28 +00002715 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002716 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2717 Pattern->AddPlaceholderChunk("expression");
2718 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2719 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2720 Pattern->AddPlaceholderChunk("statements");
2721 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00002722 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002723}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002724
Douglas Gregorbca403c2010-01-13 23:51:12 +00002725static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002726 ResultBuilder &Results,
2727 bool NeedAt) {
Douglas Gregord8e8a582010-05-25 21:41:55 +00002728 if (!Results.includeCodePatterns())
2729 return;
2730
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002731 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +00002732 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2733 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2734 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002735 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00002736 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002737}
2738
2739void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2740 ResultBuilder Results(*this);
2741 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002742 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002743 Results.ExitScope();
2744 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2745}
2746
2747void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002748 ResultBuilder Results(*this);
2749 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002750 AddObjCStatementResults(Results, false);
2751 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002752 Results.ExitScope();
2753 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2754}
2755
2756void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2757 ResultBuilder Results(*this);
2758 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002759 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002760 Results.ExitScope();
2761 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2762}
2763
Douglas Gregor988358f2009-11-19 00:14:45 +00002764/// \brief Determine whether the addition of the given flag to an Objective-C
2765/// property's attributes will cause a conflict.
2766static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2767 // Check if we've already added this flag.
2768 if (Attributes & NewFlag)
2769 return true;
2770
2771 Attributes |= NewFlag;
2772
2773 // Check for collisions with "readonly".
2774 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2775 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2776 ObjCDeclSpec::DQ_PR_assign |
2777 ObjCDeclSpec::DQ_PR_copy |
2778 ObjCDeclSpec::DQ_PR_retain)))
2779 return true;
2780
2781 // Check for more than one of { assign, copy, retain }.
2782 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2783 ObjCDeclSpec::DQ_PR_copy |
2784 ObjCDeclSpec::DQ_PR_retain);
2785 if (AssignCopyRetMask &&
2786 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2787 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2788 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2789 return true;
2790
2791 return false;
2792}
2793
Douglas Gregora93b1082009-11-18 23:08:07 +00002794void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00002795 if (!CodeCompleter)
2796 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00002797
Steve Naroffece8e712009-10-08 21:55:05 +00002798 unsigned Attributes = ODS.getPropertyAttributes();
2799
2800 typedef CodeCompleteConsumer::Result Result;
2801 ResultBuilder Results(*this);
2802 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00002803 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregora4477812010-01-14 16:01:26 +00002804 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002805 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregora4477812010-01-14 16:01:26 +00002806 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002807 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregora4477812010-01-14 16:01:26 +00002808 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002809 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregora4477812010-01-14 16:01:26 +00002810 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002811 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregora4477812010-01-14 16:01:26 +00002812 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002813 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregora4477812010-01-14 16:01:26 +00002814 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002815 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002816 CodeCompletionString *Setter = new CodeCompletionString;
2817 Setter->AddTypedTextChunk("setter");
2818 Setter->AddTextChunk(" = ");
2819 Setter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00002820 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00002821 }
Douglas Gregor988358f2009-11-19 00:14:45 +00002822 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002823 CodeCompletionString *Getter = new CodeCompletionString;
2824 Getter->AddTypedTextChunk("getter");
2825 Getter->AddTextChunk(" = ");
2826 Getter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00002827 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00002828 }
Steve Naroffece8e712009-10-08 21:55:05 +00002829 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002830 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00002831}
Steve Naroffc4df6d22009-11-07 02:08:14 +00002832
Douglas Gregor4ad96852009-11-19 07:41:15 +00002833/// \brief Descripts the kind of Objective-C method that we want to find
2834/// via code completion.
2835enum ObjCMethodKind {
2836 MK_Any, //< Any kind of method, provided it means other specified criteria.
2837 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2838 MK_OneArgSelector //< One-argument selector.
2839};
2840
2841static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2842 ObjCMethodKind WantKind,
2843 IdentifierInfo **SelIdents,
2844 unsigned NumSelIdents) {
2845 Selector Sel = Method->getSelector();
2846 if (NumSelIdents > Sel.getNumArgs())
2847 return false;
2848
2849 switch (WantKind) {
2850 case MK_Any: break;
2851 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2852 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2853 }
2854
2855 for (unsigned I = 0; I != NumSelIdents; ++I)
2856 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2857 return false;
2858
2859 return true;
2860}
2861
Douglas Gregor36ecb042009-11-17 23:22:23 +00002862/// \brief Add all of the Objective-C methods in the given Objective-C
2863/// container to the set of results.
2864///
2865/// The container will be a class, protocol, category, or implementation of
2866/// any of the above. This mether will recurse to include methods from
2867/// the superclasses of classes along with their categories, protocols, and
2868/// implementations.
2869///
2870/// \param Container the container in which we'll look to find methods.
2871///
2872/// \param WantInstance whether to add instance methods (only); if false, this
2873/// routine will add factory methods (only).
2874///
2875/// \param CurContext the context in which we're performing the lookup that
2876/// finds methods.
2877///
2878/// \param Results the structure into which we'll add results.
2879static void AddObjCMethods(ObjCContainerDecl *Container,
2880 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00002881 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00002882 IdentifierInfo **SelIdents,
2883 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00002884 DeclContext *CurContext,
2885 ResultBuilder &Results) {
2886 typedef CodeCompleteConsumer::Result Result;
2887 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2888 MEnd = Container->meth_end();
2889 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002890 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2891 // Check whether the selector identifiers we've been given are a
2892 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002893 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00002894 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002895
Douglas Gregord3c68542009-11-19 01:08:35 +00002896 Result R = Result(*M, 0);
2897 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002898 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00002899 Results.MaybeAddResult(R, CurContext);
2900 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00002901 }
2902
2903 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2904 if (!IFace)
2905 return;
2906
2907 // Add methods in protocols.
2908 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2909 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2910 E = Protocols.end();
2911 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002912 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00002913 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002914
2915 // Add methods in categories.
2916 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2917 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00002918 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2919 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002920
2921 // Add a categories protocol methods.
2922 const ObjCList<ObjCProtocolDecl> &Protocols
2923 = CatDecl->getReferencedProtocols();
2924 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2925 E = Protocols.end();
2926 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002927 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2928 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002929
2930 // Add methods in category implementations.
2931 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002932 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2933 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002934 }
2935
2936 // Add methods in superclass.
2937 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002938 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2939 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002940
2941 // Add methods in our implementation, if any.
2942 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002943 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2944 NumSelIdents, CurContext, Results);
2945}
2946
2947
2948void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2949 DeclPtrTy *Methods,
2950 unsigned NumMethods) {
2951 typedef CodeCompleteConsumer::Result Result;
2952
2953 // Try to find the interface where getters might live.
2954 ObjCInterfaceDecl *Class
2955 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2956 if (!Class) {
2957 if (ObjCCategoryDecl *Category
2958 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2959 Class = Category->getClassInterface();
2960
2961 if (!Class)
2962 return;
2963 }
2964
2965 // Find all of the potential getters.
2966 ResultBuilder Results(*this);
2967 Results.EnterNewScope();
2968
2969 // FIXME: We need to do this because Objective-C methods don't get
2970 // pushed into DeclContexts early enough. Argh!
2971 for (unsigned I = 0; I != NumMethods; ++I) {
2972 if (ObjCMethodDecl *Method
2973 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2974 if (Method->isInstanceMethod() &&
2975 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2976 Result R = Result(Method, 0);
2977 R.AllParametersAreInformative = true;
2978 Results.MaybeAddResult(R, CurContext);
2979 }
2980 }
2981
2982 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2983 Results.ExitScope();
2984 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2985}
2986
2987void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2988 DeclPtrTy *Methods,
2989 unsigned NumMethods) {
2990 typedef CodeCompleteConsumer::Result Result;
2991
2992 // Try to find the interface where setters might live.
2993 ObjCInterfaceDecl *Class
2994 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2995 if (!Class) {
2996 if (ObjCCategoryDecl *Category
2997 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2998 Class = Category->getClassInterface();
2999
3000 if (!Class)
3001 return;
3002 }
3003
3004 // Find all of the potential getters.
3005 ResultBuilder Results(*this);
3006 Results.EnterNewScope();
3007
3008 // FIXME: We need to do this because Objective-C methods don't get
3009 // pushed into DeclContexts early enough. Argh!
3010 for (unsigned I = 0; I != NumMethods; ++I) {
3011 if (ObjCMethodDecl *Method
3012 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
3013 if (Method->isInstanceMethod() &&
3014 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
3015 Result R = Result(Method, 0);
3016 R.AllParametersAreInformative = true;
3017 Results.MaybeAddResult(R, CurContext);
3018 }
3019 }
3020
3021 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
3022
3023 Results.ExitScope();
3024 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00003025}
3026
Douglas Gregor22f56992010-04-06 19:22:33 +00003027/// \brief When we have an expression with type "id", we may assume
3028/// that it has some more-specific class type based on knowledge of
3029/// common uses of Objective-C. This routine returns that class type,
3030/// or NULL if no better result could be determined.
3031static ObjCInterfaceDecl *GetAssumedMessageSendExprType(Expr *E) {
3032 ObjCMessageExpr *Msg = dyn_cast<ObjCMessageExpr>(E);
3033 if (!Msg)
3034 return 0;
3035
3036 Selector Sel = Msg->getSelector();
3037 if (Sel.isNull())
3038 return 0;
3039
3040 IdentifierInfo *Id = Sel.getIdentifierInfoForSlot(0);
3041 if (!Id)
3042 return 0;
3043
3044 ObjCMethodDecl *Method = Msg->getMethodDecl();
3045 if (!Method)
3046 return 0;
3047
3048 // Determine the class that we're sending the message to.
Douglas Gregor04badcf2010-04-21 00:45:42 +00003049 ObjCInterfaceDecl *IFace = 0;
3050 switch (Msg->getReceiverKind()) {
3051 case ObjCMessageExpr::Class:
John McCallc12c5bb2010-05-15 11:32:37 +00003052 if (const ObjCObjectType *ObjType
3053 = Msg->getClassReceiver()->getAs<ObjCObjectType>())
3054 IFace = ObjType->getInterface();
Douglas Gregor04badcf2010-04-21 00:45:42 +00003055 break;
3056
3057 case ObjCMessageExpr::Instance: {
3058 QualType T = Msg->getInstanceReceiver()->getType();
3059 if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
3060 IFace = Ptr->getInterfaceDecl();
3061 break;
3062 }
3063
3064 case ObjCMessageExpr::SuperInstance:
3065 case ObjCMessageExpr::SuperClass:
3066 break;
Douglas Gregor22f56992010-04-06 19:22:33 +00003067 }
3068
3069 if (!IFace)
3070 return 0;
3071
3072 ObjCInterfaceDecl *Super = IFace->getSuperClass();
3073 if (Method->isInstanceMethod())
3074 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3075 .Case("retain", IFace)
3076 .Case("autorelease", IFace)
3077 .Case("copy", IFace)
3078 .Case("copyWithZone", IFace)
3079 .Case("mutableCopy", IFace)
3080 .Case("mutableCopyWithZone", IFace)
3081 .Case("awakeFromCoder", IFace)
3082 .Case("replacementObjectFromCoder", IFace)
3083 .Case("class", IFace)
3084 .Case("classForCoder", IFace)
3085 .Case("superclass", Super)
3086 .Default(0);
3087
3088 return llvm::StringSwitch<ObjCInterfaceDecl *>(Id->getName())
3089 .Case("new", IFace)
3090 .Case("alloc", IFace)
3091 .Case("allocWithZone", IFace)
3092 .Case("class", IFace)
3093 .Case("superclass", Super)
3094 .Default(0);
3095}
3096
Douglas Gregor8e254cf2010-05-27 23:06:34 +00003097void Sema::CodeCompleteObjCMessageReceiver(Scope *S) {
3098 typedef CodeCompleteConsumer::Result Result;
3099 ResultBuilder Results(*this);
3100
3101 // Find anything that looks like it could be a message receiver.
3102 Results.setFilter(&ResultBuilder::IsObjCMessageReceiver);
3103 CodeCompletionDeclConsumer Consumer(Results, CurContext);
3104 Results.EnterNewScope();
3105 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
3106
3107 // If we are in an Objective-C method inside a class that has a superclass,
3108 // add "super" as an option.
3109 if (ObjCMethodDecl *Method = getCurMethodDecl())
3110 if (ObjCInterfaceDecl *Iface = Method->getClassInterface())
3111 if (Iface->getSuperClass())
3112 Results.AddResult(Result("super"));
3113
3114 Results.ExitScope();
3115
3116 if (CodeCompleter->includeMacros())
3117 AddMacroResults(PP, Results);
3118 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3119
3120}
3121
Douglas Gregor2725ca82010-04-21 19:57:20 +00003122void Sema::CodeCompleteObjCSuperMessage(Scope *S, SourceLocation SuperLoc,
3123 IdentifierInfo **SelIdents,
3124 unsigned NumSelIdents) {
3125 ObjCInterfaceDecl *CDecl = 0;
3126 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3127 // Figure out which interface we're in.
3128 CDecl = CurMethod->getClassInterface();
3129 if (!CDecl)
3130 return;
3131
3132 // Find the superclass of this class.
3133 CDecl = CDecl->getSuperClass();
3134 if (!CDecl)
3135 return;
3136
3137 if (CurMethod->isInstanceMethod()) {
3138 // We are inside an instance method, which means that the message
3139 // send [super ...] is actually calling an instance method on the
3140 // current object. Build the super expression and handle this like
3141 // an instance method.
3142 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
3143 SuperTy = Context.getObjCObjectPointerType(SuperTy);
3144 OwningExprResult Super
3145 = Owned(new (Context) ObjCSuperExpr(SuperLoc, SuperTy));
3146 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3147 SelIdents, NumSelIdents);
3148 }
3149
3150 // Fall through to send to the superclass in CDecl.
3151 } else {
3152 // "super" may be the name of a type or variable. Figure out which
3153 // it is.
3154 IdentifierInfo *Super = &Context.Idents.get("super");
3155 NamedDecl *ND = LookupSingleName(S, Super, SuperLoc,
3156 LookupOrdinaryName);
3157 if ((CDecl = dyn_cast_or_null<ObjCInterfaceDecl>(ND))) {
3158 // "super" names an interface. Use it.
3159 } else if (TypeDecl *TD = dyn_cast_or_null<TypeDecl>(ND)) {
John McCallc12c5bb2010-05-15 11:32:37 +00003160 if (const ObjCObjectType *Iface
3161 = Context.getTypeDeclType(TD)->getAs<ObjCObjectType>())
3162 CDecl = Iface->getInterface();
Douglas Gregor2725ca82010-04-21 19:57:20 +00003163 } else if (ND && isa<UnresolvedUsingTypenameDecl>(ND)) {
3164 // "super" names an unresolved type; we can't be more specific.
3165 } else {
3166 // Assume that "super" names some kind of value and parse that way.
3167 CXXScopeSpec SS;
3168 UnqualifiedId id;
3169 id.setIdentifier(Super, SuperLoc);
3170 OwningExprResult SuperExpr = ActOnIdExpression(S, SS, id, false, false);
3171 return CodeCompleteObjCInstanceMessage(S, (Expr *)SuperExpr.get(),
3172 SelIdents, NumSelIdents);
3173 }
3174
3175 // Fall through
3176 }
3177
3178 TypeTy *Receiver = 0;
3179 if (CDecl)
3180 Receiver = Context.getObjCInterfaceType(CDecl).getAsOpaquePtr();
3181 return CodeCompleteObjCClassMessage(S, Receiver, SelIdents,
3182 NumSelIdents);
3183}
3184
3185void Sema::CodeCompleteObjCClassMessage(Scope *S, TypeTy *Receiver,
Douglas Gregord3c68542009-11-19 01:08:35 +00003186 IdentifierInfo **SelIdents,
3187 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003188 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00003189 ObjCInterfaceDecl *CDecl = 0;
3190
Douglas Gregor24a069f2009-11-17 17:59:40 +00003191 // If the given name refers to an interface type, retrieve the
3192 // corresponding declaration.
Douglas Gregor2725ca82010-04-21 19:57:20 +00003193 if (Receiver) {
3194 QualType T = GetTypeFromParser(Receiver, 0);
3195 if (!T.isNull())
John McCallc12c5bb2010-05-15 11:32:37 +00003196 if (const ObjCObjectType *Interface = T->getAs<ObjCObjectType>())
3197 CDecl = Interface->getInterface();
Douglas Gregor24a069f2009-11-17 17:59:40 +00003198 }
3199
Douglas Gregor36ecb042009-11-17 23:22:23 +00003200 // Add all of the factory methods in this Objective-C class, its protocols,
3201 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003202 ResultBuilder Results(*this);
3203 Results.EnterNewScope();
Douglas Gregor13438f92010-04-06 16:40:00 +00003204
3205 if (CDecl)
3206 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3207 Results);
Douglas Gregor2725ca82010-04-21 19:57:20 +00003208 else {
Douglas Gregor13438f92010-04-06 16:40:00 +00003209 // We're messaging "id" as a type; provide all class/factory methods.
3210
Douglas Gregor719770d2010-04-06 17:30:22 +00003211 // If we have an external source, load the entire class method
3212 // pool from the PCH file.
3213 if (ExternalSource) {
3214 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3215 ++I) {
3216 Selector Sel = ExternalSource->GetSelector(I);
3217 if (Sel.isNull() || FactoryMethodPool.count(Sel) ||
3218 InstanceMethodPool.count(Sel))
3219 continue;
3220
3221 ReadMethodPool(Sel, /*isInstance=*/false);
3222 }
3223 }
3224
Douglas Gregor13438f92010-04-06 16:40:00 +00003225 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3226 M = FactoryMethodPool.begin(),
3227 MEnd = FactoryMethodPool.end();
3228 M != MEnd;
3229 ++M) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003230 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003231 MethList = MethList->Next) {
3232 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3233 NumSelIdents))
3234 continue;
3235
3236 Result R(MethList->Method, 0);
3237 R.StartParameter = NumSelIdents;
3238 R.AllParametersAreInformative = false;
3239 Results.MaybeAddResult(R, CurContext);
3240 }
3241 }
3242 }
3243
Steve Naroffc4df6d22009-11-07 02:08:14 +00003244 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003245 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003246}
3247
Douglas Gregord3c68542009-11-19 01:08:35 +00003248void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3249 IdentifierInfo **SelIdents,
3250 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003251 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003252
3253 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003254
Douglas Gregor36ecb042009-11-17 23:22:23 +00003255 // If necessary, apply function/array conversion to the receiver.
3256 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00003257 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00003258 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003259
Douglas Gregor36ecb042009-11-17 23:22:23 +00003260 // Build the set of methods we can see.
3261 ResultBuilder Results(*this);
3262 Results.EnterNewScope();
Douglas Gregor22f56992010-04-06 19:22:33 +00003263
3264 // If we're messaging an expression with type "id" or "Class", check
3265 // whether we know something special about the receiver that allows
3266 // us to assume a more-specific receiver type.
3267 if (ReceiverType->isObjCIdType() || ReceiverType->isObjCClassType())
3268 if (ObjCInterfaceDecl *IFace = GetAssumedMessageSendExprType(RecExpr))
3269 ReceiverType = Context.getObjCObjectPointerType(
3270 Context.getObjCInterfaceType(IFace));
Douglas Gregor36ecb042009-11-17 23:22:23 +00003271
Douglas Gregorf74a4192009-11-18 00:06:18 +00003272 // Handle messages to Class. This really isn't a message to an instance
3273 // method, so we treat it the same way we would treat a message send to a
3274 // class method.
3275 if (ReceiverType->isObjCClassType() ||
3276 ReceiverType->isObjCQualifiedClassType()) {
3277 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3278 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003279 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3280 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003281 }
3282 }
3283 // Handle messages to a qualified ID ("id<foo>").
3284 else if (const ObjCObjectPointerType *QualID
3285 = ReceiverType->getAsObjCQualifiedIdType()) {
3286 // Search protocols for instance methods.
3287 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3288 E = QualID->qual_end();
3289 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003290 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3291 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003292 }
3293 // Handle messages to a pointer to interface type.
3294 else if (const ObjCObjectPointerType *IFacePtr
3295 = ReceiverType->getAsObjCInterfacePointerType()) {
3296 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003297 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3298 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003299
3300 // Search protocols for instance methods.
3301 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3302 E = IFacePtr->qual_end();
3303 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003304 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3305 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003306 }
Douglas Gregor13438f92010-04-06 16:40:00 +00003307 // Handle messages to "id".
3308 else if (ReceiverType->isObjCIdType()) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003309 // We're messaging "id", so provide all instance methods we know
3310 // about as code-completion results.
3311
3312 // If we have an external source, load the entire class method
3313 // pool from the PCH file.
3314 if (ExternalSource) {
3315 for (uint32_t I = 0, N = ExternalSource->GetNumKnownSelectors(); I != N;
3316 ++I) {
3317 Selector Sel = ExternalSource->GetSelector(I);
3318 if (Sel.isNull() || InstanceMethodPool.count(Sel) ||
3319 FactoryMethodPool.count(Sel))
3320 continue;
3321
3322 ReadMethodPool(Sel, /*isInstance=*/true);
3323 }
3324 }
3325
Douglas Gregor13438f92010-04-06 16:40:00 +00003326 for (llvm::DenseMap<Selector, ObjCMethodList>::iterator
3327 M = InstanceMethodPool.begin(),
3328 MEnd = InstanceMethodPool.end();
3329 M != MEnd;
3330 ++M) {
Douglas Gregor719770d2010-04-06 17:30:22 +00003331 for (ObjCMethodList *MethList = &M->second; MethList && MethList->Method;
Douglas Gregor13438f92010-04-06 16:40:00 +00003332 MethList = MethList->Next) {
3333 if (!isAcceptableObjCMethod(MethList->Method, MK_Any, SelIdents,
3334 NumSelIdents))
3335 continue;
3336
3337 Result R(MethList->Method, 0);
3338 R.StartParameter = NumSelIdents;
3339 R.AllParametersAreInformative = false;
3340 Results.MaybeAddResult(R, CurContext);
3341 }
3342 }
3343 }
3344
Steve Naroffc4df6d22009-11-07 02:08:14 +00003345 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003346 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003347}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003348
3349/// \brief Add all of the protocol declarations that we find in the given
3350/// (translation unit) context.
3351static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003352 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003353 ResultBuilder &Results) {
3354 typedef CodeCompleteConsumer::Result Result;
3355
3356 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3357 DEnd = Ctx->decls_end();
3358 D != DEnd; ++D) {
3359 // Record any protocols we find.
3360 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003361 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003362 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003363
3364 // Record any forward-declared protocols we find.
3365 if (ObjCForwardProtocolDecl *Forward
3366 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3367 for (ObjCForwardProtocolDecl::protocol_iterator
3368 P = Forward->protocol_begin(),
3369 PEnd = Forward->protocol_end();
3370 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003371 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003372 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003373 }
3374 }
3375}
3376
3377void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3378 unsigned NumProtocols) {
3379 ResultBuilder Results(*this);
3380 Results.EnterNewScope();
3381
3382 // Tell the result set to ignore all of the protocols we have
3383 // already seen.
3384 for (unsigned I = 0; I != NumProtocols; ++I)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003385 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first,
3386 Protocols[I].second))
Douglas Gregor55385fe2009-11-18 04:19:12 +00003387 Results.Ignore(Protocol);
3388
3389 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003390 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3391 Results);
3392
3393 Results.ExitScope();
3394 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3395}
3396
3397void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3398 ResultBuilder Results(*this);
3399 Results.EnterNewScope();
3400
3401 // Add all protocols.
3402 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3403 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003404
3405 Results.ExitScope();
3406 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3407}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003408
3409/// \brief Add all of the Objective-C interface declarations that we find in
3410/// the given (translation unit) context.
3411static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3412 bool OnlyForwardDeclarations,
3413 bool OnlyUnimplemented,
3414 ResultBuilder &Results) {
3415 typedef CodeCompleteConsumer::Result Result;
3416
3417 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3418 DEnd = Ctx->decls_end();
3419 D != DEnd; ++D) {
3420 // Record any interfaces we find.
3421 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3422 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3423 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003424 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003425
3426 // Record any forward-declared interfaces we find.
3427 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3428 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3429 C != CEnd; ++C)
3430 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3431 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003432 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3433 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003434 }
3435 }
3436}
3437
3438void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3439 ResultBuilder Results(*this);
3440 Results.EnterNewScope();
3441
3442 // Add all classes.
3443 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3444 false, Results);
3445
3446 Results.ExitScope();
3447 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3448}
3449
Douglas Gregorc83c6872010-04-15 22:33:43 +00003450void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName,
3451 SourceLocation ClassNameLoc) {
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003452 ResultBuilder Results(*this);
3453 Results.EnterNewScope();
3454
3455 // Make sure that we ignore the class we're currently defining.
3456 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003457 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003458 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003459 Results.Ignore(CurClass);
3460
3461 // Add all classes.
3462 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3463 false, Results);
3464
3465 Results.ExitScope();
3466 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3467}
3468
3469void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3470 ResultBuilder Results(*this);
3471 Results.EnterNewScope();
3472
3473 // Add all unimplemented classes.
3474 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3475 true, Results);
3476
3477 Results.ExitScope();
3478 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3479}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003480
3481void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00003482 IdentifierInfo *ClassName,
3483 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003484 typedef CodeCompleteConsumer::Result Result;
3485
3486 ResultBuilder Results(*this);
3487
3488 // Ignore any categories we find that have already been implemented by this
3489 // interface.
3490 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3491 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003492 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003493 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3494 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3495 Category = Category->getNextClassCategory())
3496 CategoryNames.insert(Category->getIdentifier());
3497
3498 // Add all of the categories we know about.
3499 Results.EnterNewScope();
3500 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3501 for (DeclContext::decl_iterator D = TU->decls_begin(),
3502 DEnd = TU->decls_end();
3503 D != DEnd; ++D)
3504 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3505 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003506 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003507 Results.ExitScope();
3508
3509 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3510}
3511
3512void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
Douglas Gregorc83c6872010-04-15 22:33:43 +00003513 IdentifierInfo *ClassName,
3514 SourceLocation ClassNameLoc) {
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003515 typedef CodeCompleteConsumer::Result Result;
3516
3517 // Find the corresponding interface. If we couldn't find the interface, the
3518 // program itself is ill-formed. However, we'll try to be helpful still by
3519 // providing the list of all of the categories we know about.
3520 NamedDecl *CurClass
Douglas Gregorc83c6872010-04-15 22:33:43 +00003521 = LookupSingleName(TUScope, ClassName, ClassNameLoc, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003522 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3523 if (!Class)
Douglas Gregorc83c6872010-04-15 22:33:43 +00003524 return CodeCompleteObjCInterfaceCategory(S, ClassName, ClassNameLoc);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003525
3526 ResultBuilder Results(*this);
3527
3528 // Add all of the categories that have have corresponding interface
3529 // declarations in this class and any of its superclasses, except for
3530 // already-implemented categories in the class itself.
3531 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3532 Results.EnterNewScope();
3533 bool IgnoreImplemented = true;
3534 while (Class) {
3535 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3536 Category = Category->getNextClassCategory())
3537 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3538 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003539 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003540
3541 Class = Class->getSuperClass();
3542 IgnoreImplemented = false;
3543 }
3544 Results.ExitScope();
3545
3546 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3547}
Douglas Gregor322328b2009-11-18 22:32:06 +00003548
Douglas Gregor424b2a52009-11-18 22:56:13 +00003549void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00003550 typedef CodeCompleteConsumer::Result Result;
3551 ResultBuilder Results(*this);
3552
3553 // Figure out where this @synthesize lives.
3554 ObjCContainerDecl *Container
3555 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3556 if (!Container ||
3557 (!isa<ObjCImplementationDecl>(Container) &&
3558 !isa<ObjCCategoryImplDecl>(Container)))
3559 return;
3560
3561 // Ignore any properties that have already been implemented.
3562 for (DeclContext::decl_iterator D = Container->decls_begin(),
3563 DEnd = Container->decls_end();
3564 D != DEnd; ++D)
3565 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3566 Results.Ignore(PropertyImpl->getPropertyDecl());
3567
3568 // Add any properties that we find.
3569 Results.EnterNewScope();
3570 if (ObjCImplementationDecl *ClassImpl
3571 = dyn_cast<ObjCImplementationDecl>(Container))
3572 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3573 Results);
3574 else
3575 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3576 false, CurContext, Results);
3577 Results.ExitScope();
3578
3579 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3580}
3581
3582void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3583 IdentifierInfo *PropertyName,
3584 DeclPtrTy ObjCImpDecl) {
3585 typedef CodeCompleteConsumer::Result Result;
3586 ResultBuilder Results(*this);
3587
3588 // Figure out where this @synthesize lives.
3589 ObjCContainerDecl *Container
3590 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3591 if (!Container ||
3592 (!isa<ObjCImplementationDecl>(Container) &&
3593 !isa<ObjCCategoryImplDecl>(Container)))
3594 return;
3595
3596 // Figure out which interface we're looking into.
3597 ObjCInterfaceDecl *Class = 0;
3598 if (ObjCImplementationDecl *ClassImpl
3599 = dyn_cast<ObjCImplementationDecl>(Container))
3600 Class = ClassImpl->getClassInterface();
3601 else
3602 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3603 ->getClassInterface();
3604
3605 // Add all of the instance variables in this class and its superclasses.
3606 Results.EnterNewScope();
3607 for(; Class; Class = Class->getSuperClass()) {
3608 // FIXME: We could screen the type of each ivar for compatibility with
3609 // the property, but is that being too paternal?
3610 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3611 IVarEnd = Class->ivar_end();
3612 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00003613 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00003614 }
3615 Results.ExitScope();
3616
3617 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3618}
Douglas Gregore8f5a172010-04-07 00:21:17 +00003619
3620typedef llvm::DenseMap<Selector, ObjCMethodDecl *> KnownMethodsMap;
3621
3622/// \brief Find all of the methods that reside in the given container
3623/// (and its superclasses, protocols, etc.) that meet the given
3624/// criteria. Insert those methods into the map of known methods,
3625/// indexed by selector so they can be easily found.
3626static void FindImplementableMethods(ASTContext &Context,
3627 ObjCContainerDecl *Container,
3628 bool WantInstanceMethods,
3629 QualType ReturnType,
3630 bool IsInImplementation,
3631 KnownMethodsMap &KnownMethods) {
3632 if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)) {
3633 // Recurse into protocols.
3634 const ObjCList<ObjCProtocolDecl> &Protocols
3635 = IFace->getReferencedProtocols();
3636 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3637 E = Protocols.end();
3638 I != E; ++I)
3639 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3640 IsInImplementation, KnownMethods);
3641
3642 // If we're not in the implementation of a class, also visit the
3643 // superclass.
3644 if (!IsInImplementation && IFace->getSuperClass())
3645 FindImplementableMethods(Context, IFace->getSuperClass(),
3646 WantInstanceMethods, ReturnType,
3647 IsInImplementation, KnownMethods);
3648
3649 // Add methods from any class extensions (but not from categories;
3650 // those should go into category implementations).
3651 for (ObjCCategoryDecl *Cat = IFace->getCategoryList(); Cat;
3652 Cat = Cat->getNextClassCategory()) {
3653 if (!Cat->IsClassExtension())
3654 continue;
3655
3656 FindImplementableMethods(Context, Cat, WantInstanceMethods, ReturnType,
3657 IsInImplementation, KnownMethods);
3658 }
3659 }
3660
3661 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(Container)) {
3662 // Recurse into protocols.
3663 const ObjCList<ObjCProtocolDecl> &Protocols
3664 = Category->getReferencedProtocols();
3665 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3666 E = Protocols.end();
3667 I != E; ++I)
3668 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3669 IsInImplementation, KnownMethods);
3670 }
3671
3672 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
3673 // Recurse into protocols.
3674 const ObjCList<ObjCProtocolDecl> &Protocols
3675 = Protocol->getReferencedProtocols();
3676 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
3677 E = Protocols.end();
3678 I != E; ++I)
3679 FindImplementableMethods(Context, *I, WantInstanceMethods, ReturnType,
3680 IsInImplementation, KnownMethods);
3681 }
3682
3683 // Add methods in this container. This operation occurs last because
3684 // we want the methods from this container to override any methods
3685 // we've previously seen with the same selector.
3686 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
3687 MEnd = Container->meth_end();
3688 M != MEnd; ++M) {
3689 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
3690 if (!ReturnType.isNull() &&
3691 !Context.hasSameUnqualifiedType(ReturnType, (*M)->getResultType()))
3692 continue;
3693
3694 KnownMethods[(*M)->getSelector()] = *M;
3695 }
3696 }
3697}
3698
3699void Sema::CodeCompleteObjCMethodDecl(Scope *S,
3700 bool IsInstanceMethod,
3701 TypeTy *ReturnTy,
3702 DeclPtrTy IDecl) {
3703 // Determine the return type of the method we're declaring, if
3704 // provided.
3705 QualType ReturnType = GetTypeFromParser(ReturnTy);
3706
3707 // Determine where we should start searching for methods, and where we
3708 ObjCContainerDecl *SearchDecl = 0, *CurrentDecl = 0;
3709 bool IsInImplementation = false;
3710 if (Decl *D = IDecl.getAs<Decl>()) {
3711 if (ObjCImplementationDecl *Impl = dyn_cast<ObjCImplementationDecl>(D)) {
3712 SearchDecl = Impl->getClassInterface();
3713 CurrentDecl = Impl;
3714 IsInImplementation = true;
3715 } else if (ObjCCategoryImplDecl *CatImpl
3716 = dyn_cast<ObjCCategoryImplDecl>(D)) {
3717 SearchDecl = CatImpl->getCategoryDecl();
3718 CurrentDecl = CatImpl;
3719 IsInImplementation = true;
3720 } else {
3721 SearchDecl = dyn_cast<ObjCContainerDecl>(D);
3722 CurrentDecl = SearchDecl;
3723 }
3724 }
3725
3726 if (!SearchDecl && S) {
3727 if (DeclContext *DC = static_cast<DeclContext *>(S->getEntity())) {
3728 SearchDecl = dyn_cast<ObjCContainerDecl>(DC);
3729 CurrentDecl = SearchDecl;
3730 }
3731 }
3732
3733 if (!SearchDecl || !CurrentDecl) {
3734 HandleCodeCompleteResults(this, CodeCompleter, 0, 0);
3735 return;
3736 }
3737
3738 // Find all of the methods that we could declare/implement here.
3739 KnownMethodsMap KnownMethods;
3740 FindImplementableMethods(Context, SearchDecl, IsInstanceMethod,
3741 ReturnType, IsInImplementation, KnownMethods);
3742
3743 // Erase any methods that have already been declared or
3744 // implemented here.
3745 for (ObjCContainerDecl::method_iterator M = CurrentDecl->meth_begin(),
3746 MEnd = CurrentDecl->meth_end();
3747 M != MEnd; ++M) {
3748 if ((*M)->isInstanceMethod() != IsInstanceMethod)
3749 continue;
3750
3751 KnownMethodsMap::iterator Pos = KnownMethods.find((*M)->getSelector());
3752 if (Pos != KnownMethods.end())
3753 KnownMethods.erase(Pos);
3754 }
3755
3756 // Add declarations or definitions for each of the known methods.
3757 typedef CodeCompleteConsumer::Result Result;
3758 ResultBuilder Results(*this);
3759 Results.EnterNewScope();
3760 PrintingPolicy Policy(Context.PrintingPolicy);
3761 Policy.AnonymousTagLocations = false;
3762 for (KnownMethodsMap::iterator M = KnownMethods.begin(),
3763 MEnd = KnownMethods.end();
3764 M != MEnd; ++M) {
3765 ObjCMethodDecl *Method = M->second;
3766 CodeCompletionString *Pattern = new CodeCompletionString;
3767
3768 // If the result type was not already provided, add it to the
3769 // pattern as (type).
3770 if (ReturnType.isNull()) {
3771 std::string TypeStr;
3772 Method->getResultType().getAsStringInternal(TypeStr, Policy);
3773 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3774 Pattern->AddTextChunk(TypeStr);
3775 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3776 }
3777
3778 Selector Sel = Method->getSelector();
3779
3780 // Add the first part of the selector to the pattern.
3781 Pattern->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
3782
3783 // Add parameters to the pattern.
3784 unsigned I = 0;
3785 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
3786 PEnd = Method->param_end();
3787 P != PEnd; (void)++P, ++I) {
3788 // Add the part of the selector name.
3789 if (I == 0)
3790 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3791 else if (I < Sel.getNumArgs()) {
3792 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3793 Pattern->AddTextChunk(Sel.getIdentifierInfoForSlot(1)->getName());
3794 Pattern->AddChunk(CodeCompletionString::CK_Colon);
3795 } else
3796 break;
3797
3798 // Add the parameter type.
3799 std::string TypeStr;
3800 (*P)->getOriginalType().getAsStringInternal(TypeStr, Policy);
3801 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
3802 Pattern->AddTextChunk(TypeStr);
3803 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
3804
3805 if (IdentifierInfo *Id = (*P)->getIdentifier())
3806 Pattern->AddTextChunk(Id->getName());
3807 }
3808
3809 if (Method->isVariadic()) {
3810 if (Method->param_size() > 0)
3811 Pattern->AddChunk(CodeCompletionString::CK_Comma);
3812 Pattern->AddTextChunk("...");
3813 }
3814
3815 if (IsInImplementation) {
3816 // We will be defining the method here, so add a compound statement.
3817 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3818 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
3819 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3820 if (!Method->getResultType()->isVoidType()) {
3821 // If the result type is not void, add a return clause.
3822 Pattern->AddTextChunk("return");
3823 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
3824 Pattern->AddPlaceholderChunk("expression");
3825 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
3826 } else
3827 Pattern->AddPlaceholderChunk("statements");
3828
3829 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
3830 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
3831 }
3832
3833 Results.AddResult(Result(Pattern));
3834 }
3835
3836 Results.ExitScope();
3837
3838 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3839}