blob: 73e0ab0fadebbb89f8e8541669efef8e33d61b83 [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"
14#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000015#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000016#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000017#include "clang/Lex/MacroInfo.h"
18#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000019#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000020#include "llvm/ADT/StringExtras.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000021#include <list>
22#include <map>
23#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000024
25using namespace clang;
26
Douglas Gregor86d9a522009-09-21 16:56:56 +000027namespace {
28 /// \brief A container of code-completion results.
29 class ResultBuilder {
30 public:
31 /// \brief The type of a name-lookup filter, which can be provided to the
32 /// name-lookup routines to specify which declarations should be included in
33 /// the result set (when it returns true) and which declarations should be
34 /// filtered out (returns false).
35 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
36
37 typedef CodeCompleteConsumer::Result Result;
38
39 private:
40 /// \brief The actual results we have found.
41 std::vector<Result> Results;
42
43 /// \brief A record of all of the declarations we have found and placed
44 /// into the result set, used to ensure that no declaration ever gets into
45 /// the result set twice.
46 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
47
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000048 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
49
50 /// \brief An entry in the shadow map, which is optimized to store
51 /// a single (declaration, index) mapping (the common case) but
52 /// can also store a list of (declaration, index) mappings.
53 class ShadowMapEntry {
54 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
55
56 /// \brief Contains either the solitary NamedDecl * or a vector
57 /// of (declaration, index) pairs.
58 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
59
60 /// \brief When the entry contains a single declaration, this is
61 /// the index associated with that entry.
62 unsigned SingleDeclIndex;
63
64 public:
65 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
66
67 void Add(NamedDecl *ND, unsigned Index) {
68 if (DeclOrVector.isNull()) {
69 // 0 - > 1 elements: just set the single element information.
70 DeclOrVector = ND;
71 SingleDeclIndex = Index;
72 return;
73 }
74
75 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
76 // 1 -> 2 elements: create the vector of results and push in the
77 // existing declaration.
78 DeclIndexPairVector *Vec = new DeclIndexPairVector;
79 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
80 DeclOrVector = Vec;
81 }
82
83 // Add the new element to the end of the vector.
84 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
85 DeclIndexPair(ND, Index));
86 }
87
88 void Destroy() {
89 if (DeclIndexPairVector *Vec
90 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
91 delete Vec;
92 DeclOrVector = ((NamedDecl *)0);
93 }
94 }
95
96 // Iteration.
97 class iterator;
98 iterator begin() const;
99 iterator end() const;
100 };
101
Douglas Gregor86d9a522009-09-21 16:56:56 +0000102 /// \brief A mapping from declaration names to the declarations that have
103 /// this name within a particular scope and their index within the list of
104 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000105 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000106
107 /// \brief The semantic analysis object for which results are being
108 /// produced.
109 Sema &SemaRef;
110
111 /// \brief If non-NULL, a filter function used to remove any code-completion
112 /// results that are not desirable.
113 LookupFilter Filter;
114
115 /// \brief A list of shadow maps, which is used to model name hiding at
116 /// different levels of, e.g., the inheritance hierarchy.
117 std::list<ShadowMap> ShadowMaps;
118
119 public:
120 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
121 : SemaRef(SemaRef), Filter(Filter) { }
122
123 /// \brief Set the filter used for code-completion results.
124 void setFilter(LookupFilter Filter) {
125 this->Filter = Filter;
126 }
127
128 typedef std::vector<Result>::iterator iterator;
129 iterator begin() { return Results.begin(); }
130 iterator end() { return Results.end(); }
131
132 Result *data() { return Results.empty()? 0 : &Results.front(); }
133 unsigned size() const { return Results.size(); }
134 bool empty() const { return Results.empty(); }
135
136 /// \brief Add a new result to this result set (if it isn't already in one
137 /// of the shadow maps), or replace an existing result (for, e.g., a
138 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000139 ///
140 /// \param R the result to add (if it is unique).
141 ///
142 /// \param R the context in which this result will be named.
143 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000144
145 /// \brief Enter into a new scope.
146 void EnterNewScope();
147
148 /// \brief Exit from the current scope.
149 void ExitScope();
150
Douglas Gregor55385fe2009-11-18 04:19:12 +0000151 /// \brief Ignore this declaration, if it is seen again.
152 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
153
Douglas Gregor86d9a522009-09-21 16:56:56 +0000154 /// \name Name lookup predicates
155 ///
156 /// These predicates can be passed to the name lookup functions to filter the
157 /// results of name lookup. All of the predicates have the same type, so that
158 ///
159 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000160 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000161 bool IsNestedNameSpecifier(NamedDecl *ND) const;
162 bool IsEnum(NamedDecl *ND) const;
163 bool IsClassOrStruct(NamedDecl *ND) const;
164 bool IsUnion(NamedDecl *ND) const;
165 bool IsNamespace(NamedDecl *ND) const;
166 bool IsNamespaceOrAlias(NamedDecl *ND) const;
167 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000168 bool IsMember(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000169 //@}
170 };
171}
172
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000173class ResultBuilder::ShadowMapEntry::iterator {
174 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
175 unsigned SingleDeclIndex;
176
177public:
178 typedef DeclIndexPair value_type;
179 typedef value_type reference;
180 typedef std::ptrdiff_t difference_type;
181 typedef std::input_iterator_tag iterator_category;
182
183 class pointer {
184 DeclIndexPair Value;
185
186 public:
187 pointer(const DeclIndexPair &Value) : Value(Value) { }
188
189 const DeclIndexPair *operator->() const {
190 return &Value;
191 }
192 };
193
194 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
195
196 iterator(NamedDecl *SingleDecl, unsigned Index)
197 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
198
199 iterator(const DeclIndexPair *Iterator)
200 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
201
202 iterator &operator++() {
203 if (DeclOrIterator.is<NamedDecl *>()) {
204 DeclOrIterator = (NamedDecl *)0;
205 SingleDeclIndex = 0;
206 return *this;
207 }
208
209 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
210 ++I;
211 DeclOrIterator = I;
212 return *this;
213 }
214
215 iterator operator++(int) {
216 iterator tmp(*this);
217 ++(*this);
218 return tmp;
219 }
220
221 reference operator*() const {
222 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
223 return reference(ND, SingleDeclIndex);
224
Douglas Gregord490f952009-12-06 21:27:58 +0000225 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000226 }
227
228 pointer operator->() const {
229 return pointer(**this);
230 }
231
232 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000233 return X.DeclOrIterator.getOpaqueValue()
234 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000235 X.SingleDeclIndex == Y.SingleDeclIndex;
236 }
237
238 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000239 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000240 }
241};
242
243namespace llvm {
244 template<>
245 struct DenseMapInfo<ResultBuilder::ShadowMapEntry> {
246 static bool isPod() { return false; }
247 };
248}
249
250ResultBuilder::ShadowMapEntry::iterator
251ResultBuilder::ShadowMapEntry::begin() const {
252 if (DeclOrVector.isNull())
253 return iterator();
254
255 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
256 return iterator(ND, SingleDeclIndex);
257
258 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
259}
260
261ResultBuilder::ShadowMapEntry::iterator
262ResultBuilder::ShadowMapEntry::end() const {
263 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
264 return iterator();
265
266 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
267}
268
Douglas Gregor86d9a522009-09-21 16:56:56 +0000269/// \brief Determines whether the given hidden result could be found with
270/// some extra work, e.g., by qualifying the name.
271///
272/// \param Hidden the declaration that is hidden by the currenly \p Visible
273/// declaration.
274///
275/// \param Visible the declaration with the same name that is already visible.
276///
277/// \returns true if the hidden result can be found by some mechanism,
278/// false otherwise.
279static bool canHiddenResultBeFound(const LangOptions &LangOpts,
280 NamedDecl *Hidden, NamedDecl *Visible) {
281 // In C, there is no way to refer to a hidden name.
282 if (!LangOpts.CPlusPlus)
283 return false;
284
285 DeclContext *HiddenCtx = Hidden->getDeclContext()->getLookupContext();
286
287 // There is no way to qualify a name declared in a function or method.
288 if (HiddenCtx->isFunctionOrMethod())
289 return false;
290
Douglas Gregor86d9a522009-09-21 16:56:56 +0000291 return HiddenCtx != Visible->getDeclContext()->getLookupContext();
292}
293
Douglas Gregor456c4a12009-09-21 20:12:40 +0000294/// \brief Compute the qualification required to get from the current context
295/// (\p CurContext) to the target context (\p TargetContext).
296///
297/// \param Context the AST context in which the qualification will be used.
298///
299/// \param CurContext the context where an entity is being named, which is
300/// typically based on the current scope.
301///
302/// \param TargetContext the context in which the named entity actually
303/// resides.
304///
305/// \returns a nested name specifier that refers into the target context, or
306/// NULL if no qualification is needed.
307static NestedNameSpecifier *
308getRequiredQualification(ASTContext &Context,
309 DeclContext *CurContext,
310 DeclContext *TargetContext) {
311 llvm::SmallVector<DeclContext *, 4> TargetParents;
312
313 for (DeclContext *CommonAncestor = TargetContext;
314 CommonAncestor && !CommonAncestor->Encloses(CurContext);
315 CommonAncestor = CommonAncestor->getLookupParent()) {
316 if (CommonAncestor->isTransparentContext() ||
317 CommonAncestor->isFunctionOrMethod())
318 continue;
319
320 TargetParents.push_back(CommonAncestor);
321 }
322
323 NestedNameSpecifier *Result = 0;
324 while (!TargetParents.empty()) {
325 DeclContext *Parent = TargetParents.back();
326 TargetParents.pop_back();
327
328 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
329 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
330 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
331 Result = NestedNameSpecifier::Create(Context, Result,
332 false,
333 Context.getTypeDeclType(TD).getTypePtr());
334 else
335 assert(Parent->isTranslationUnit());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000336 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000337 return Result;
338}
339
340void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
Douglas Gregor8e0a0e42009-09-22 23:31:26 +0000341 assert(!ShadowMaps.empty() && "Must enter into a results scope");
342
Douglas Gregor86d9a522009-09-21 16:56:56 +0000343 if (R.Kind != Result::RK_Declaration) {
344 // For non-declaration results, just add the result.
345 Results.push_back(R);
346 return;
347 }
Douglas Gregorf52cede2009-10-09 22:16:47 +0000348
349 // Skip unnamed entities.
350 if (!R.Declaration->getDeclName())
351 return;
352
Douglas Gregor86d9a522009-09-21 16:56:56 +0000353 // Look through using declarations.
John McCall9488ea12009-11-17 05:59:44 +0000354 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration))
Douglas Gregor0563c262009-09-22 23:15:58 +0000355 MaybeAddResult(Result(Using->getTargetDecl(), R.Rank, R.Qualifier),
356 CurContext);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000357
Douglas Gregor86d9a522009-09-21 16:56:56 +0000358 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
359 unsigned IDNS = CanonDecl->getIdentifierNamespace();
360
361 // Friend declarations and declarations introduced due to friends are never
362 // added as results.
363 if (isa<FriendDecl>(CanonDecl) ||
364 (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend)))
365 return;
366
367 if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) {
368 // __va_list_tag is a freak of nature. Find it and skip it.
369 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
370 return;
371
Douglas Gregorf52cede2009-10-09 22:16:47 +0000372 // Filter out names reserved for the implementation (C99 7.1.3,
373 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbare013d682009-10-18 20:26:12 +0000374 //
375 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000376 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000377 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000378 if (Name[0] == '_' &&
379 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
380 return;
381 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000382 }
383
384 // C++ constructors are never found by name lookup.
385 if (isa<CXXConstructorDecl>(CanonDecl))
386 return;
387
388 // Filter out any unwanted results.
389 if (Filter && !(this->*Filter)(R.Declaration))
390 return;
391
392 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000393 ShadowMapEntry::iterator I, IEnd;
394 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
395 if (NamePos != SMap.end()) {
396 I = NamePos->second.begin();
397 IEnd = NamePos->second.end();
398 }
399
400 for (; I != IEnd; ++I) {
401 NamedDecl *ND = I->first;
402 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000403 if (ND->getCanonicalDecl() == CanonDecl) {
404 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000405 Results[Index].Declaration = R.Declaration;
406
407 // Pick the best rank of the two.
408 Results[Index].Rank = std::min(Results[Index].Rank, R.Rank);
409
410 // We're done.
411 return;
412 }
413 }
414
415 // This is a new declaration in this scope. However, check whether this
416 // declaration name is hidden by a similarly-named declaration in an outer
417 // scope.
418 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
419 --SMEnd;
420 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000421 ShadowMapEntry::iterator I, IEnd;
422 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
423 if (NamePos != SM->end()) {
424 I = NamePos->second.begin();
425 IEnd = NamePos->second.end();
426 }
427 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000428 // A tag declaration does not hide a non-tag declaration.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000429 if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000430 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
431 Decl::IDNS_ObjCProtocol)))
432 continue;
433
434 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000435 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000436 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000437 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000438 continue;
439
440 // The newly-added result is hidden by an entry in the shadow map.
441 if (canHiddenResultBeFound(SemaRef.getLangOptions(), R.Declaration,
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000442 I->first)) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000443 // Note that this result was hidden.
444 R.Hidden = true;
Douglas Gregor0563c262009-09-22 23:15:58 +0000445 R.QualifierIsInformative = false;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000446
447 if (!R.Qualifier)
448 R.Qualifier = getRequiredQualification(SemaRef.Context,
449 CurContext,
450 R.Declaration->getDeclContext());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000451 } else {
452 // This result was hidden and cannot be found; don't bother adding
453 // it.
454 return;
455 }
456
457 break;
458 }
459 }
460
461 // Make sure that any given declaration only shows up in the result set once.
462 if (!AllDeclsFound.insert(CanonDecl))
463 return;
464
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000465 // If the filter is for nested-name-specifiers, then this result starts a
466 // nested-name-specifier.
467 if ((Filter == &ResultBuilder::IsNestedNameSpecifier) ||
468 (Filter == &ResultBuilder::IsMember &&
469 isa<CXXRecordDecl>(R.Declaration) &&
470 cast<CXXRecordDecl>(R.Declaration)->isInjectedClassName()))
471 R.StartsNestedNameSpecifier = true;
472
Douglas Gregor0563c262009-09-22 23:15:58 +0000473 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000474 if (R.QualifierIsInformative && !R.Qualifier &&
475 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000476 DeclContext *Ctx = R.Declaration->getDeclContext();
477 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
478 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
479 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
480 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
481 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
482 else
483 R.QualifierIsInformative = false;
484 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000485
Douglas Gregor86d9a522009-09-21 16:56:56 +0000486 // Insert this result into the set of results and into the current shadow
487 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000488 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000489 Results.push_back(R);
490}
491
492/// \brief Enter into a new scope.
493void ResultBuilder::EnterNewScope() {
494 ShadowMaps.push_back(ShadowMap());
495}
496
497/// \brief Exit from the current scope.
498void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000499 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
500 EEnd = ShadowMaps.back().end();
501 E != EEnd;
502 ++E)
503 E->second.Destroy();
504
Douglas Gregor86d9a522009-09-21 16:56:56 +0000505 ShadowMaps.pop_back();
506}
507
Douglas Gregor791215b2009-09-21 20:51:25 +0000508/// \brief Determines whether this given declaration will be found by
509/// ordinary name lookup.
510bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
511 unsigned IDNS = Decl::IDNS_Ordinary;
512 if (SemaRef.getLangOptions().CPlusPlus)
513 IDNS |= Decl::IDNS_Tag;
514
515 return ND->getIdentifierNamespace() & IDNS;
516}
517
Douglas Gregor86d9a522009-09-21 16:56:56 +0000518/// \brief Determines whether the given declaration is suitable as the
519/// start of a C++ nested-name-specifier, e.g., a class or namespace.
520bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
521 // Allow us to find class templates, too.
522 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
523 ND = ClassTemplate->getTemplatedDecl();
524
525 return SemaRef.isAcceptableNestedNameSpecifier(ND);
526}
527
528/// \brief Determines whether the given declaration is an enumeration.
529bool ResultBuilder::IsEnum(NamedDecl *ND) const {
530 return isa<EnumDecl>(ND);
531}
532
533/// \brief Determines whether the given declaration is a class or struct.
534bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
535 // Allow us to find class templates, too.
536 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
537 ND = ClassTemplate->getTemplatedDecl();
538
539 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
540 return RD->getTagKind() == TagDecl::TK_class ||
541 RD->getTagKind() == TagDecl::TK_struct;
542
543 return false;
544}
545
546/// \brief Determines whether the given declaration is a union.
547bool ResultBuilder::IsUnion(NamedDecl *ND) const {
548 // Allow us to find class templates, too.
549 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
550 ND = ClassTemplate->getTemplatedDecl();
551
552 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
553 return RD->getTagKind() == TagDecl::TK_union;
554
555 return false;
556}
557
558/// \brief Determines whether the given declaration is a namespace.
559bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
560 return isa<NamespaceDecl>(ND);
561}
562
563/// \brief Determines whether the given declaration is a namespace or
564/// namespace alias.
565bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
566 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
567}
568
569/// \brief Brief determines whether the given declaration is a namespace or
570/// namespace alias.
571bool ResultBuilder::IsType(NamedDecl *ND) const {
572 return isa<TypeDecl>(ND);
573}
574
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000575/// \brief Since every declaration found within a class is a member that we
576/// care about, always returns true. This predicate exists mostly to
577/// communicate to the result builder that we are performing a lookup for
578/// member access.
579bool ResultBuilder::IsMember(NamedDecl *ND) const {
580 return true;
581}
582
Douglas Gregor86d9a522009-09-21 16:56:56 +0000583// Find the next outer declaration context corresponding to this scope.
584static DeclContext *findOuterContext(Scope *S) {
585 for (S = S->getParent(); S; S = S->getParent())
586 if (S->getEntity())
587 return static_cast<DeclContext *>(S->getEntity())->getPrimaryContext();
588
589 return 0;
590}
591
592/// \brief Collect the results of searching for members within the given
593/// declaration context.
594///
595/// \param Ctx the declaration context from which we will gather results.
596///
Douglas Gregor0563c262009-09-22 23:15:58 +0000597/// \param Rank the rank given to results in this declaration context.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000598///
599/// \param Visited the set of declaration contexts that have already been
600/// visited. Declaration contexts will only be visited once.
601///
602/// \param Results the result set that will be extended with any results
603/// found within this declaration context (and, for a C++ class, its bases).
604///
Douglas Gregor0563c262009-09-22 23:15:58 +0000605/// \param InBaseClass whether we are in a base class.
606///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000607/// \returns the next higher rank value, after considering all of the
608/// names within this declaration context.
609static unsigned CollectMemberLookupResults(DeclContext *Ctx,
Douglas Gregor0563c262009-09-22 23:15:58 +0000610 unsigned Rank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000611 DeclContext *CurContext,
612 llvm::SmallPtrSet<DeclContext *, 16> &Visited,
Douglas Gregor0563c262009-09-22 23:15:58 +0000613 ResultBuilder &Results,
614 bool InBaseClass = false) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000615 // Make sure we don't visit the same context twice.
616 if (!Visited.insert(Ctx->getPrimaryContext()))
Douglas Gregor0563c262009-09-22 23:15:58 +0000617 return Rank;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000618
619 // Enumerate all of the results in this context.
Douglas Gregor0563c262009-09-22 23:15:58 +0000620 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000621 Results.EnterNewScope();
622 for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
623 CurCtx = CurCtx->getNextContext()) {
624 for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000625 DEnd = CurCtx->decls_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000626 D != DEnd; ++D) {
627 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
Douglas Gregor0563c262009-09-22 23:15:58 +0000628 Results.MaybeAddResult(Result(ND, Rank, 0, InBaseClass), CurContext);
Douglas Gregorff4393c2009-11-09 21:35:27 +0000629
630 // Visit transparent contexts inside this context.
631 if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
632 if (InnerCtx->isTransparentContext())
633 CollectMemberLookupResults(InnerCtx, Rank, CurContext, Visited,
634 Results, InBaseClass);
635 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000636 }
637 }
638
639 // Traverse the contexts of inherited classes.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000640 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
641 for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000642 BEnd = Record->bases_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000643 B != BEnd; ++B) {
644 QualType BaseType = B->getType();
645
646 // Don't look into dependent bases, because name lookup can't look
647 // there anyway.
648 if (BaseType->isDependentType())
649 continue;
650
651 const RecordType *Record = BaseType->getAs<RecordType>();
652 if (!Record)
653 continue;
654
655 // FIXME: It would be nice to be able to determine whether referencing
656 // a particular member would be ambiguous. For example, given
657 //
658 // struct A { int member; };
659 // struct B { int member; };
660 // struct C : A, B { };
661 //
662 // void f(C *c) { c->### }
663 // accessing 'member' would result in an ambiguity. However, code
664 // completion could be smart enough to qualify the member with the
665 // base class, e.g.,
666 //
667 // c->B::member
668 //
669 // or
670 //
671 // c->A::member
672
673 // Collect results from this base class (and its bases).
Douglas Gregor0563c262009-09-22 23:15:58 +0000674 CollectMemberLookupResults(Record->getDecl(), Rank, CurContext, Visited,
675 Results, /*InBaseClass=*/true);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000676 }
677 }
678
679 // FIXME: Look into base classes in Objective-C!
680
681 Results.ExitScope();
Douglas Gregor0563c262009-09-22 23:15:58 +0000682 return Rank + 1;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000683}
684
685/// \brief Collect the results of searching for members within the given
686/// declaration context.
687///
688/// \param Ctx the declaration context from which we will gather results.
689///
690/// \param InitialRank the initial rank given to results in this declaration
691/// context. Larger rank values will be used for, e.g., members found in
692/// base classes.
693///
694/// \param Results the result set that will be extended with any results
695/// found within this declaration context (and, for a C++ class, its bases).
696///
697/// \returns the next higher rank value, after considering all of the
698/// names within this declaration context.
699static unsigned CollectMemberLookupResults(DeclContext *Ctx,
700 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000701 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000702 ResultBuilder &Results) {
703 llvm::SmallPtrSet<DeclContext *, 16> Visited;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000704 return CollectMemberLookupResults(Ctx, InitialRank, CurContext, Visited,
705 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000706}
707
708/// \brief Collect the results of searching for declarations within the given
709/// scope and its parent scopes.
710///
711/// \param S the scope in which we will start looking for declarations.
712///
713/// \param InitialRank the initial rank given to results in this scope.
714/// Larger rank values will be used for results found in parent scopes.
715///
Douglas Gregor456c4a12009-09-21 20:12:40 +0000716/// \param CurContext the context from which lookup results will be found.
717///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000718/// \param Results the builder object that will receive each result.
719static unsigned CollectLookupResults(Scope *S,
720 TranslationUnitDecl *TranslationUnit,
721 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000722 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000723 ResultBuilder &Results) {
724 if (!S)
725 return InitialRank;
726
727 // FIXME: Using directives!
728
729 unsigned NextRank = InitialRank;
730 Results.EnterNewScope();
731 if (S->getEntity() &&
732 !((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
733 // Look into this scope's declaration context, along with any of its
734 // parent lookup contexts (e.g., enclosing classes), up to the point
735 // where we hit the context stored in the next outer scope.
736 DeclContext *Ctx = (DeclContext *)S->getEntity();
737 DeclContext *OuterCtx = findOuterContext(S);
738
739 for (; Ctx && Ctx->getPrimaryContext() != OuterCtx;
740 Ctx = Ctx->getLookupParent()) {
741 if (Ctx->isFunctionOrMethod())
742 continue;
743
Douglas Gregor456c4a12009-09-21 20:12:40 +0000744 NextRank = CollectMemberLookupResults(Ctx, NextRank + 1, CurContext,
745 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000746 }
747 } else if (!S->getParent()) {
748 // Look into the translation unit scope. We walk through the translation
749 // unit's declaration context, because the Scope itself won't have all of
750 // the declarations if we loaded a precompiled header.
751 // FIXME: We would like the translation unit's Scope object to point to the
752 // translation unit, so we don't need this special "if" branch. However,
753 // doing so would force the normal C++ name-lookup code to look into the
754 // translation unit decl when the IdentifierInfo chains would suffice.
755 // Once we fix that problem (which is part of a more general "don't look
756 // in DeclContexts unless we have to" optimization), we can eliminate the
757 // TranslationUnit parameter entirely.
758 NextRank = CollectMemberLookupResults(TranslationUnit, NextRank + 1,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000759 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000760 } else {
761 // Walk through the declarations in this Scope.
762 for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
763 D != DEnd; ++D) {
764 if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
Douglas Gregor456c4a12009-09-21 20:12:40 +0000765 Results.MaybeAddResult(CodeCompleteConsumer::Result(ND, NextRank),
766 CurContext);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000767 }
768
769 NextRank = NextRank + 1;
770 }
771
772 // Lookup names in the parent scope.
773 NextRank = CollectLookupResults(S->getParent(), TranslationUnit, NextRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000774 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000775 Results.ExitScope();
776
777 return NextRank;
778}
779
780/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregor9a0c85e2009-12-07 09:51:25 +0000781static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000782 ResultBuilder &Results) {
783 typedef CodeCompleteConsumer::Result Result;
784 Results.MaybeAddResult(Result("short", Rank));
785 Results.MaybeAddResult(Result("long", Rank));
786 Results.MaybeAddResult(Result("signed", Rank));
787 Results.MaybeAddResult(Result("unsigned", Rank));
788 Results.MaybeAddResult(Result("void", Rank));
789 Results.MaybeAddResult(Result("char", Rank));
790 Results.MaybeAddResult(Result("int", Rank));
791 Results.MaybeAddResult(Result("float", Rank));
792 Results.MaybeAddResult(Result("double", Rank));
793 Results.MaybeAddResult(Result("enum", Rank));
794 Results.MaybeAddResult(Result("struct", Rank));
795 Results.MaybeAddResult(Result("union", Rank));
796
797 if (LangOpts.C99) {
798 // C99-specific
799 Results.MaybeAddResult(Result("_Complex", Rank));
800 Results.MaybeAddResult(Result("_Imaginary", Rank));
801 Results.MaybeAddResult(Result("_Bool", Rank));
802 }
803
804 if (LangOpts.CPlusPlus) {
805 // C++-specific
806 Results.MaybeAddResult(Result("bool", Rank));
807 Results.MaybeAddResult(Result("class", Rank));
808 Results.MaybeAddResult(Result("typename", Rank));
809 Results.MaybeAddResult(Result("wchar_t", Rank));
810
811 if (LangOpts.CPlusPlus0x) {
812 Results.MaybeAddResult(Result("char16_t", Rank));
813 Results.MaybeAddResult(Result("char32_t", Rank));
814 Results.MaybeAddResult(Result("decltype", Rank));
815 }
816 }
817
818 // GNU extensions
819 if (LangOpts.GNUMode) {
820 // FIXME: Enable when we actually support decimal floating point.
821 // Results.MaybeAddResult(Result("_Decimal32", Rank));
822 // Results.MaybeAddResult(Result("_Decimal64", Rank));
823 // Results.MaybeAddResult(Result("_Decimal128", Rank));
824 Results.MaybeAddResult(Result("typeof", Rank));
825 }
826}
827
828/// \brief Add function parameter chunks to the given code completion string.
829static void AddFunctionParameterChunks(ASTContext &Context,
830 FunctionDecl *Function,
831 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000832 typedef CodeCompletionString::Chunk Chunk;
833
Douglas Gregor86d9a522009-09-21 16:56:56 +0000834 CodeCompletionString *CCStr = Result;
835
836 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
837 ParmVarDecl *Param = Function->getParamDecl(P);
838
839 if (Param->hasDefaultArg()) {
840 // When we see an optional default argument, put that argument and
841 // the remaining default arguments into a new, optional string.
842 CodeCompletionString *Opt = new CodeCompletionString;
843 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
844 CCStr = Opt;
845 }
846
847 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000848 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000849
850 // Format the placeholder string.
851 std::string PlaceholderStr;
852 if (Param->getIdentifier())
853 PlaceholderStr = Param->getIdentifier()->getName();
854
855 Param->getType().getAsStringInternal(PlaceholderStr,
856 Context.PrintingPolicy);
857
858 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +0000859 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000860 }
Douglas Gregorb3d45252009-09-22 21:42:17 +0000861
862 if (const FunctionProtoType *Proto
863 = Function->getType()->getAs<FunctionProtoType>())
864 if (Proto->isVariadic())
865 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +0000866}
867
868/// \brief Add template parameter chunks to the given code completion string.
869static void AddTemplateParameterChunks(ASTContext &Context,
870 TemplateDecl *Template,
871 CodeCompletionString *Result,
872 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000873 typedef CodeCompletionString::Chunk Chunk;
874
Douglas Gregor86d9a522009-09-21 16:56:56 +0000875 CodeCompletionString *CCStr = Result;
876 bool FirstParameter = true;
877
878 TemplateParameterList *Params = Template->getTemplateParameters();
879 TemplateParameterList::iterator PEnd = Params->end();
880 if (MaxParameters)
881 PEnd = Params->begin() + MaxParameters;
882 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
883 bool HasDefaultArg = false;
884 std::string PlaceholderStr;
885 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
886 if (TTP->wasDeclaredWithTypename())
887 PlaceholderStr = "typename";
888 else
889 PlaceholderStr = "class";
890
891 if (TTP->getIdentifier()) {
892 PlaceholderStr += ' ';
893 PlaceholderStr += TTP->getIdentifier()->getName();
894 }
895
896 HasDefaultArg = TTP->hasDefaultArgument();
897 } else if (NonTypeTemplateParmDecl *NTTP
898 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
899 if (NTTP->getIdentifier())
900 PlaceholderStr = NTTP->getIdentifier()->getName();
901 NTTP->getType().getAsStringInternal(PlaceholderStr,
902 Context.PrintingPolicy);
903 HasDefaultArg = NTTP->hasDefaultArgument();
904 } else {
905 assert(isa<TemplateTemplateParmDecl>(*P));
906 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
907
908 // Since putting the template argument list into the placeholder would
909 // be very, very long, we just use an abbreviation.
910 PlaceholderStr = "template<...> class";
911 if (TTP->getIdentifier()) {
912 PlaceholderStr += ' ';
913 PlaceholderStr += TTP->getIdentifier()->getName();
914 }
915
916 HasDefaultArg = TTP->hasDefaultArgument();
917 }
918
919 if (HasDefaultArg) {
920 // When we see an optional default argument, put that argument and
921 // the remaining default arguments into a new, optional string.
922 CodeCompletionString *Opt = new CodeCompletionString;
923 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
924 CCStr = Opt;
925 }
926
927 if (FirstParameter)
928 FirstParameter = false;
929 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000930 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000931
932 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +0000933 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000934 }
935}
936
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000937/// \brief Add a qualifier to the given code-completion string, if the
938/// provided nested-name-specifier is non-NULL.
939void AddQualifierToCompletionString(CodeCompletionString *Result,
940 NestedNameSpecifier *Qualifier,
Douglas Gregor0563c262009-09-22 23:15:58 +0000941 bool QualifierIsInformative,
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000942 ASTContext &Context) {
943 if (!Qualifier)
944 return;
945
946 std::string PrintedNNS;
947 {
948 llvm::raw_string_ostream OS(PrintedNNS);
949 Qualifier->print(OS, Context.PrintingPolicy);
950 }
Douglas Gregor0563c262009-09-22 23:15:58 +0000951 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +0000952 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +0000953 else
Benjamin Kramer660cc182009-11-29 20:18:50 +0000954 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000955}
956
Douglas Gregor86d9a522009-09-21 16:56:56 +0000957/// \brief If possible, create a new code completion string for the given
958/// result.
959///
960/// \returns Either a new, heap-allocated code completion string describing
961/// how to use this result, or NULL to indicate that the string or name of the
962/// result is all that is needed.
963CodeCompletionString *
964CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000965 typedef CodeCompletionString::Chunk Chunk;
966
Douglas Gregor2b4074f2009-12-01 05:55:20 +0000967 if (Kind == RK_Pattern)
968 return Pattern->Clone();
969
970 CodeCompletionString *Result = new CodeCompletionString;
971
972 if (Kind == RK_Keyword) {
973 Result->AddTypedTextChunk(Keyword);
974 return Result;
975 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000976
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000977 if (Kind == RK_Macro) {
978 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +0000979 assert(MI && "Not a macro?");
980
981 Result->AddTypedTextChunk(Macro->getName());
982
983 if (!MI->isFunctionLike())
984 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000985
986 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000987 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000988 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
989 A != AEnd; ++A) {
990 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000991 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000992
993 if (!MI->isVariadic() || A != AEnd - 1) {
994 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +0000995 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000996 continue;
997 }
998
999 // Variadic argument; cope with the different between GNU and C99
1000 // variadic macros, providing a single placeholder for the rest of the
1001 // arguments.
1002 if ((*A)->isStr("__VA_ARGS__"))
1003 Result->AddPlaceholderChunk("...");
1004 else {
1005 std::string Arg = (*A)->getName();
1006 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001007 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001008 }
1009 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001010 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001011 return Result;
1012 }
1013
1014 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001015 NamedDecl *ND = Declaration;
1016
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001017 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001018 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001019 Result->AddTextChunk("::");
1020 return Result;
1021 }
1022
Douglas Gregor86d9a522009-09-21 16:56:56 +00001023 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001024 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1025 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001026 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001027 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001028 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001029 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001030 return Result;
1031 }
1032
1033 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001034 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1035 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001036 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001037 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001038
1039 // Figure out which template parameters are deduced (or have default
1040 // arguments).
1041 llvm::SmallVector<bool, 16> Deduced;
1042 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1043 unsigned LastDeducibleArgument;
1044 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1045 --LastDeducibleArgument) {
1046 if (!Deduced[LastDeducibleArgument - 1]) {
1047 // C++0x: Figure out if the template argument has a default. If so,
1048 // the user doesn't need to type this argument.
1049 // FIXME: We need to abstract template parameters better!
1050 bool HasDefaultArg = false;
1051 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1052 LastDeducibleArgument - 1);
1053 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1054 HasDefaultArg = TTP->hasDefaultArgument();
1055 else if (NonTypeTemplateParmDecl *NTTP
1056 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1057 HasDefaultArg = NTTP->hasDefaultArgument();
1058 else {
1059 assert(isa<TemplateTemplateParmDecl>(Param));
1060 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001061 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001062 }
1063
1064 if (!HasDefaultArg)
1065 break;
1066 }
1067 }
1068
1069 if (LastDeducibleArgument) {
1070 // Some of the function template arguments cannot be deduced from a
1071 // function call, so we introduce an explicit template argument list
1072 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001073 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001074 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1075 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001076 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001077 }
1078
1079 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001080 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001081 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001082 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001083 return Result;
1084 }
1085
1086 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001087 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1088 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001089 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001090 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001091 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001092 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001093 return Result;
1094 }
1095
Douglas Gregor9630eb62009-11-17 16:44:22 +00001096 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001097 Selector Sel = Method->getSelector();
1098 if (Sel.isUnarySelector()) {
1099 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1100 return Result;
1101 }
1102
Douglas Gregord3c68542009-11-19 01:08:35 +00001103 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1104 SelName += ':';
1105 if (StartParameter == 0)
1106 Result->AddTypedTextChunk(SelName);
1107 else {
1108 Result->AddInformativeChunk(SelName);
1109
1110 // If there is only one parameter, and we're past it, add an empty
1111 // typed-text chunk since there is nothing to type.
1112 if (Method->param_size() == 1)
1113 Result->AddTypedTextChunk("");
1114 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001115 unsigned Idx = 0;
1116 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1117 PEnd = Method->param_end();
1118 P != PEnd; (void)++P, ++Idx) {
1119 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001120 std::string Keyword;
1121 if (Idx > StartParameter)
1122 Keyword = " ";
Douglas Gregor9630eb62009-11-17 16:44:22 +00001123 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1124 Keyword += II->getName().str();
1125 Keyword += ":";
Douglas Gregor4ad96852009-11-19 07:41:15 +00001126 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001127 Result->AddInformativeChunk(Keyword);
1128 } else if (Idx == StartParameter)
1129 Result->AddTypedTextChunk(Keyword);
1130 else
1131 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001132 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001133
1134 // If we're before the starting parameter, skip the placeholder.
1135 if (Idx < StartParameter)
1136 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001137
1138 std::string Arg;
1139 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1140 Arg = "(" + Arg + ")";
1141 if (IdentifierInfo *II = (*P)->getIdentifier())
1142 Arg += II->getName().str();
Douglas Gregor4ad96852009-11-19 07:41:15 +00001143 if (AllParametersAreInformative)
1144 Result->AddInformativeChunk(Arg);
1145 else
1146 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001147 }
1148
1149 return Result;
1150 }
1151
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001152 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00001153 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1154 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001155
1156 Result->AddTypedTextChunk(ND->getNameAsString());
1157 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001158}
1159
Douglas Gregor86d802e2009-09-23 00:34:09 +00001160CodeCompletionString *
1161CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1162 unsigned CurrentArg,
1163 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001164 typedef CodeCompletionString::Chunk Chunk;
1165
Douglas Gregor86d802e2009-09-23 00:34:09 +00001166 CodeCompletionString *Result = new CodeCompletionString;
1167 FunctionDecl *FDecl = getFunction();
1168 const FunctionProtoType *Proto
1169 = dyn_cast<FunctionProtoType>(getFunctionType());
1170 if (!FDecl && !Proto) {
1171 // Function without a prototype. Just give the return type and a
1172 // highlighted ellipsis.
1173 const FunctionType *FT = getFunctionType();
1174 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001175 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001176 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1177 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1178 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001179 return Result;
1180 }
1181
1182 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001183 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00001184 else
1185 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001186 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001187
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001188 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001189 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1190 for (unsigned I = 0; I != NumParams; ++I) {
1191 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001192 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001193
1194 std::string ArgString;
1195 QualType ArgType;
1196
1197 if (FDecl) {
1198 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1199 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1200 } else {
1201 ArgType = Proto->getArgType(I);
1202 }
1203
1204 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1205
1206 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001207 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00001208 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001209 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001210 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001211 }
1212
1213 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001214 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001215 if (CurrentArg < NumParams)
1216 Result->AddTextChunk("...");
1217 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001218 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001219 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001220 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001221
1222 return Result;
1223}
1224
Douglas Gregor86d9a522009-09-21 16:56:56 +00001225namespace {
1226 struct SortCodeCompleteResult {
1227 typedef CodeCompleteConsumer::Result Result;
1228
Douglas Gregor6a684032009-09-28 03:51:44 +00001229 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001230 Selector XSel = X.getObjCSelector();
1231 Selector YSel = Y.getObjCSelector();
1232 if (!XSel.isNull() && !YSel.isNull()) {
1233 // We are comparing two selectors.
1234 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1235 if (N == 0)
1236 ++N;
1237 for (unsigned I = 0; I != N; ++I) {
1238 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1239 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1240 if (!XId || !YId)
1241 return XId && !YId;
1242
1243 switch (XId->getName().compare_lower(YId->getName())) {
1244 case -1: return true;
1245 case 1: return false;
1246 default: break;
1247 }
1248 }
1249
1250 return XSel.getNumArgs() < YSel.getNumArgs();
1251 }
1252
1253 // For non-selectors, order by kind.
1254 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00001255 return X.getNameKind() < Y.getNameKind();
1256
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001257 // Order identifiers by comparison of their lowercased names.
1258 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1259 return XId->getName().compare_lower(
1260 Y.getAsIdentifierInfo()->getName()) < 0;
1261
1262 // Order overloaded operators by the order in which they appear
1263 // in our list of operators.
1264 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1265 return XOp < Y.getCXXOverloadedOperator();
1266
1267 // Order C++0x user-defined literal operators lexically by their
1268 // lowercased suffixes.
1269 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1270 return XLit->getName().compare_lower(
1271 Y.getCXXLiteralIdentifier()->getName()) < 0;
1272
1273 // The only stable ordering we have is to turn the name into a
1274 // string and then compare the lower-case strings. This is
1275 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00001276 return llvm::StringRef(X.getAsString()).compare_lower(
1277 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00001278 }
1279
Douglas Gregor86d9a522009-09-21 16:56:56 +00001280 bool operator()(const Result &X, const Result &Y) const {
1281 // Sort first by rank.
1282 if (X.Rank < Y.Rank)
1283 return true;
1284 else if (X.Rank > Y.Rank)
1285 return false;
1286
Douglas Gregor54f01612009-11-19 00:01:57 +00001287 // We use a special ordering for keywords and patterns, based on the
1288 // typed text.
1289 if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
1290 (Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
1291 const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword
1292 : X.Pattern->getTypedText();
1293 const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
1294 : Y.Pattern->getTypedText();
Benjamin Kramerf42d4882009-12-05 10:07:04 +00001295 return llvm::StringRef(XStr).compare_lower(YStr) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001296 }
1297
Douglas Gregor86d9a522009-09-21 16:56:56 +00001298 // Result kinds are ordered by decreasing importance.
1299 if (X.Kind < Y.Kind)
1300 return true;
1301 else if (X.Kind > Y.Kind)
1302 return false;
1303
1304 // Non-hidden names precede hidden names.
1305 if (X.Hidden != Y.Hidden)
1306 return !X.Hidden;
1307
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001308 // Non-nested-name-specifiers precede nested-name-specifiers.
1309 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1310 return !X.StartsNestedNameSpecifier;
1311
Douglas Gregor86d9a522009-09-21 16:56:56 +00001312 // Ordering depends on the kind of result.
1313 switch (X.Kind) {
1314 case Result::RK_Declaration:
1315 // Order based on the declaration names.
Douglas Gregor6a684032009-09-28 03:51:44 +00001316 return isEarlierDeclarationName(X.Declaration->getDeclName(),
1317 Y.Declaration->getDeclName());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001318
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001319 case Result::RK_Macro:
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001320 return X.Macro->getName().compare_lower(Y.Macro->getName()) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001321
1322 case Result::RK_Keyword:
1323 case Result::RK_Pattern:
1324 llvm::llvm_unreachable("Result kinds handled above");
1325 break;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001326 }
1327
1328 // Silence GCC warning.
1329 return false;
1330 }
1331 };
1332}
1333
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001334static void AddMacroResults(Preprocessor &PP, unsigned Rank,
1335 ResultBuilder &Results) {
1336 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001337 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1338 MEnd = PP.macro_end();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001339 M != MEnd; ++M)
1340 Results.MaybeAddResult(CodeCompleteConsumer::Result(M->first, Rank));
1341 Results.ExitScope();
1342}
1343
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001344static void HandleCodeCompleteResults(Sema *S,
1345 CodeCompleteConsumer *CodeCompleter,
1346 CodeCompleteConsumer::Result *Results,
1347 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001348 // Sort the results by rank/kind/etc.
1349 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1350
1351 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001352 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00001353
1354 for (unsigned I = 0; I != NumResults; ++I)
1355 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001356}
1357
Douglas Gregor791215b2009-09-21 20:51:25 +00001358void Sema::CodeCompleteOrdinaryName(Scope *S) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001359 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor791215b2009-09-21 20:51:25 +00001360 ResultBuilder Results(*this, &ResultBuilder::IsOrdinaryName);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001361 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1362 0, CurContext, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001363
1364 Results.EnterNewScope();
1365 AddTypeSpecifierResults(getLangOptions(), NextRank, Results);
1366
1367 if (getLangOptions().ObjC1) {
1368 // Add the "super" keyword, if appropriate.
1369 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
1370 if (Method->getClassInterface()->getSuperClass())
1371 Results.MaybeAddResult(Result("super", NextRank));
1372 }
1373
1374 Results.ExitScope();
1375
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001376 if (CodeCompleter->includeMacros())
1377 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001378 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00001379}
1380
Douglas Gregor95ac6552009-11-18 01:29:26 +00001381static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00001382 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00001383 DeclContext *CurContext,
1384 ResultBuilder &Results) {
1385 typedef CodeCompleteConsumer::Result Result;
1386
1387 // Add properties in this container.
1388 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1389 PEnd = Container->prop_end();
1390 P != PEnd;
1391 ++P)
1392 Results.MaybeAddResult(Result(*P, 0), CurContext);
1393
1394 // Add properties in referenced protocols.
1395 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1396 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1397 PEnd = Protocol->protocol_end();
1398 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001399 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001400 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00001401 if (AllowCategories) {
1402 // Look through categories.
1403 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1404 Category; Category = Category->getNextClassCategory())
1405 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1406 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001407
1408 // Look through protocols.
1409 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1410 E = IFace->protocol_end();
1411 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001412 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001413
1414 // Look in the superclass.
1415 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00001416 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
1417 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001418 } else if (const ObjCCategoryDecl *Category
1419 = dyn_cast<ObjCCategoryDecl>(Container)) {
1420 // Look through protocols.
1421 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
1422 PEnd = Category->protocol_end();
1423 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001424 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001425 }
1426}
1427
Douglas Gregor81b747b2009-09-17 21:32:03 +00001428void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
1429 SourceLocation OpLoc,
1430 bool IsArrow) {
1431 if (!BaseE || !CodeCompleter)
1432 return;
1433
Douglas Gregor86d9a522009-09-21 16:56:56 +00001434 typedef CodeCompleteConsumer::Result Result;
1435
Douglas Gregor81b747b2009-09-17 21:32:03 +00001436 Expr *Base = static_cast<Expr *>(BaseE);
1437 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001438
1439 if (IsArrow) {
1440 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1441 BaseType = Ptr->getPointeeType();
1442 else if (BaseType->isObjCObjectPointerType())
1443 /*Do nothing*/ ;
1444 else
1445 return;
1446 }
1447
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001448 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001449 unsigned NextRank = 0;
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001450
Douglas Gregor95ac6552009-11-18 01:29:26 +00001451 Results.EnterNewScope();
1452 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
1453 // Access to a C/C++ class, struct, or union.
1454 NextRank = CollectMemberLookupResults(Record->getDecl(), NextRank,
1455 Record->getDecl(), Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001456
Douglas Gregor95ac6552009-11-18 01:29:26 +00001457 if (getLangOptions().CPlusPlus) {
1458 if (!Results.empty()) {
1459 // The "template" keyword can follow "->" or "." in the grammar.
1460 // However, we only want to suggest the template keyword if something
1461 // is dependent.
1462 bool IsDependent = BaseType->isDependentType();
1463 if (!IsDependent) {
1464 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
1465 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
1466 IsDependent = Ctx->isDependentContext();
1467 break;
1468 }
1469 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001470
Douglas Gregor95ac6552009-11-18 01:29:26 +00001471 if (IsDependent)
1472 Results.MaybeAddResult(Result("template", NextRank++));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001473 }
1474
Douglas Gregor95ac6552009-11-18 01:29:26 +00001475 // We could have the start of a nested-name-specifier. Add those
1476 // results as well.
1477 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
1478 CollectLookupResults(S, Context.getTranslationUnitDecl(), NextRank,
1479 CurContext, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001480 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001481 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
1482 // Objective-C property reference.
1483
1484 // Add property results based on our interface.
1485 const ObjCObjectPointerType *ObjCPtr
1486 = BaseType->getAsObjCInterfacePointerType();
1487 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00001488 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001489
1490 // Add properties from the protocols in a qualified interface.
1491 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
1492 E = ObjCPtr->qual_end();
1493 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001494 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001495
1496 // FIXME: We could (should?) also look for "implicit" properties, identified
1497 // only by the presence of nullary and unary selectors.
1498 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
1499 (!IsArrow && BaseType->isObjCInterfaceType())) {
1500 // Objective-C instance variable access.
1501 ObjCInterfaceDecl *Class = 0;
1502 if (const ObjCObjectPointerType *ObjCPtr
1503 = BaseType->getAs<ObjCObjectPointerType>())
1504 Class = ObjCPtr->getInterfaceDecl();
1505 else
1506 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
1507
1508 // Add all ivars from this class and its superclasses.
1509 for (; Class; Class = Class->getSuperClass()) {
1510 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
1511 IVarEnd = Class->ivar_end();
1512 IVar != IVarEnd; ++IVar)
1513 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
1514 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001515 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001516
1517 // FIXME: How do we cope with isa?
1518
1519 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001520
1521 // Add macros
1522 if (CodeCompleter->includeMacros())
1523 AddMacroResults(PP, NextRank, Results);
1524
1525 // Hand off the results found for code completion.
1526 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00001527}
1528
Douglas Gregor374929f2009-09-18 15:37:17 +00001529void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
1530 if (!CodeCompleter)
1531 return;
1532
Douglas Gregor86d9a522009-09-21 16:56:56 +00001533 typedef CodeCompleteConsumer::Result Result;
1534 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00001535 switch ((DeclSpec::TST)TagSpec) {
1536 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001537 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00001538 break;
1539
1540 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001541 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00001542 break;
1543
1544 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00001545 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001546 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00001547 break;
1548
1549 default:
1550 assert(false && "Unknown type specifier kind in CodeCompleteTag");
1551 return;
1552 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001553
1554 ResultBuilder Results(*this, Filter);
1555 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00001556 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001557
1558 if (getLangOptions().CPlusPlus) {
1559 // We could have the start of a nested-name-specifier. Add those
1560 // results as well.
1561 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001562 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1563 NextRank, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001564 }
1565
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001566 if (CodeCompleter->includeMacros())
1567 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001568 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00001569}
1570
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001571void Sema::CodeCompleteCase(Scope *S) {
1572 if (getSwitchStack().empty() || !CodeCompleter)
1573 return;
1574
1575 SwitchStmt *Switch = getSwitchStack().back();
1576 if (!Switch->getCond()->getType()->isEnumeralType())
1577 return;
1578
1579 // Code-complete the cases of a switch statement over an enumeration type
1580 // by providing the list of
1581 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
1582
1583 // Determine which enumerators we have already seen in the switch statement.
1584 // FIXME: Ideally, we would also be able to look *past* the code-completion
1585 // token, in case we are code-completing in the middle of the switch and not
1586 // at the end. However, we aren't able to do so at the moment.
1587 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001588 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001589 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
1590 SC = SC->getNextSwitchCase()) {
1591 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
1592 if (!Case)
1593 continue;
1594
1595 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
1596 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
1597 if (EnumConstantDecl *Enumerator
1598 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
1599 // We look into the AST of the case statement to determine which
1600 // enumerator was named. Alternatively, we could compute the value of
1601 // the integral constant expression, then compare it against the
1602 // values of each enumerator. However, value-based approach would not
1603 // work as well with C++ templates where enumerators declared within a
1604 // template are type- and value-dependent.
1605 EnumeratorsSeen.insert(Enumerator);
1606
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001607 // If this is a qualified-id, keep track of the nested-name-specifier
1608 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001609 //
1610 // switch (TagD.getKind()) {
1611 // case TagDecl::TK_enum:
1612 // break;
1613 // case XXX
1614 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001615 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001616 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
1617 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00001618 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001619 }
1620 }
1621
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001622 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
1623 // If there are no prior enumerators in C++, check whether we have to
1624 // qualify the names of the enumerators that we suggest, because they
1625 // may not be visible in this scope.
1626 Qualifier = getRequiredQualification(Context, CurContext,
1627 Enum->getDeclContext());
1628
1629 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
1630 }
1631
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001632 // Add any enumerators that have not yet been mentioned.
1633 ResultBuilder Results(*this);
1634 Results.EnterNewScope();
1635 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
1636 EEnd = Enum->enumerator_end();
1637 E != EEnd; ++E) {
1638 if (EnumeratorsSeen.count(*E))
1639 continue;
1640
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001641 Results.MaybeAddResult(CodeCompleteConsumer::Result(*E, 0, Qualifier));
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001642 }
1643 Results.ExitScope();
1644
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001645 if (CodeCompleter->includeMacros())
1646 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001647 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001648}
1649
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001650namespace {
1651 struct IsBetterOverloadCandidate {
1652 Sema &S;
1653
1654 public:
1655 explicit IsBetterOverloadCandidate(Sema &S) : S(S) { }
1656
1657 bool
1658 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
1659 return S.isBetterOverloadCandidate(X, Y);
1660 }
1661 };
1662}
1663
1664void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
1665 ExprTy **ArgsIn, unsigned NumArgs) {
1666 if (!CodeCompleter)
1667 return;
1668
1669 Expr *Fn = (Expr *)FnIn;
1670 Expr **Args = (Expr **)ArgsIn;
1671
1672 // Ignore type-dependent call expressions entirely.
1673 if (Fn->isTypeDependent() ||
1674 Expr::hasAnyTypeDependentArguments(Args, NumArgs))
1675 return;
1676
John McCallba135432009-11-21 08:51:07 +00001677 llvm::SmallVector<NamedDecl*,8> Fns;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001678 DeclarationName UnqualifiedName;
1679 NestedNameSpecifier *Qualifier;
1680 SourceRange QualifierRange;
1681 bool ArgumentDependentLookup;
John McCall7453ed42009-11-22 00:44:51 +00001682 bool Overloaded;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001683 bool HasExplicitTemplateArgs;
John McCalld5532b62009-11-23 01:53:49 +00001684 TemplateArgumentListInfo ExplicitTemplateArgs;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001685
John McCallba135432009-11-21 08:51:07 +00001686 DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
John McCall7453ed42009-11-22 00:44:51 +00001687 ArgumentDependentLookup, Overloaded,
John McCalld5532b62009-11-23 01:53:49 +00001688 HasExplicitTemplateArgs, ExplicitTemplateArgs);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001689
1690
1691 // FIXME: What if we're calling something that isn't a function declaration?
1692 // FIXME: What if we're calling a pseudo-destructor?
1693 // FIXME: What if we're calling a member function?
1694
1695 // Build an overload candidate set based on the functions we find.
1696 OverloadCandidateSet CandidateSet;
John McCallba135432009-11-21 08:51:07 +00001697 AddOverloadedCallCandidates(Fns, UnqualifiedName,
John McCalld5532b62009-11-23 01:53:49 +00001698 ArgumentDependentLookup,
1699 (HasExplicitTemplateArgs ? &ExplicitTemplateArgs : 0),
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001700 Args, NumArgs,
1701 CandidateSet,
1702 /*PartialOverloading=*/true);
1703
1704 // Sort the overload candidate set by placing the best overloads first.
1705 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
1706 IsBetterOverloadCandidate(*this));
1707
1708 // Add the remaining viable overload candidates as code-completion reslults.
Douglas Gregor05944382009-09-23 00:16:58 +00001709 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
1710 llvm::SmallVector<ResultCandidate, 8> Results;
Anders Carlsson90756302009-09-22 17:29:51 +00001711
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001712 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
1713 CandEnd = CandidateSet.end();
1714 Cand != CandEnd; ++Cand) {
1715 if (Cand->Viable)
Douglas Gregor05944382009-09-23 00:16:58 +00001716 Results.push_back(ResultCandidate(Cand->Function));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001717 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001718 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
Douglas Gregor05944382009-09-23 00:16:58 +00001719 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001720}
1721
Douglas Gregor81b747b2009-09-17 21:32:03 +00001722void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
1723 bool EnteringContext) {
1724 if (!SS.getScopeRep() || !CodeCompleter)
1725 return;
1726
Douglas Gregor86d9a522009-09-21 16:56:56 +00001727 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
1728 if (!Ctx)
1729 return;
1730
1731 ResultBuilder Results(*this);
Douglas Gregor456c4a12009-09-21 20:12:40 +00001732 unsigned NextRank = CollectMemberLookupResults(Ctx, 0, Ctx, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001733
1734 // The "template" keyword can follow "::" in the grammar, but only
1735 // put it into the grammar if the nested-name-specifier is dependent.
1736 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
1737 if (!Results.empty() && NNS->isDependent())
1738 Results.MaybeAddResult(CodeCompleteConsumer::Result("template", NextRank));
1739
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001740 if (CodeCompleter->includeMacros())
1741 AddMacroResults(PP, NextRank + 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001742 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00001743}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001744
1745void Sema::CodeCompleteUsing(Scope *S) {
1746 if (!CodeCompleter)
1747 return;
1748
Douglas Gregor86d9a522009-09-21 16:56:56 +00001749 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001750 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001751
1752 // If we aren't in class scope, we could see the "namespace" keyword.
1753 if (!S->isClassScope())
1754 Results.MaybeAddResult(CodeCompleteConsumer::Result("namespace", 0));
1755
1756 // After "using", we can see anything that would start a
1757 // nested-name-specifier.
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001758 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1759 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001760 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001761
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001762 if (CodeCompleter->includeMacros())
1763 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001764 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001765}
1766
1767void Sema::CodeCompleteUsingDirective(Scope *S) {
1768 if (!CodeCompleter)
1769 return;
1770
Douglas Gregor86d9a522009-09-21 16:56:56 +00001771 // After "using namespace", we expect to see a namespace name or namespace
1772 // alias.
1773 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001774 Results.EnterNewScope();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001775 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1776 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001777 Results.ExitScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001778 if (CodeCompleter->includeMacros())
1779 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001780 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001781}
1782
1783void Sema::CodeCompleteNamespaceDecl(Scope *S) {
1784 if (!CodeCompleter)
1785 return;
1786
Douglas Gregor86d9a522009-09-21 16:56:56 +00001787 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
1788 DeclContext *Ctx = (DeclContext *)S->getEntity();
1789 if (!S->getParent())
1790 Ctx = Context.getTranslationUnitDecl();
1791
1792 if (Ctx && Ctx->isFileContext()) {
1793 // We only want to see those namespaces that have already been defined
1794 // within this scope, because its likely that the user is creating an
1795 // extended namespace declaration. Keep track of the most recent
1796 // definition of each namespace.
1797 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
1798 for (DeclContext::specific_decl_iterator<NamespaceDecl>
1799 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
1800 NS != NSEnd; ++NS)
1801 OrigToLatest[NS->getOriginalNamespace()] = *NS;
1802
1803 // Add the most recent definition (or extended definition) of each
1804 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001805 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001806 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
1807 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
1808 NS != NSEnd; ++NS)
Douglas Gregor456c4a12009-09-21 20:12:40 +00001809 Results.MaybeAddResult(CodeCompleteConsumer::Result(NS->second, 0),
1810 CurContext);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001811 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001812 }
1813
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001814 if (CodeCompleter->includeMacros())
1815 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001816 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001817}
1818
1819void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
1820 if (!CodeCompleter)
1821 return;
1822
Douglas Gregor86d9a522009-09-21 16:56:56 +00001823 // After "namespace", we expect to see a namespace or alias.
1824 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001825 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1826 0, CurContext, Results);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001827 if (CodeCompleter->includeMacros())
1828 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001829 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001830}
1831
Douglas Gregored8d3222009-09-18 20:05:18 +00001832void Sema::CodeCompleteOperatorName(Scope *S) {
1833 if (!CodeCompleter)
1834 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001835
1836 typedef CodeCompleteConsumer::Result Result;
1837 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001838 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00001839
Douglas Gregor86d9a522009-09-21 16:56:56 +00001840 // Add the names of overloadable operators.
1841#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1842 if (std::strcmp(Spelling, "?")) \
1843 Results.MaybeAddResult(Result(Spelling, 0));
1844#include "clang/Basic/OperatorKinds.def"
1845
1846 // Add any type names visible from the current scope
1847 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00001848 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001849
1850 // Add any type specifiers
1851 AddTypeSpecifierResults(getLangOptions(), 0, Results);
1852
1853 // Add any nested-name-specifiers
1854 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001855 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1856 NextRank + 1, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001857 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001858
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001859 if (CodeCompleter->includeMacros())
1860 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001861 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00001862}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001863
Douglas Gregorc464ae82009-12-07 09:27:33 +00001864void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
1865 bool InInterface) {
1866 typedef CodeCompleteConsumer::Result Result;
1867 ResultBuilder Results(*this);
1868 Results.EnterNewScope();
1869 if (ObjCImpDecl) {
1870 // Since we have an implementation, we can end it.
1871 Results.MaybeAddResult(Result("end", 0));
1872
1873 CodeCompletionString *Pattern = 0;
1874 Decl *ImpDecl = ObjCImpDecl.getAs<Decl>();
1875 if (isa<ObjCImplementationDecl>(ImpDecl) ||
1876 isa<ObjCCategoryImplDecl>(ImpDecl)) {
1877 // @dynamic
1878 Pattern = new CodeCompletionString;
1879 Pattern->AddTypedTextChunk("dynamic");
1880 Pattern->AddTextChunk(" ");
1881 Pattern->AddPlaceholderChunk("property");
1882 Results.MaybeAddResult(Result(Pattern, 0));
1883
1884 // @synthesize
1885 Pattern = new CodeCompletionString;
1886 Pattern->AddTypedTextChunk("synthesize");
1887 Pattern->AddTextChunk(" ");
1888 Pattern->AddPlaceholderChunk("property");
1889 Results.MaybeAddResult(Result(Pattern, 0));
1890 }
1891 } else if (InInterface) {
1892 // Since we have an interface or protocol, we can end it.
1893 Results.MaybeAddResult(Result("end", 0));
1894
1895 if (LangOpts.ObjC2) {
1896 // @property
1897 Results.MaybeAddResult(Result("property", 0));
1898 }
1899
1900 // @required
1901 Results.MaybeAddResult(Result("required", 0));
1902
1903 // @optional
1904 Results.MaybeAddResult(Result("optional", 0));
1905 } else {
1906 CodeCompletionString *Pattern = 0;
1907
1908 // @class name ;
1909 Pattern = new CodeCompletionString;
1910 Pattern->AddTypedTextChunk("class");
1911 Pattern->AddTextChunk(" ");
1912 Pattern->AddPlaceholderChunk("identifier");
1913 Pattern->AddTextChunk(";"); // add ';' chunk
1914 Results.MaybeAddResult(Result(Pattern, 0));
1915
1916 // @interface name
1917 // FIXME: Could introduce the whole pattern, including superclasses and
1918 // such.
1919 Pattern = new CodeCompletionString;
1920 Pattern->AddTypedTextChunk("interface");
1921 Pattern->AddTextChunk(" ");
1922 Pattern->AddPlaceholderChunk("class");
1923 Results.MaybeAddResult(Result(Pattern, 0));
1924
1925 // @protocol name
1926 Pattern = new CodeCompletionString;
1927 Pattern->AddTypedTextChunk("protocol");
1928 Pattern->AddTextChunk(" ");
1929 Pattern->AddPlaceholderChunk("protocol");
1930 Results.MaybeAddResult(Result(Pattern, 0));
1931
1932 // @implementation name
1933 Pattern = new CodeCompletionString;
1934 Pattern->AddTypedTextChunk("implementation");
1935 Pattern->AddTextChunk(" ");
1936 Pattern->AddPlaceholderChunk("class");
1937 Results.MaybeAddResult(Result(Pattern, 0));
1938
1939 // @compatibility_alias name
1940 Pattern = new CodeCompletionString;
1941 Pattern->AddTypedTextChunk("compatibility_alias");
1942 Pattern->AddTextChunk(" ");
1943 Pattern->AddPlaceholderChunk("alias");
1944 Pattern->AddTextChunk(" ");
1945 Pattern->AddPlaceholderChunk("class");
1946 Results.MaybeAddResult(Result(Pattern, 0));
1947 }
1948 Results.ExitScope();
1949 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
1950}
1951
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00001952static void AddObjCExpressionResults(unsigned Rank, ResultBuilder &Results) {
1953 typedef CodeCompleteConsumer::Result Result;
1954 CodeCompletionString *Pattern = 0;
1955
1956 // @encode ( type-name )
1957 Pattern = new CodeCompletionString;
1958 Pattern->AddTypedTextChunk("encode");
1959 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1960 Pattern->AddPlaceholderChunk("type-name");
1961 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1962 Results.MaybeAddResult(Result(Pattern, Rank));
1963
1964 // @protocol ( protocol-name )
1965 Pattern = new CodeCompletionString;
1966 Pattern->AddTypedTextChunk("protocol");
1967 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1968 Pattern->AddPlaceholderChunk("protocol-name");
1969 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1970 Results.MaybeAddResult(Result(Pattern, Rank));
1971
1972 // @selector ( selector )
1973 Pattern = new CodeCompletionString;
1974 Pattern->AddTypedTextChunk("selector");
1975 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1976 Pattern->AddPlaceholderChunk("selector");
1977 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1978 Results.MaybeAddResult(Result(Pattern, Rank));
1979}
1980
1981void Sema::CodeCompleteObjCAtStatement(Scope *S) {
1982 typedef CodeCompleteConsumer::Result Result;
1983 ResultBuilder Results(*this);
1984 Results.EnterNewScope();
1985
1986 CodeCompletionString *Pattern = 0;
1987
1988 // @try { statements } @catch ( declaration ) { statements } @finally
1989 // { statements }
1990 Pattern = new CodeCompletionString;
1991 Pattern->AddTypedTextChunk("try");
1992 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1993 Pattern->AddPlaceholderChunk("statements");
1994 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1995 Pattern->AddTextChunk("@catch");
1996 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1997 Pattern->AddPlaceholderChunk("parameter");
1998 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1999 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2000 Pattern->AddPlaceholderChunk("statements");
2001 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2002 Pattern->AddTextChunk("@finally");
2003 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2004 Pattern->AddPlaceholderChunk("statements");
2005 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2006 Results.MaybeAddResult(Result(Pattern, 0));
2007
2008 // @throw
2009 Pattern = new CodeCompletionString;
2010 Pattern->AddTypedTextChunk("throw");
2011 Pattern->AddTextChunk(" ");
2012 Pattern->AddPlaceholderChunk("expression");
2013 Pattern->AddTextChunk(";");
2014 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2015
2016 // @synchronized ( expression ) { statements }
2017 Pattern = new CodeCompletionString;
2018 Pattern->AddTypedTextChunk("synchronized");
2019 Pattern->AddTextChunk(" ");
2020 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2021 Pattern->AddPlaceholderChunk("expression");
2022 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2023 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2024 Pattern->AddPlaceholderChunk("statements");
2025 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2026 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2027
2028 AddObjCExpressionResults(0, Results);
2029 Results.ExitScope();
2030 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2031}
2032
2033void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2034 ResultBuilder Results(*this);
2035 Results.EnterNewScope();
2036 AddObjCExpressionResults(0, Results);
2037 Results.ExitScope();
2038 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2039}
2040
Douglas Gregor988358f2009-11-19 00:14:45 +00002041/// \brief Determine whether the addition of the given flag to an Objective-C
2042/// property's attributes will cause a conflict.
2043static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2044 // Check if we've already added this flag.
2045 if (Attributes & NewFlag)
2046 return true;
2047
2048 Attributes |= NewFlag;
2049
2050 // Check for collisions with "readonly".
2051 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2052 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2053 ObjCDeclSpec::DQ_PR_assign |
2054 ObjCDeclSpec::DQ_PR_copy |
2055 ObjCDeclSpec::DQ_PR_retain)))
2056 return true;
2057
2058 // Check for more than one of { assign, copy, retain }.
2059 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2060 ObjCDeclSpec::DQ_PR_copy |
2061 ObjCDeclSpec::DQ_PR_retain);
2062 if (AssignCopyRetMask &&
2063 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2064 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2065 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2066 return true;
2067
2068 return false;
2069}
2070
Douglas Gregora93b1082009-11-18 23:08:07 +00002071void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00002072 if (!CodeCompleter)
2073 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00002074
Steve Naroffece8e712009-10-08 21:55:05 +00002075 unsigned Attributes = ODS.getPropertyAttributes();
2076
2077 typedef CodeCompleteConsumer::Result Result;
2078 ResultBuilder Results(*this);
2079 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00002080 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Steve Naroffece8e712009-10-08 21:55:05 +00002081 Results.MaybeAddResult(CodeCompleteConsumer::Result("readonly", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002082 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Steve Naroffece8e712009-10-08 21:55:05 +00002083 Results.MaybeAddResult(CodeCompleteConsumer::Result("assign", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002084 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Steve Naroffece8e712009-10-08 21:55:05 +00002085 Results.MaybeAddResult(CodeCompleteConsumer::Result("readwrite", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002086 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Steve Naroffece8e712009-10-08 21:55:05 +00002087 Results.MaybeAddResult(CodeCompleteConsumer::Result("retain", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002088 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Steve Naroffece8e712009-10-08 21:55:05 +00002089 Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002090 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Steve Naroffece8e712009-10-08 21:55:05 +00002091 Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002092 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002093 CodeCompletionString *Setter = new CodeCompletionString;
2094 Setter->AddTypedTextChunk("setter");
2095 Setter->AddTextChunk(" = ");
2096 Setter->AddPlaceholderChunk("method");
2097 Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
2098 }
Douglas Gregor988358f2009-11-19 00:14:45 +00002099 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002100 CodeCompletionString *Getter = new CodeCompletionString;
2101 Getter->AddTypedTextChunk("getter");
2102 Getter->AddTextChunk(" = ");
2103 Getter->AddPlaceholderChunk("method");
2104 Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
2105 }
Steve Naroffece8e712009-10-08 21:55:05 +00002106 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002107 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00002108}
Steve Naroffc4df6d22009-11-07 02:08:14 +00002109
Douglas Gregor4ad96852009-11-19 07:41:15 +00002110/// \brief Descripts the kind of Objective-C method that we want to find
2111/// via code completion.
2112enum ObjCMethodKind {
2113 MK_Any, //< Any kind of method, provided it means other specified criteria.
2114 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2115 MK_OneArgSelector //< One-argument selector.
2116};
2117
2118static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2119 ObjCMethodKind WantKind,
2120 IdentifierInfo **SelIdents,
2121 unsigned NumSelIdents) {
2122 Selector Sel = Method->getSelector();
2123 if (NumSelIdents > Sel.getNumArgs())
2124 return false;
2125
2126 switch (WantKind) {
2127 case MK_Any: break;
2128 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2129 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2130 }
2131
2132 for (unsigned I = 0; I != NumSelIdents; ++I)
2133 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2134 return false;
2135
2136 return true;
2137}
2138
Douglas Gregor36ecb042009-11-17 23:22:23 +00002139/// \brief Add all of the Objective-C methods in the given Objective-C
2140/// container to the set of results.
2141///
2142/// The container will be a class, protocol, category, or implementation of
2143/// any of the above. This mether will recurse to include methods from
2144/// the superclasses of classes along with their categories, protocols, and
2145/// implementations.
2146///
2147/// \param Container the container in which we'll look to find methods.
2148///
2149/// \param WantInstance whether to add instance methods (only); if false, this
2150/// routine will add factory methods (only).
2151///
2152/// \param CurContext the context in which we're performing the lookup that
2153/// finds methods.
2154///
2155/// \param Results the structure into which we'll add results.
2156static void AddObjCMethods(ObjCContainerDecl *Container,
2157 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00002158 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00002159 IdentifierInfo **SelIdents,
2160 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00002161 DeclContext *CurContext,
2162 ResultBuilder &Results) {
2163 typedef CodeCompleteConsumer::Result Result;
2164 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2165 MEnd = Container->meth_end();
2166 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002167 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2168 // Check whether the selector identifiers we've been given are a
2169 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002170 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00002171 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002172
Douglas Gregord3c68542009-11-19 01:08:35 +00002173 Result R = Result(*M, 0);
2174 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002175 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00002176 Results.MaybeAddResult(R, CurContext);
2177 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00002178 }
2179
2180 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2181 if (!IFace)
2182 return;
2183
2184 // Add methods in protocols.
2185 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2186 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2187 E = Protocols.end();
2188 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002189 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00002190 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002191
2192 // Add methods in categories.
2193 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2194 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00002195 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2196 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002197
2198 // Add a categories protocol methods.
2199 const ObjCList<ObjCProtocolDecl> &Protocols
2200 = CatDecl->getReferencedProtocols();
2201 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2202 E = Protocols.end();
2203 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002204 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2205 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002206
2207 // Add methods in category implementations.
2208 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002209 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2210 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002211 }
2212
2213 // Add methods in superclass.
2214 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002215 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2216 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002217
2218 // Add methods in our implementation, if any.
2219 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002220 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2221 NumSelIdents, CurContext, Results);
2222}
2223
2224
2225void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2226 DeclPtrTy *Methods,
2227 unsigned NumMethods) {
2228 typedef CodeCompleteConsumer::Result Result;
2229
2230 // Try to find the interface where getters might live.
2231 ObjCInterfaceDecl *Class
2232 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2233 if (!Class) {
2234 if (ObjCCategoryDecl *Category
2235 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2236 Class = Category->getClassInterface();
2237
2238 if (!Class)
2239 return;
2240 }
2241
2242 // Find all of the potential getters.
2243 ResultBuilder Results(*this);
2244 Results.EnterNewScope();
2245
2246 // FIXME: We need to do this because Objective-C methods don't get
2247 // pushed into DeclContexts early enough. Argh!
2248 for (unsigned I = 0; I != NumMethods; ++I) {
2249 if (ObjCMethodDecl *Method
2250 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2251 if (Method->isInstanceMethod() &&
2252 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2253 Result R = Result(Method, 0);
2254 R.AllParametersAreInformative = true;
2255 Results.MaybeAddResult(R, CurContext);
2256 }
2257 }
2258
2259 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2260 Results.ExitScope();
2261 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2262}
2263
2264void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2265 DeclPtrTy *Methods,
2266 unsigned NumMethods) {
2267 typedef CodeCompleteConsumer::Result Result;
2268
2269 // Try to find the interface where setters might live.
2270 ObjCInterfaceDecl *Class
2271 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2272 if (!Class) {
2273 if (ObjCCategoryDecl *Category
2274 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2275 Class = Category->getClassInterface();
2276
2277 if (!Class)
2278 return;
2279 }
2280
2281 // Find all of the potential getters.
2282 ResultBuilder Results(*this);
2283 Results.EnterNewScope();
2284
2285 // FIXME: We need to do this because Objective-C methods don't get
2286 // pushed into DeclContexts early enough. Argh!
2287 for (unsigned I = 0; I != NumMethods; ++I) {
2288 if (ObjCMethodDecl *Method
2289 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2290 if (Method->isInstanceMethod() &&
2291 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2292 Result R = Result(Method, 0);
2293 R.AllParametersAreInformative = true;
2294 Results.MaybeAddResult(R, CurContext);
2295 }
2296 }
2297
2298 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2299
2300 Results.ExitScope();
2301 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00002302}
2303
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002304void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregord3c68542009-11-19 01:08:35 +00002305 SourceLocation FNameLoc,
2306 IdentifierInfo **SelIdents,
2307 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002308 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00002309 ObjCInterfaceDecl *CDecl = 0;
2310
Douglas Gregor24a069f2009-11-17 17:59:40 +00002311 if (FName->isStr("super")) {
2312 // We're sending a message to "super".
2313 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2314 // Figure out which interface we're in.
2315 CDecl = CurMethod->getClassInterface();
2316 if (!CDecl)
2317 return;
2318
2319 // Find the superclass of this class.
2320 CDecl = CDecl->getSuperClass();
2321 if (!CDecl)
2322 return;
2323
2324 if (CurMethod->isInstanceMethod()) {
2325 // We are inside an instance method, which means that the message
2326 // send [super ...] is actually calling an instance method on the
2327 // current object. Build the super expression and handle this like
2328 // an instance method.
2329 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2330 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2331 OwningExprResult Super
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002332 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregord3c68542009-11-19 01:08:35 +00002333 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2334 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002335 }
2336
2337 // Okay, we're calling a factory method in our superclass.
2338 }
2339 }
2340
2341 // If the given name refers to an interface type, retrieve the
2342 // corresponding declaration.
2343 if (!CDecl)
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002344 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor24a069f2009-11-17 17:59:40 +00002345 QualType T = GetTypeFromParser(Ty, 0);
2346 if (!T.isNull())
2347 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
2348 CDecl = Interface->getDecl();
2349 }
2350
2351 if (!CDecl && FName->isStr("super")) {
2352 // "super" may be the name of a variable, in which case we are
2353 // probably calling an instance method.
John McCallf7a1a742009-11-24 19:00:30 +00002354 CXXScopeSpec SS;
2355 UnqualifiedId id;
2356 id.setIdentifier(FName, FNameLoc);
2357 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregord3c68542009-11-19 01:08:35 +00002358 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2359 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002360 }
2361
Douglas Gregor36ecb042009-11-17 23:22:23 +00002362 // Add all of the factory methods in this Objective-C class, its protocols,
2363 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00002364 ResultBuilder Results(*this);
2365 Results.EnterNewScope();
Douglas Gregor4ad96852009-11-19 07:41:15 +00002366 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
2367 Results);
Steve Naroffc4df6d22009-11-07 02:08:14 +00002368 Results.ExitScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00002369
Steve Naroffc4df6d22009-11-07 02:08:14 +00002370 // This also suppresses remaining diagnostics.
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002371 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00002372}
2373
Douglas Gregord3c68542009-11-19 01:08:35 +00002374void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
2375 IdentifierInfo **SelIdents,
2376 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002377 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00002378
2379 Expr *RecExpr = static_cast<Expr *>(Receiver);
2380 QualType RecType = RecExpr->getType();
2381
Douglas Gregor36ecb042009-11-17 23:22:23 +00002382 // If necessary, apply function/array conversion to the receiver.
2383 // C99 6.7.5.3p[7,8].
2384 DefaultFunctionArrayConversion(RecExpr);
2385 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00002386
Douglas Gregor36ecb042009-11-17 23:22:23 +00002387 if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType()) {
2388 // FIXME: We're messaging 'id'. Do we actually want to look up every method
2389 // in the universe?
2390 return;
2391 }
2392
Douglas Gregor36ecb042009-11-17 23:22:23 +00002393 // Build the set of methods we can see.
2394 ResultBuilder Results(*this);
2395 Results.EnterNewScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00002396
Douglas Gregorf74a4192009-11-18 00:06:18 +00002397 // Handle messages to Class. This really isn't a message to an instance
2398 // method, so we treat it the same way we would treat a message send to a
2399 // class method.
2400 if (ReceiverType->isObjCClassType() ||
2401 ReceiverType->isObjCQualifiedClassType()) {
2402 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2403 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002404 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
2405 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002406 }
2407 }
2408 // Handle messages to a qualified ID ("id<foo>").
2409 else if (const ObjCObjectPointerType *QualID
2410 = ReceiverType->getAsObjCQualifiedIdType()) {
2411 // Search protocols for instance methods.
2412 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
2413 E = QualID->qual_end();
2414 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002415 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2416 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002417 }
2418 // Handle messages to a pointer to interface type.
2419 else if (const ObjCObjectPointerType *IFacePtr
2420 = ReceiverType->getAsObjCInterfacePointerType()) {
2421 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002422 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
2423 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002424
2425 // Search protocols for instance methods.
2426 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
2427 E = IFacePtr->qual_end();
2428 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002429 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2430 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002431 }
2432
Steve Naroffc4df6d22009-11-07 02:08:14 +00002433 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002434 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00002435}
Douglas Gregor55385fe2009-11-18 04:19:12 +00002436
2437/// \brief Add all of the protocol declarations that we find in the given
2438/// (translation unit) context.
2439static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00002440 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00002441 ResultBuilder &Results) {
2442 typedef CodeCompleteConsumer::Result Result;
2443
2444 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2445 DEnd = Ctx->decls_end();
2446 D != DEnd; ++D) {
2447 // Record any protocols we find.
2448 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00002449 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
2450 Results.MaybeAddResult(Result(Proto, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002451
2452 // Record any forward-declared protocols we find.
2453 if (ObjCForwardProtocolDecl *Forward
2454 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
2455 for (ObjCForwardProtocolDecl::protocol_iterator
2456 P = Forward->protocol_begin(),
2457 PEnd = Forward->protocol_end();
2458 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00002459 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
2460 Results.MaybeAddResult(Result(*P, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002461 }
2462 }
2463}
2464
2465void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
2466 unsigned NumProtocols) {
2467 ResultBuilder Results(*this);
2468 Results.EnterNewScope();
2469
2470 // Tell the result set to ignore all of the protocols we have
2471 // already seen.
2472 for (unsigned I = 0; I != NumProtocols; ++I)
2473 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
2474 Results.Ignore(Protocol);
2475
2476 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00002477 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
2478 Results);
2479
2480 Results.ExitScope();
2481 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2482}
2483
2484void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
2485 ResultBuilder Results(*this);
2486 Results.EnterNewScope();
2487
2488 // Add all protocols.
2489 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
2490 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002491
2492 Results.ExitScope();
2493 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2494}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00002495
2496/// \brief Add all of the Objective-C interface declarations that we find in
2497/// the given (translation unit) context.
2498static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
2499 bool OnlyForwardDeclarations,
2500 bool OnlyUnimplemented,
2501 ResultBuilder &Results) {
2502 typedef CodeCompleteConsumer::Result Result;
2503
2504 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2505 DEnd = Ctx->decls_end();
2506 D != DEnd; ++D) {
2507 // Record any interfaces we find.
2508 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
2509 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
2510 (!OnlyUnimplemented || !Class->getImplementation()))
2511 Results.MaybeAddResult(Result(Class, 0), CurContext);
2512
2513 // Record any forward-declared interfaces we find.
2514 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
2515 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
2516 C != CEnd; ++C)
2517 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
2518 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
2519 Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
2520 }
2521 }
2522}
2523
2524void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
2525 ResultBuilder Results(*this);
2526 Results.EnterNewScope();
2527
2528 // Add all classes.
2529 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
2530 false, Results);
2531
2532 Results.ExitScope();
2533 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2534}
2535
2536void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
2537 ResultBuilder Results(*this);
2538 Results.EnterNewScope();
2539
2540 // Make sure that we ignore the class we're currently defining.
2541 NamedDecl *CurClass
2542 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00002543 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00002544 Results.Ignore(CurClass);
2545
2546 // Add all classes.
2547 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2548 false, Results);
2549
2550 Results.ExitScope();
2551 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2552}
2553
2554void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
2555 ResultBuilder Results(*this);
2556 Results.EnterNewScope();
2557
2558 // Add all unimplemented classes.
2559 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2560 true, Results);
2561
2562 Results.ExitScope();
2563 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2564}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00002565
2566void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
2567 IdentifierInfo *ClassName) {
2568 typedef CodeCompleteConsumer::Result Result;
2569
2570 ResultBuilder Results(*this);
2571
2572 // Ignore any categories we find that have already been implemented by this
2573 // interface.
2574 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2575 NamedDecl *CurClass
2576 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2577 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
2578 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2579 Category = Category->getNextClassCategory())
2580 CategoryNames.insert(Category->getIdentifier());
2581
2582 // Add all of the categories we know about.
2583 Results.EnterNewScope();
2584 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
2585 for (DeclContext::decl_iterator D = TU->decls_begin(),
2586 DEnd = TU->decls_end();
2587 D != DEnd; ++D)
2588 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
2589 if (CategoryNames.insert(Category->getIdentifier()))
2590 Results.MaybeAddResult(Result(Category, 0), CurContext);
2591 Results.ExitScope();
2592
2593 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2594}
2595
2596void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
2597 IdentifierInfo *ClassName) {
2598 typedef CodeCompleteConsumer::Result Result;
2599
2600 // Find the corresponding interface. If we couldn't find the interface, the
2601 // program itself is ill-formed. However, we'll try to be helpful still by
2602 // providing the list of all of the categories we know about.
2603 NamedDecl *CurClass
2604 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2605 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
2606 if (!Class)
2607 return CodeCompleteObjCInterfaceCategory(S, ClassName);
2608
2609 ResultBuilder Results(*this);
2610
2611 // Add all of the categories that have have corresponding interface
2612 // declarations in this class and any of its superclasses, except for
2613 // already-implemented categories in the class itself.
2614 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2615 Results.EnterNewScope();
2616 bool IgnoreImplemented = true;
2617 while (Class) {
2618 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2619 Category = Category->getNextClassCategory())
2620 if ((!IgnoreImplemented || !Category->getImplementation()) &&
2621 CategoryNames.insert(Category->getIdentifier()))
2622 Results.MaybeAddResult(Result(Category, 0), CurContext);
2623
2624 Class = Class->getSuperClass();
2625 IgnoreImplemented = false;
2626 }
2627 Results.ExitScope();
2628
2629 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2630}
Douglas Gregor322328b2009-11-18 22:32:06 +00002631
Douglas Gregor424b2a52009-11-18 22:56:13 +00002632void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00002633 typedef CodeCompleteConsumer::Result Result;
2634 ResultBuilder Results(*this);
2635
2636 // Figure out where this @synthesize lives.
2637 ObjCContainerDecl *Container
2638 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2639 if (!Container ||
2640 (!isa<ObjCImplementationDecl>(Container) &&
2641 !isa<ObjCCategoryImplDecl>(Container)))
2642 return;
2643
2644 // Ignore any properties that have already been implemented.
2645 for (DeclContext::decl_iterator D = Container->decls_begin(),
2646 DEnd = Container->decls_end();
2647 D != DEnd; ++D)
2648 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
2649 Results.Ignore(PropertyImpl->getPropertyDecl());
2650
2651 // Add any properties that we find.
2652 Results.EnterNewScope();
2653 if (ObjCImplementationDecl *ClassImpl
2654 = dyn_cast<ObjCImplementationDecl>(Container))
2655 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
2656 Results);
2657 else
2658 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
2659 false, CurContext, Results);
2660 Results.ExitScope();
2661
2662 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2663}
2664
2665void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
2666 IdentifierInfo *PropertyName,
2667 DeclPtrTy ObjCImpDecl) {
2668 typedef CodeCompleteConsumer::Result Result;
2669 ResultBuilder Results(*this);
2670
2671 // Figure out where this @synthesize lives.
2672 ObjCContainerDecl *Container
2673 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2674 if (!Container ||
2675 (!isa<ObjCImplementationDecl>(Container) &&
2676 !isa<ObjCCategoryImplDecl>(Container)))
2677 return;
2678
2679 // Figure out which interface we're looking into.
2680 ObjCInterfaceDecl *Class = 0;
2681 if (ObjCImplementationDecl *ClassImpl
2682 = dyn_cast<ObjCImplementationDecl>(Container))
2683 Class = ClassImpl->getClassInterface();
2684 else
2685 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
2686 ->getClassInterface();
2687
2688 // Add all of the instance variables in this class and its superclasses.
2689 Results.EnterNewScope();
2690 for(; Class; Class = Class->getSuperClass()) {
2691 // FIXME: We could screen the type of each ivar for compatibility with
2692 // the property, but is that being too paternal?
2693 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
2694 IVarEnd = Class->ivar_end();
2695 IVar != IVarEnd; ++IVar)
2696 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
2697 }
2698 Results.ExitScope();
2699
2700 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2701}