blob: 63c8bdcc6c20bfd9c9b2c577422cad8ea1cda8d8 [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;
Douglas Gregore29ffaa2009-12-11 16:18:54 +0000366
367 // Class template (partial) specializations are never added as results
368 if (isa<ClassTemplateSpecializationDecl>(CanonDecl) ||
369 isa<ClassTemplatePartialSpecializationDecl>(CanonDecl))
370 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000371
372 if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) {
373 // __va_list_tag is a freak of nature. Find it and skip it.
374 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
375 return;
376
Douglas Gregorf52cede2009-10-09 22:16:47 +0000377 // Filter out names reserved for the implementation (C99 7.1.3,
378 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbare013d682009-10-18 20:26:12 +0000379 //
380 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000381 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000382 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000383 if (Name[0] == '_' &&
384 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
385 return;
386 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000387 }
388
389 // C++ constructors are never found by name lookup.
390 if (isa<CXXConstructorDecl>(CanonDecl))
391 return;
392
393 // Filter out any unwanted results.
394 if (Filter && !(this->*Filter)(R.Declaration))
395 return;
396
397 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000398 ShadowMapEntry::iterator I, IEnd;
399 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
400 if (NamePos != SMap.end()) {
401 I = NamePos->second.begin();
402 IEnd = NamePos->second.end();
403 }
404
405 for (; I != IEnd; ++I) {
406 NamedDecl *ND = I->first;
407 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000408 if (ND->getCanonicalDecl() == CanonDecl) {
409 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000410 Results[Index].Declaration = R.Declaration;
411
412 // Pick the best rank of the two.
413 Results[Index].Rank = std::min(Results[Index].Rank, R.Rank);
414
415 // We're done.
416 return;
417 }
418 }
419
420 // This is a new declaration in this scope. However, check whether this
421 // declaration name is hidden by a similarly-named declaration in an outer
422 // scope.
423 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
424 --SMEnd;
425 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000426 ShadowMapEntry::iterator I, IEnd;
427 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
428 if (NamePos != SM->end()) {
429 I = NamePos->second.begin();
430 IEnd = NamePos->second.end();
431 }
432 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000433 // A tag declaration does not hide a non-tag declaration.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000434 if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000435 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
436 Decl::IDNS_ObjCProtocol)))
437 continue;
438
439 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000440 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000441 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000442 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000443 continue;
444
445 // The newly-added result is hidden by an entry in the shadow map.
446 if (canHiddenResultBeFound(SemaRef.getLangOptions(), R.Declaration,
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000447 I->first)) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000448 // Note that this result was hidden.
449 R.Hidden = true;
Douglas Gregor0563c262009-09-22 23:15:58 +0000450 R.QualifierIsInformative = false;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000451
452 if (!R.Qualifier)
453 R.Qualifier = getRequiredQualification(SemaRef.Context,
454 CurContext,
455 R.Declaration->getDeclContext());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000456 } else {
457 // This result was hidden and cannot be found; don't bother adding
458 // it.
459 return;
460 }
461
462 break;
463 }
464 }
465
466 // Make sure that any given declaration only shows up in the result set once.
467 if (!AllDeclsFound.insert(CanonDecl))
468 return;
469
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000470 // If the filter is for nested-name-specifiers, then this result starts a
471 // nested-name-specifier.
472 if ((Filter == &ResultBuilder::IsNestedNameSpecifier) ||
473 (Filter == &ResultBuilder::IsMember &&
474 isa<CXXRecordDecl>(R.Declaration) &&
475 cast<CXXRecordDecl>(R.Declaration)->isInjectedClassName()))
476 R.StartsNestedNameSpecifier = true;
477
Douglas Gregor0563c262009-09-22 23:15:58 +0000478 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000479 if (R.QualifierIsInformative && !R.Qualifier &&
480 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000481 DeclContext *Ctx = R.Declaration->getDeclContext();
482 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
483 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
484 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
485 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
486 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
487 else
488 R.QualifierIsInformative = false;
489 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000490
Douglas Gregor86d9a522009-09-21 16:56:56 +0000491 // Insert this result into the set of results and into the current shadow
492 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000493 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000494 Results.push_back(R);
495}
496
497/// \brief Enter into a new scope.
498void ResultBuilder::EnterNewScope() {
499 ShadowMaps.push_back(ShadowMap());
500}
501
502/// \brief Exit from the current scope.
503void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000504 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
505 EEnd = ShadowMaps.back().end();
506 E != EEnd;
507 ++E)
508 E->second.Destroy();
509
Douglas Gregor86d9a522009-09-21 16:56:56 +0000510 ShadowMaps.pop_back();
511}
512
Douglas Gregor791215b2009-09-21 20:51:25 +0000513/// \brief Determines whether this given declaration will be found by
514/// ordinary name lookup.
515bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
516 unsigned IDNS = Decl::IDNS_Ordinary;
517 if (SemaRef.getLangOptions().CPlusPlus)
518 IDNS |= Decl::IDNS_Tag;
519
520 return ND->getIdentifierNamespace() & IDNS;
521}
522
Douglas Gregor86d9a522009-09-21 16:56:56 +0000523/// \brief Determines whether the given declaration is suitable as the
524/// start of a C++ nested-name-specifier, e.g., a class or namespace.
525bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
526 // Allow us to find class templates, too.
527 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
528 ND = ClassTemplate->getTemplatedDecl();
529
530 return SemaRef.isAcceptableNestedNameSpecifier(ND);
531}
532
533/// \brief Determines whether the given declaration is an enumeration.
534bool ResultBuilder::IsEnum(NamedDecl *ND) const {
535 return isa<EnumDecl>(ND);
536}
537
538/// \brief Determines whether the given declaration is a class or struct.
539bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
540 // Allow us to find class templates, too.
541 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
542 ND = ClassTemplate->getTemplatedDecl();
543
544 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
545 return RD->getTagKind() == TagDecl::TK_class ||
546 RD->getTagKind() == TagDecl::TK_struct;
547
548 return false;
549}
550
551/// \brief Determines whether the given declaration is a union.
552bool ResultBuilder::IsUnion(NamedDecl *ND) const {
553 // Allow us to find class templates, too.
554 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
555 ND = ClassTemplate->getTemplatedDecl();
556
557 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
558 return RD->getTagKind() == TagDecl::TK_union;
559
560 return false;
561}
562
563/// \brief Determines whether the given declaration is a namespace.
564bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
565 return isa<NamespaceDecl>(ND);
566}
567
568/// \brief Determines whether the given declaration is a namespace or
569/// namespace alias.
570bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
571 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
572}
573
574/// \brief Brief determines whether the given declaration is a namespace or
575/// namespace alias.
576bool ResultBuilder::IsType(NamedDecl *ND) const {
577 return isa<TypeDecl>(ND);
578}
579
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000580/// \brief Since every declaration found within a class is a member that we
581/// care about, always returns true. This predicate exists mostly to
582/// communicate to the result builder that we are performing a lookup for
583/// member access.
584bool ResultBuilder::IsMember(NamedDecl *ND) const {
585 return true;
586}
587
Douglas Gregor86d9a522009-09-21 16:56:56 +0000588// Find the next outer declaration context corresponding to this scope.
589static DeclContext *findOuterContext(Scope *S) {
590 for (S = S->getParent(); S; S = S->getParent())
591 if (S->getEntity())
592 return static_cast<DeclContext *>(S->getEntity())->getPrimaryContext();
593
594 return 0;
595}
596
597/// \brief Collect the results of searching for members within the given
598/// declaration context.
599///
600/// \param Ctx the declaration context from which we will gather results.
601///
Douglas Gregor0563c262009-09-22 23:15:58 +0000602/// \param Rank the rank given to results in this declaration context.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000603///
604/// \param Visited the set of declaration contexts that have already been
605/// visited. Declaration contexts will only be visited once.
606///
607/// \param Results the result set that will be extended with any results
608/// found within this declaration context (and, for a C++ class, its bases).
609///
Douglas Gregor0563c262009-09-22 23:15:58 +0000610/// \param InBaseClass whether we are in a base class.
611///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000612/// \returns the next higher rank value, after considering all of the
613/// names within this declaration context.
614static unsigned CollectMemberLookupResults(DeclContext *Ctx,
Douglas Gregor0563c262009-09-22 23:15:58 +0000615 unsigned Rank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000616 DeclContext *CurContext,
617 llvm::SmallPtrSet<DeclContext *, 16> &Visited,
Douglas Gregor0563c262009-09-22 23:15:58 +0000618 ResultBuilder &Results,
619 bool InBaseClass = false) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000620 // Make sure we don't visit the same context twice.
621 if (!Visited.insert(Ctx->getPrimaryContext()))
Douglas Gregor0563c262009-09-22 23:15:58 +0000622 return Rank;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000623
624 // Enumerate all of the results in this context.
Douglas Gregor0563c262009-09-22 23:15:58 +0000625 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000626 Results.EnterNewScope();
627 for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
628 CurCtx = CurCtx->getNextContext()) {
629 for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000630 DEnd = CurCtx->decls_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000631 D != DEnd; ++D) {
632 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
Douglas Gregor0563c262009-09-22 23:15:58 +0000633 Results.MaybeAddResult(Result(ND, Rank, 0, InBaseClass), CurContext);
Douglas Gregorff4393c2009-11-09 21:35:27 +0000634
635 // Visit transparent contexts inside this context.
636 if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
637 if (InnerCtx->isTransparentContext())
638 CollectMemberLookupResults(InnerCtx, Rank, CurContext, Visited,
639 Results, InBaseClass);
640 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000641 }
642 }
643
644 // Traverse the contexts of inherited classes.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000645 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
646 for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000647 BEnd = Record->bases_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000648 B != BEnd; ++B) {
649 QualType BaseType = B->getType();
650
651 // Don't look into dependent bases, because name lookup can't look
652 // there anyway.
653 if (BaseType->isDependentType())
654 continue;
655
656 const RecordType *Record = BaseType->getAs<RecordType>();
657 if (!Record)
658 continue;
659
660 // FIXME: It would be nice to be able to determine whether referencing
661 // a particular member would be ambiguous. For example, given
662 //
663 // struct A { int member; };
664 // struct B { int member; };
665 // struct C : A, B { };
666 //
667 // void f(C *c) { c->### }
668 // accessing 'member' would result in an ambiguity. However, code
669 // completion could be smart enough to qualify the member with the
670 // base class, e.g.,
671 //
672 // c->B::member
673 //
674 // or
675 //
676 // c->A::member
677
678 // Collect results from this base class (and its bases).
Douglas Gregor0563c262009-09-22 23:15:58 +0000679 CollectMemberLookupResults(Record->getDecl(), Rank, CurContext, Visited,
680 Results, /*InBaseClass=*/true);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000681 }
682 }
683
684 // FIXME: Look into base classes in Objective-C!
685
686 Results.ExitScope();
Douglas Gregor0563c262009-09-22 23:15:58 +0000687 return Rank + 1;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000688}
689
690/// \brief Collect the results of searching for members within the given
691/// declaration context.
692///
693/// \param Ctx the declaration context from which we will gather results.
694///
695/// \param InitialRank the initial rank given to results in this declaration
696/// context. Larger rank values will be used for, e.g., members found in
697/// base classes.
698///
699/// \param Results the result set that will be extended with any results
700/// found within this declaration context (and, for a C++ class, its bases).
701///
702/// \returns the next higher rank value, after considering all of the
703/// names within this declaration context.
704static unsigned CollectMemberLookupResults(DeclContext *Ctx,
705 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000706 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000707 ResultBuilder &Results) {
708 llvm::SmallPtrSet<DeclContext *, 16> Visited;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000709 return CollectMemberLookupResults(Ctx, InitialRank, CurContext, Visited,
710 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000711}
712
713/// \brief Collect the results of searching for declarations within the given
714/// scope and its parent scopes.
715///
716/// \param S the scope in which we will start looking for declarations.
717///
718/// \param InitialRank the initial rank given to results in this scope.
719/// Larger rank values will be used for results found in parent scopes.
720///
Douglas Gregor456c4a12009-09-21 20:12:40 +0000721/// \param CurContext the context from which lookup results will be found.
722///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000723/// \param Results the builder object that will receive each result.
724static unsigned CollectLookupResults(Scope *S,
725 TranslationUnitDecl *TranslationUnit,
726 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000727 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000728 ResultBuilder &Results) {
729 if (!S)
730 return InitialRank;
731
732 // FIXME: Using directives!
733
734 unsigned NextRank = InitialRank;
735 Results.EnterNewScope();
736 if (S->getEntity() &&
737 !((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
738 // Look into this scope's declaration context, along with any of its
739 // parent lookup contexts (e.g., enclosing classes), up to the point
740 // where we hit the context stored in the next outer scope.
741 DeclContext *Ctx = (DeclContext *)S->getEntity();
742 DeclContext *OuterCtx = findOuterContext(S);
743
744 for (; Ctx && Ctx->getPrimaryContext() != OuterCtx;
745 Ctx = Ctx->getLookupParent()) {
746 if (Ctx->isFunctionOrMethod())
747 continue;
748
Douglas Gregor456c4a12009-09-21 20:12:40 +0000749 NextRank = CollectMemberLookupResults(Ctx, NextRank + 1, CurContext,
750 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000751 }
752 } else if (!S->getParent()) {
753 // Look into the translation unit scope. We walk through the translation
754 // unit's declaration context, because the Scope itself won't have all of
755 // the declarations if we loaded a precompiled header.
756 // FIXME: We would like the translation unit's Scope object to point to the
757 // translation unit, so we don't need this special "if" branch. However,
758 // doing so would force the normal C++ name-lookup code to look into the
759 // translation unit decl when the IdentifierInfo chains would suffice.
760 // Once we fix that problem (which is part of a more general "don't look
761 // in DeclContexts unless we have to" optimization), we can eliminate the
762 // TranslationUnit parameter entirely.
763 NextRank = CollectMemberLookupResults(TranslationUnit, NextRank + 1,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000764 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000765 } else {
766 // Walk through the declarations in this Scope.
767 for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
768 D != DEnd; ++D) {
769 if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
Douglas Gregor456c4a12009-09-21 20:12:40 +0000770 Results.MaybeAddResult(CodeCompleteConsumer::Result(ND, NextRank),
771 CurContext);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000772 }
773
774 NextRank = NextRank + 1;
775 }
776
777 // Lookup names in the parent scope.
778 NextRank = CollectLookupResults(S->getParent(), TranslationUnit, NextRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000779 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000780 Results.ExitScope();
781
782 return NextRank;
783}
784
785/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregor9a0c85e2009-12-07 09:51:25 +0000786static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000787 ResultBuilder &Results) {
788 typedef CodeCompleteConsumer::Result Result;
789 Results.MaybeAddResult(Result("short", Rank));
790 Results.MaybeAddResult(Result("long", Rank));
791 Results.MaybeAddResult(Result("signed", Rank));
792 Results.MaybeAddResult(Result("unsigned", Rank));
793 Results.MaybeAddResult(Result("void", Rank));
794 Results.MaybeAddResult(Result("char", Rank));
795 Results.MaybeAddResult(Result("int", Rank));
796 Results.MaybeAddResult(Result("float", Rank));
797 Results.MaybeAddResult(Result("double", Rank));
798 Results.MaybeAddResult(Result("enum", Rank));
799 Results.MaybeAddResult(Result("struct", Rank));
800 Results.MaybeAddResult(Result("union", Rank));
801
802 if (LangOpts.C99) {
803 // C99-specific
804 Results.MaybeAddResult(Result("_Complex", Rank));
805 Results.MaybeAddResult(Result("_Imaginary", Rank));
806 Results.MaybeAddResult(Result("_Bool", Rank));
807 }
808
809 if (LangOpts.CPlusPlus) {
810 // C++-specific
811 Results.MaybeAddResult(Result("bool", Rank));
812 Results.MaybeAddResult(Result("class", Rank));
813 Results.MaybeAddResult(Result("typename", Rank));
814 Results.MaybeAddResult(Result("wchar_t", Rank));
815
816 if (LangOpts.CPlusPlus0x) {
817 Results.MaybeAddResult(Result("char16_t", Rank));
818 Results.MaybeAddResult(Result("char32_t", Rank));
819 Results.MaybeAddResult(Result("decltype", Rank));
820 }
821 }
822
823 // GNU extensions
824 if (LangOpts.GNUMode) {
825 // FIXME: Enable when we actually support decimal floating point.
826 // Results.MaybeAddResult(Result("_Decimal32", Rank));
827 // Results.MaybeAddResult(Result("_Decimal64", Rank));
828 // Results.MaybeAddResult(Result("_Decimal128", Rank));
829 Results.MaybeAddResult(Result("typeof", Rank));
830 }
831}
832
833/// \brief Add function parameter chunks to the given code completion string.
834static void AddFunctionParameterChunks(ASTContext &Context,
835 FunctionDecl *Function,
836 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000837 typedef CodeCompletionString::Chunk Chunk;
838
Douglas Gregor86d9a522009-09-21 16:56:56 +0000839 CodeCompletionString *CCStr = Result;
840
841 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
842 ParmVarDecl *Param = Function->getParamDecl(P);
843
844 if (Param->hasDefaultArg()) {
845 // When we see an optional default argument, put that argument and
846 // the remaining default arguments into a new, optional string.
847 CodeCompletionString *Opt = new CodeCompletionString;
848 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
849 CCStr = Opt;
850 }
851
852 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000853 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000854
855 // Format the placeholder string.
856 std::string PlaceholderStr;
857 if (Param->getIdentifier())
858 PlaceholderStr = Param->getIdentifier()->getName();
859
860 Param->getType().getAsStringInternal(PlaceholderStr,
861 Context.PrintingPolicy);
862
863 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +0000864 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000865 }
Douglas Gregorb3d45252009-09-22 21:42:17 +0000866
867 if (const FunctionProtoType *Proto
868 = Function->getType()->getAs<FunctionProtoType>())
869 if (Proto->isVariadic())
870 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +0000871}
872
873/// \brief Add template parameter chunks to the given code completion string.
874static void AddTemplateParameterChunks(ASTContext &Context,
875 TemplateDecl *Template,
876 CodeCompletionString *Result,
877 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000878 typedef CodeCompletionString::Chunk Chunk;
879
Douglas Gregor86d9a522009-09-21 16:56:56 +0000880 CodeCompletionString *CCStr = Result;
881 bool FirstParameter = true;
882
883 TemplateParameterList *Params = Template->getTemplateParameters();
884 TemplateParameterList::iterator PEnd = Params->end();
885 if (MaxParameters)
886 PEnd = Params->begin() + MaxParameters;
887 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
888 bool HasDefaultArg = false;
889 std::string PlaceholderStr;
890 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
891 if (TTP->wasDeclaredWithTypename())
892 PlaceholderStr = "typename";
893 else
894 PlaceholderStr = "class";
895
896 if (TTP->getIdentifier()) {
897 PlaceholderStr += ' ';
898 PlaceholderStr += TTP->getIdentifier()->getName();
899 }
900
901 HasDefaultArg = TTP->hasDefaultArgument();
902 } else if (NonTypeTemplateParmDecl *NTTP
903 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
904 if (NTTP->getIdentifier())
905 PlaceholderStr = NTTP->getIdentifier()->getName();
906 NTTP->getType().getAsStringInternal(PlaceholderStr,
907 Context.PrintingPolicy);
908 HasDefaultArg = NTTP->hasDefaultArgument();
909 } else {
910 assert(isa<TemplateTemplateParmDecl>(*P));
911 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
912
913 // Since putting the template argument list into the placeholder would
914 // be very, very long, we just use an abbreviation.
915 PlaceholderStr = "template<...> class";
916 if (TTP->getIdentifier()) {
917 PlaceholderStr += ' ';
918 PlaceholderStr += TTP->getIdentifier()->getName();
919 }
920
921 HasDefaultArg = TTP->hasDefaultArgument();
922 }
923
924 if (HasDefaultArg) {
925 // When we see an optional default argument, put that argument and
926 // the remaining default arguments into a new, optional string.
927 CodeCompletionString *Opt = new CodeCompletionString;
928 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
929 CCStr = Opt;
930 }
931
932 if (FirstParameter)
933 FirstParameter = false;
934 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000935 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000936
937 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +0000938 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000939 }
940}
941
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000942/// \brief Add a qualifier to the given code-completion string, if the
943/// provided nested-name-specifier is non-NULL.
944void AddQualifierToCompletionString(CodeCompletionString *Result,
945 NestedNameSpecifier *Qualifier,
Douglas Gregor0563c262009-09-22 23:15:58 +0000946 bool QualifierIsInformative,
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000947 ASTContext &Context) {
948 if (!Qualifier)
949 return;
950
951 std::string PrintedNNS;
952 {
953 llvm::raw_string_ostream OS(PrintedNNS);
954 Qualifier->print(OS, Context.PrintingPolicy);
955 }
Douglas Gregor0563c262009-09-22 23:15:58 +0000956 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +0000957 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +0000958 else
Benjamin Kramer660cc182009-11-29 20:18:50 +0000959 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000960}
961
Douglas Gregor86d9a522009-09-21 16:56:56 +0000962/// \brief If possible, create a new code completion string for the given
963/// result.
964///
965/// \returns Either a new, heap-allocated code completion string describing
966/// how to use this result, or NULL to indicate that the string or name of the
967/// result is all that is needed.
968CodeCompletionString *
969CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000970 typedef CodeCompletionString::Chunk Chunk;
971
Douglas Gregor2b4074f2009-12-01 05:55:20 +0000972 if (Kind == RK_Pattern)
973 return Pattern->Clone();
974
975 CodeCompletionString *Result = new CodeCompletionString;
976
977 if (Kind == RK_Keyword) {
978 Result->AddTypedTextChunk(Keyword);
979 return Result;
980 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000981
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000982 if (Kind == RK_Macro) {
983 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +0000984 assert(MI && "Not a macro?");
985
986 Result->AddTypedTextChunk(Macro->getName());
987
988 if (!MI->isFunctionLike())
989 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000990
991 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000992 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000993 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
994 A != AEnd; ++A) {
995 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000996 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000997
998 if (!MI->isVariadic() || A != AEnd - 1) {
999 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001000 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001001 continue;
1002 }
1003
1004 // Variadic argument; cope with the different between GNU and C99
1005 // variadic macros, providing a single placeholder for the rest of the
1006 // arguments.
1007 if ((*A)->isStr("__VA_ARGS__"))
1008 Result->AddPlaceholderChunk("...");
1009 else {
1010 std::string Arg = (*A)->getName();
1011 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001012 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001013 }
1014 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001015 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001016 return Result;
1017 }
1018
1019 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001020 NamedDecl *ND = Declaration;
1021
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001022 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001023 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001024 Result->AddTextChunk("::");
1025 return Result;
1026 }
1027
Douglas Gregor86d9a522009-09-21 16:56:56 +00001028 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001029 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1030 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001031 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001032 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001033 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001034 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001035 return Result;
1036 }
1037
1038 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001039 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1040 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001041 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001042 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001043
1044 // Figure out which template parameters are deduced (or have default
1045 // arguments).
1046 llvm::SmallVector<bool, 16> Deduced;
1047 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1048 unsigned LastDeducibleArgument;
1049 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1050 --LastDeducibleArgument) {
1051 if (!Deduced[LastDeducibleArgument - 1]) {
1052 // C++0x: Figure out if the template argument has a default. If so,
1053 // the user doesn't need to type this argument.
1054 // FIXME: We need to abstract template parameters better!
1055 bool HasDefaultArg = false;
1056 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1057 LastDeducibleArgument - 1);
1058 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1059 HasDefaultArg = TTP->hasDefaultArgument();
1060 else if (NonTypeTemplateParmDecl *NTTP
1061 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1062 HasDefaultArg = NTTP->hasDefaultArgument();
1063 else {
1064 assert(isa<TemplateTemplateParmDecl>(Param));
1065 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001066 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001067 }
1068
1069 if (!HasDefaultArg)
1070 break;
1071 }
1072 }
1073
1074 if (LastDeducibleArgument) {
1075 // Some of the function template arguments cannot be deduced from a
1076 // function call, so we introduce an explicit template argument list
1077 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001078 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001079 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1080 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001081 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001082 }
1083
1084 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001085 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001086 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001087 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001088 return Result;
1089 }
1090
1091 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001092 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1093 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001094 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001095 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001096 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001097 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001098 return Result;
1099 }
1100
Douglas Gregor9630eb62009-11-17 16:44:22 +00001101 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001102 Selector Sel = Method->getSelector();
1103 if (Sel.isUnarySelector()) {
1104 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1105 return Result;
1106 }
1107
Douglas Gregord3c68542009-11-19 01:08:35 +00001108 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1109 SelName += ':';
1110 if (StartParameter == 0)
1111 Result->AddTypedTextChunk(SelName);
1112 else {
1113 Result->AddInformativeChunk(SelName);
1114
1115 // If there is only one parameter, and we're past it, add an empty
1116 // typed-text chunk since there is nothing to type.
1117 if (Method->param_size() == 1)
1118 Result->AddTypedTextChunk("");
1119 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001120 unsigned Idx = 0;
1121 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1122 PEnd = Method->param_end();
1123 P != PEnd; (void)++P, ++Idx) {
1124 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001125 std::string Keyword;
1126 if (Idx > StartParameter)
1127 Keyword = " ";
Douglas Gregor9630eb62009-11-17 16:44:22 +00001128 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1129 Keyword += II->getName().str();
1130 Keyword += ":";
Douglas Gregor4ad96852009-11-19 07:41:15 +00001131 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001132 Result->AddInformativeChunk(Keyword);
1133 } else if (Idx == StartParameter)
1134 Result->AddTypedTextChunk(Keyword);
1135 else
1136 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001137 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001138
1139 // If we're before the starting parameter, skip the placeholder.
1140 if (Idx < StartParameter)
1141 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001142
1143 std::string Arg;
1144 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1145 Arg = "(" + Arg + ")";
1146 if (IdentifierInfo *II = (*P)->getIdentifier())
1147 Arg += II->getName().str();
Douglas Gregor4ad96852009-11-19 07:41:15 +00001148 if (AllParametersAreInformative)
1149 Result->AddInformativeChunk(Arg);
1150 else
1151 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001152 }
1153
1154 return Result;
1155 }
1156
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001157 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00001158 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1159 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001160
1161 Result->AddTypedTextChunk(ND->getNameAsString());
1162 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001163}
1164
Douglas Gregor86d802e2009-09-23 00:34:09 +00001165CodeCompletionString *
1166CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1167 unsigned CurrentArg,
1168 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001169 typedef CodeCompletionString::Chunk Chunk;
1170
Douglas Gregor86d802e2009-09-23 00:34:09 +00001171 CodeCompletionString *Result = new CodeCompletionString;
1172 FunctionDecl *FDecl = getFunction();
1173 const FunctionProtoType *Proto
1174 = dyn_cast<FunctionProtoType>(getFunctionType());
1175 if (!FDecl && !Proto) {
1176 // Function without a prototype. Just give the return type and a
1177 // highlighted ellipsis.
1178 const FunctionType *FT = getFunctionType();
1179 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001180 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001181 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1182 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1183 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001184 return Result;
1185 }
1186
1187 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001188 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00001189 else
1190 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001191 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001192
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001193 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001194 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1195 for (unsigned I = 0; I != NumParams; ++I) {
1196 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001197 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001198
1199 std::string ArgString;
1200 QualType ArgType;
1201
1202 if (FDecl) {
1203 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1204 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1205 } else {
1206 ArgType = Proto->getArgType(I);
1207 }
1208
1209 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1210
1211 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001212 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00001213 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001214 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001215 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001216 }
1217
1218 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001219 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001220 if (CurrentArg < NumParams)
1221 Result->AddTextChunk("...");
1222 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001223 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001224 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001225 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001226
1227 return Result;
1228}
1229
Douglas Gregor86d9a522009-09-21 16:56:56 +00001230namespace {
1231 struct SortCodeCompleteResult {
1232 typedef CodeCompleteConsumer::Result Result;
1233
Douglas Gregor6a684032009-09-28 03:51:44 +00001234 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001235 Selector XSel = X.getObjCSelector();
1236 Selector YSel = Y.getObjCSelector();
1237 if (!XSel.isNull() && !YSel.isNull()) {
1238 // We are comparing two selectors.
1239 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1240 if (N == 0)
1241 ++N;
1242 for (unsigned I = 0; I != N; ++I) {
1243 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1244 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1245 if (!XId || !YId)
1246 return XId && !YId;
1247
1248 switch (XId->getName().compare_lower(YId->getName())) {
1249 case -1: return true;
1250 case 1: return false;
1251 default: break;
1252 }
1253 }
1254
1255 return XSel.getNumArgs() < YSel.getNumArgs();
1256 }
1257
1258 // For non-selectors, order by kind.
1259 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00001260 return X.getNameKind() < Y.getNameKind();
1261
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001262 // Order identifiers by comparison of their lowercased names.
1263 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1264 return XId->getName().compare_lower(
1265 Y.getAsIdentifierInfo()->getName()) < 0;
1266
1267 // Order overloaded operators by the order in which they appear
1268 // in our list of operators.
1269 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1270 return XOp < Y.getCXXOverloadedOperator();
1271
1272 // Order C++0x user-defined literal operators lexically by their
1273 // lowercased suffixes.
1274 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1275 return XLit->getName().compare_lower(
1276 Y.getCXXLiteralIdentifier()->getName()) < 0;
1277
1278 // The only stable ordering we have is to turn the name into a
1279 // string and then compare the lower-case strings. This is
1280 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00001281 return llvm::StringRef(X.getAsString()).compare_lower(
1282 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00001283 }
1284
Douglas Gregor86d9a522009-09-21 16:56:56 +00001285 bool operator()(const Result &X, const Result &Y) const {
1286 // Sort first by rank.
1287 if (X.Rank < Y.Rank)
1288 return true;
1289 else if (X.Rank > Y.Rank)
1290 return false;
1291
Douglas Gregor54f01612009-11-19 00:01:57 +00001292 // We use a special ordering for keywords and patterns, based on the
1293 // typed text.
1294 if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
1295 (Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
1296 const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword
1297 : X.Pattern->getTypedText();
1298 const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
1299 : Y.Pattern->getTypedText();
Benjamin Kramerf42d4882009-12-05 10:07:04 +00001300 return llvm::StringRef(XStr).compare_lower(YStr) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001301 }
1302
Douglas Gregor86d9a522009-09-21 16:56:56 +00001303 // Result kinds are ordered by decreasing importance.
1304 if (X.Kind < Y.Kind)
1305 return true;
1306 else if (X.Kind > Y.Kind)
1307 return false;
1308
1309 // Non-hidden names precede hidden names.
1310 if (X.Hidden != Y.Hidden)
1311 return !X.Hidden;
1312
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001313 // Non-nested-name-specifiers precede nested-name-specifiers.
1314 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1315 return !X.StartsNestedNameSpecifier;
1316
Douglas Gregor86d9a522009-09-21 16:56:56 +00001317 // Ordering depends on the kind of result.
1318 switch (X.Kind) {
1319 case Result::RK_Declaration:
1320 // Order based on the declaration names.
Douglas Gregor6a684032009-09-28 03:51:44 +00001321 return isEarlierDeclarationName(X.Declaration->getDeclName(),
1322 Y.Declaration->getDeclName());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001323
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001324 case Result::RK_Macro:
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001325 return X.Macro->getName().compare_lower(Y.Macro->getName()) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001326
1327 case Result::RK_Keyword:
1328 case Result::RK_Pattern:
1329 llvm::llvm_unreachable("Result kinds handled above");
1330 break;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001331 }
1332
1333 // Silence GCC warning.
1334 return false;
1335 }
1336 };
1337}
1338
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001339static void AddMacroResults(Preprocessor &PP, unsigned Rank,
1340 ResultBuilder &Results) {
1341 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001342 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1343 MEnd = PP.macro_end();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001344 M != MEnd; ++M)
1345 Results.MaybeAddResult(CodeCompleteConsumer::Result(M->first, Rank));
1346 Results.ExitScope();
1347}
1348
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001349static void HandleCodeCompleteResults(Sema *S,
1350 CodeCompleteConsumer *CodeCompleter,
1351 CodeCompleteConsumer::Result *Results,
1352 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001353 // Sort the results by rank/kind/etc.
1354 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1355
1356 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001357 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00001358
1359 for (unsigned I = 0; I != NumResults; ++I)
1360 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001361}
1362
Douglas Gregor791215b2009-09-21 20:51:25 +00001363void Sema::CodeCompleteOrdinaryName(Scope *S) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001364 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor791215b2009-09-21 20:51:25 +00001365 ResultBuilder Results(*this, &ResultBuilder::IsOrdinaryName);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001366 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1367 0, CurContext, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001368
1369 Results.EnterNewScope();
1370 AddTypeSpecifierResults(getLangOptions(), NextRank, Results);
1371
1372 if (getLangOptions().ObjC1) {
1373 // Add the "super" keyword, if appropriate.
1374 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
1375 if (Method->getClassInterface()->getSuperClass())
1376 Results.MaybeAddResult(Result("super", NextRank));
1377 }
1378
1379 Results.ExitScope();
1380
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001381 if (CodeCompleter->includeMacros())
1382 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001383 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00001384}
1385
Douglas Gregor95ac6552009-11-18 01:29:26 +00001386static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00001387 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00001388 DeclContext *CurContext,
1389 ResultBuilder &Results) {
1390 typedef CodeCompleteConsumer::Result Result;
1391
1392 // Add properties in this container.
1393 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1394 PEnd = Container->prop_end();
1395 P != PEnd;
1396 ++P)
1397 Results.MaybeAddResult(Result(*P, 0), CurContext);
1398
1399 // Add properties in referenced protocols.
1400 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1401 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1402 PEnd = Protocol->protocol_end();
1403 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001404 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001405 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00001406 if (AllowCategories) {
1407 // Look through categories.
1408 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1409 Category; Category = Category->getNextClassCategory())
1410 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1411 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001412
1413 // Look through protocols.
1414 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1415 E = IFace->protocol_end();
1416 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001417 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001418
1419 // Look in the superclass.
1420 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00001421 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
1422 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001423 } else if (const ObjCCategoryDecl *Category
1424 = dyn_cast<ObjCCategoryDecl>(Container)) {
1425 // Look through protocols.
1426 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
1427 PEnd = Category->protocol_end();
1428 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001429 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001430 }
1431}
1432
Douglas Gregor81b747b2009-09-17 21:32:03 +00001433void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
1434 SourceLocation OpLoc,
1435 bool IsArrow) {
1436 if (!BaseE || !CodeCompleter)
1437 return;
1438
Douglas Gregor86d9a522009-09-21 16:56:56 +00001439 typedef CodeCompleteConsumer::Result Result;
1440
Douglas Gregor81b747b2009-09-17 21:32:03 +00001441 Expr *Base = static_cast<Expr *>(BaseE);
1442 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001443
1444 if (IsArrow) {
1445 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1446 BaseType = Ptr->getPointeeType();
1447 else if (BaseType->isObjCObjectPointerType())
1448 /*Do nothing*/ ;
1449 else
1450 return;
1451 }
1452
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001453 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001454 unsigned NextRank = 0;
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001455
Douglas Gregor95ac6552009-11-18 01:29:26 +00001456 Results.EnterNewScope();
1457 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
1458 // Access to a C/C++ class, struct, or union.
1459 NextRank = CollectMemberLookupResults(Record->getDecl(), NextRank,
1460 Record->getDecl(), Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001461
Douglas Gregor95ac6552009-11-18 01:29:26 +00001462 if (getLangOptions().CPlusPlus) {
1463 if (!Results.empty()) {
1464 // The "template" keyword can follow "->" or "." in the grammar.
1465 // However, we only want to suggest the template keyword if something
1466 // is dependent.
1467 bool IsDependent = BaseType->isDependentType();
1468 if (!IsDependent) {
1469 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
1470 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
1471 IsDependent = Ctx->isDependentContext();
1472 break;
1473 }
1474 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001475
Douglas Gregor95ac6552009-11-18 01:29:26 +00001476 if (IsDependent)
1477 Results.MaybeAddResult(Result("template", NextRank++));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001478 }
1479
Douglas Gregor95ac6552009-11-18 01:29:26 +00001480 // We could have the start of a nested-name-specifier. Add those
1481 // results as well.
1482 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
1483 CollectLookupResults(S, Context.getTranslationUnitDecl(), NextRank,
1484 CurContext, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001485 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001486 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
1487 // Objective-C property reference.
1488
1489 // Add property results based on our interface.
1490 const ObjCObjectPointerType *ObjCPtr
1491 = BaseType->getAsObjCInterfacePointerType();
1492 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00001493 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001494
1495 // Add properties from the protocols in a qualified interface.
1496 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
1497 E = ObjCPtr->qual_end();
1498 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001499 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001500
1501 // FIXME: We could (should?) also look for "implicit" properties, identified
1502 // only by the presence of nullary and unary selectors.
1503 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
1504 (!IsArrow && BaseType->isObjCInterfaceType())) {
1505 // Objective-C instance variable access.
1506 ObjCInterfaceDecl *Class = 0;
1507 if (const ObjCObjectPointerType *ObjCPtr
1508 = BaseType->getAs<ObjCObjectPointerType>())
1509 Class = ObjCPtr->getInterfaceDecl();
1510 else
1511 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
1512
1513 // Add all ivars from this class and its superclasses.
1514 for (; Class; Class = Class->getSuperClass()) {
1515 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
1516 IVarEnd = Class->ivar_end();
1517 IVar != IVarEnd; ++IVar)
1518 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
1519 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001520 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001521
1522 // FIXME: How do we cope with isa?
1523
1524 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001525
1526 // Add macros
1527 if (CodeCompleter->includeMacros())
1528 AddMacroResults(PP, NextRank, Results);
1529
1530 // Hand off the results found for code completion.
1531 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00001532}
1533
Douglas Gregor374929f2009-09-18 15:37:17 +00001534void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
1535 if (!CodeCompleter)
1536 return;
1537
Douglas Gregor86d9a522009-09-21 16:56:56 +00001538 typedef CodeCompleteConsumer::Result Result;
1539 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00001540 switch ((DeclSpec::TST)TagSpec) {
1541 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001542 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00001543 break;
1544
1545 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001546 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00001547 break;
1548
1549 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00001550 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001551 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00001552 break;
1553
1554 default:
1555 assert(false && "Unknown type specifier kind in CodeCompleteTag");
1556 return;
1557 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001558
1559 ResultBuilder Results(*this, Filter);
1560 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00001561 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001562
1563 if (getLangOptions().CPlusPlus) {
1564 // We could have the start of a nested-name-specifier. Add those
1565 // results as well.
1566 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001567 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1568 NextRank, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001569 }
1570
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001571 if (CodeCompleter->includeMacros())
1572 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001573 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00001574}
1575
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001576void Sema::CodeCompleteCase(Scope *S) {
1577 if (getSwitchStack().empty() || !CodeCompleter)
1578 return;
1579
1580 SwitchStmt *Switch = getSwitchStack().back();
1581 if (!Switch->getCond()->getType()->isEnumeralType())
1582 return;
1583
1584 // Code-complete the cases of a switch statement over an enumeration type
1585 // by providing the list of
1586 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
1587
1588 // Determine which enumerators we have already seen in the switch statement.
1589 // FIXME: Ideally, we would also be able to look *past* the code-completion
1590 // token, in case we are code-completing in the middle of the switch and not
1591 // at the end. However, we aren't able to do so at the moment.
1592 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001593 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001594 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
1595 SC = SC->getNextSwitchCase()) {
1596 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
1597 if (!Case)
1598 continue;
1599
1600 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
1601 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
1602 if (EnumConstantDecl *Enumerator
1603 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
1604 // We look into the AST of the case statement to determine which
1605 // enumerator was named. Alternatively, we could compute the value of
1606 // the integral constant expression, then compare it against the
1607 // values of each enumerator. However, value-based approach would not
1608 // work as well with C++ templates where enumerators declared within a
1609 // template are type- and value-dependent.
1610 EnumeratorsSeen.insert(Enumerator);
1611
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001612 // If this is a qualified-id, keep track of the nested-name-specifier
1613 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001614 //
1615 // switch (TagD.getKind()) {
1616 // case TagDecl::TK_enum:
1617 // break;
1618 // case XXX
1619 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001620 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001621 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
1622 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00001623 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001624 }
1625 }
1626
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001627 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
1628 // If there are no prior enumerators in C++, check whether we have to
1629 // qualify the names of the enumerators that we suggest, because they
1630 // may not be visible in this scope.
1631 Qualifier = getRequiredQualification(Context, CurContext,
1632 Enum->getDeclContext());
1633
1634 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
1635 }
1636
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001637 // Add any enumerators that have not yet been mentioned.
1638 ResultBuilder Results(*this);
1639 Results.EnterNewScope();
1640 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
1641 EEnd = Enum->enumerator_end();
1642 E != EEnd; ++E) {
1643 if (EnumeratorsSeen.count(*E))
1644 continue;
1645
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001646 Results.MaybeAddResult(CodeCompleteConsumer::Result(*E, 0, Qualifier));
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001647 }
1648 Results.ExitScope();
1649
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001650 if (CodeCompleter->includeMacros())
1651 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001652 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001653}
1654
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001655namespace {
1656 struct IsBetterOverloadCandidate {
1657 Sema &S;
1658
1659 public:
1660 explicit IsBetterOverloadCandidate(Sema &S) : S(S) { }
1661
1662 bool
1663 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
1664 return S.isBetterOverloadCandidate(X, Y);
1665 }
1666 };
1667}
1668
1669void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
1670 ExprTy **ArgsIn, unsigned NumArgs) {
1671 if (!CodeCompleter)
1672 return;
1673
1674 Expr *Fn = (Expr *)FnIn;
1675 Expr **Args = (Expr **)ArgsIn;
1676
1677 // Ignore type-dependent call expressions entirely.
1678 if (Fn->isTypeDependent() ||
1679 Expr::hasAnyTypeDependentArguments(Args, NumArgs))
1680 return;
1681
John McCallba135432009-11-21 08:51:07 +00001682 llvm::SmallVector<NamedDecl*,8> Fns;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001683 DeclarationName UnqualifiedName;
1684 NestedNameSpecifier *Qualifier;
1685 SourceRange QualifierRange;
1686 bool ArgumentDependentLookup;
John McCall7453ed42009-11-22 00:44:51 +00001687 bool Overloaded;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001688 bool HasExplicitTemplateArgs;
John McCalld5532b62009-11-23 01:53:49 +00001689 TemplateArgumentListInfo ExplicitTemplateArgs;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001690
John McCallba135432009-11-21 08:51:07 +00001691 DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
John McCall7453ed42009-11-22 00:44:51 +00001692 ArgumentDependentLookup, Overloaded,
John McCalld5532b62009-11-23 01:53:49 +00001693 HasExplicitTemplateArgs, ExplicitTemplateArgs);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001694
1695
1696 // FIXME: What if we're calling something that isn't a function declaration?
1697 // FIXME: What if we're calling a pseudo-destructor?
1698 // FIXME: What if we're calling a member function?
1699
1700 // Build an overload candidate set based on the functions we find.
1701 OverloadCandidateSet CandidateSet;
John McCallba135432009-11-21 08:51:07 +00001702 AddOverloadedCallCandidates(Fns, UnqualifiedName,
John McCalld5532b62009-11-23 01:53:49 +00001703 ArgumentDependentLookup,
1704 (HasExplicitTemplateArgs ? &ExplicitTemplateArgs : 0),
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001705 Args, NumArgs,
1706 CandidateSet,
1707 /*PartialOverloading=*/true);
1708
1709 // Sort the overload candidate set by placing the best overloads first.
1710 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
1711 IsBetterOverloadCandidate(*this));
1712
1713 // Add the remaining viable overload candidates as code-completion reslults.
Douglas Gregor05944382009-09-23 00:16:58 +00001714 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
1715 llvm::SmallVector<ResultCandidate, 8> Results;
Anders Carlsson90756302009-09-22 17:29:51 +00001716
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001717 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
1718 CandEnd = CandidateSet.end();
1719 Cand != CandEnd; ++Cand) {
1720 if (Cand->Viable)
Douglas Gregor05944382009-09-23 00:16:58 +00001721 Results.push_back(ResultCandidate(Cand->Function));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001722 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001723 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
Douglas Gregor05944382009-09-23 00:16:58 +00001724 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001725}
1726
Douglas Gregor81b747b2009-09-17 21:32:03 +00001727void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
1728 bool EnteringContext) {
1729 if (!SS.getScopeRep() || !CodeCompleter)
1730 return;
1731
Douglas Gregor86d9a522009-09-21 16:56:56 +00001732 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
1733 if (!Ctx)
1734 return;
1735
1736 ResultBuilder Results(*this);
Douglas Gregor456c4a12009-09-21 20:12:40 +00001737 unsigned NextRank = CollectMemberLookupResults(Ctx, 0, Ctx, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001738
1739 // The "template" keyword can follow "::" in the grammar, but only
1740 // put it into the grammar if the nested-name-specifier is dependent.
1741 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
1742 if (!Results.empty() && NNS->isDependent())
1743 Results.MaybeAddResult(CodeCompleteConsumer::Result("template", NextRank));
1744
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001745 if (CodeCompleter->includeMacros())
1746 AddMacroResults(PP, NextRank + 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001747 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00001748}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001749
1750void Sema::CodeCompleteUsing(Scope *S) {
1751 if (!CodeCompleter)
1752 return;
1753
Douglas Gregor86d9a522009-09-21 16:56:56 +00001754 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001755 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001756
1757 // If we aren't in class scope, we could see the "namespace" keyword.
1758 if (!S->isClassScope())
1759 Results.MaybeAddResult(CodeCompleteConsumer::Result("namespace", 0));
1760
1761 // After "using", we can see anything that would start a
1762 // nested-name-specifier.
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001763 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1764 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001765 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001766
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001767 if (CodeCompleter->includeMacros())
1768 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001769 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001770}
1771
1772void Sema::CodeCompleteUsingDirective(Scope *S) {
1773 if (!CodeCompleter)
1774 return;
1775
Douglas Gregor86d9a522009-09-21 16:56:56 +00001776 // After "using namespace", we expect to see a namespace name or namespace
1777 // alias.
1778 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001779 Results.EnterNewScope();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001780 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1781 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001782 Results.ExitScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001783 if (CodeCompleter->includeMacros())
1784 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001785 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001786}
1787
1788void Sema::CodeCompleteNamespaceDecl(Scope *S) {
1789 if (!CodeCompleter)
1790 return;
1791
Douglas Gregor86d9a522009-09-21 16:56:56 +00001792 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
1793 DeclContext *Ctx = (DeclContext *)S->getEntity();
1794 if (!S->getParent())
1795 Ctx = Context.getTranslationUnitDecl();
1796
1797 if (Ctx && Ctx->isFileContext()) {
1798 // We only want to see those namespaces that have already been defined
1799 // within this scope, because its likely that the user is creating an
1800 // extended namespace declaration. Keep track of the most recent
1801 // definition of each namespace.
1802 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
1803 for (DeclContext::specific_decl_iterator<NamespaceDecl>
1804 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
1805 NS != NSEnd; ++NS)
1806 OrigToLatest[NS->getOriginalNamespace()] = *NS;
1807
1808 // Add the most recent definition (or extended definition) of each
1809 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001810 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001811 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
1812 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
1813 NS != NSEnd; ++NS)
Douglas Gregor456c4a12009-09-21 20:12:40 +00001814 Results.MaybeAddResult(CodeCompleteConsumer::Result(NS->second, 0),
1815 CurContext);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001816 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001817 }
1818
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001819 if (CodeCompleter->includeMacros())
1820 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001821 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001822}
1823
1824void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
1825 if (!CodeCompleter)
1826 return;
1827
Douglas Gregor86d9a522009-09-21 16:56:56 +00001828 // After "namespace", we expect to see a namespace or alias.
1829 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001830 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1831 0, CurContext, Results);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001832 if (CodeCompleter->includeMacros())
1833 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001834 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001835}
1836
Douglas Gregored8d3222009-09-18 20:05:18 +00001837void Sema::CodeCompleteOperatorName(Scope *S) {
1838 if (!CodeCompleter)
1839 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001840
1841 typedef CodeCompleteConsumer::Result Result;
1842 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001843 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00001844
Douglas Gregor86d9a522009-09-21 16:56:56 +00001845 // Add the names of overloadable operators.
1846#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1847 if (std::strcmp(Spelling, "?")) \
1848 Results.MaybeAddResult(Result(Spelling, 0));
1849#include "clang/Basic/OperatorKinds.def"
1850
1851 // Add any type names visible from the current scope
1852 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00001853 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001854
1855 // Add any type specifiers
1856 AddTypeSpecifierResults(getLangOptions(), 0, Results);
1857
1858 // Add any nested-name-specifiers
1859 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001860 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1861 NextRank + 1, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001862 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001863
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001864 if (CodeCompleter->includeMacros())
1865 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001866 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00001867}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001868
Douglas Gregorc464ae82009-12-07 09:27:33 +00001869void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
1870 bool InInterface) {
1871 typedef CodeCompleteConsumer::Result Result;
1872 ResultBuilder Results(*this);
1873 Results.EnterNewScope();
1874 if (ObjCImpDecl) {
1875 // Since we have an implementation, we can end it.
1876 Results.MaybeAddResult(Result("end", 0));
1877
1878 CodeCompletionString *Pattern = 0;
1879 Decl *ImpDecl = ObjCImpDecl.getAs<Decl>();
1880 if (isa<ObjCImplementationDecl>(ImpDecl) ||
1881 isa<ObjCCategoryImplDecl>(ImpDecl)) {
1882 // @dynamic
1883 Pattern = new CodeCompletionString;
1884 Pattern->AddTypedTextChunk("dynamic");
1885 Pattern->AddTextChunk(" ");
1886 Pattern->AddPlaceholderChunk("property");
1887 Results.MaybeAddResult(Result(Pattern, 0));
1888
1889 // @synthesize
1890 Pattern = new CodeCompletionString;
1891 Pattern->AddTypedTextChunk("synthesize");
1892 Pattern->AddTextChunk(" ");
1893 Pattern->AddPlaceholderChunk("property");
1894 Results.MaybeAddResult(Result(Pattern, 0));
1895 }
1896 } else if (InInterface) {
1897 // Since we have an interface or protocol, we can end it.
1898 Results.MaybeAddResult(Result("end", 0));
1899
1900 if (LangOpts.ObjC2) {
1901 // @property
1902 Results.MaybeAddResult(Result("property", 0));
1903 }
1904
1905 // @required
1906 Results.MaybeAddResult(Result("required", 0));
1907
1908 // @optional
1909 Results.MaybeAddResult(Result("optional", 0));
1910 } else {
1911 CodeCompletionString *Pattern = 0;
1912
1913 // @class name ;
1914 Pattern = new CodeCompletionString;
1915 Pattern->AddTypedTextChunk("class");
1916 Pattern->AddTextChunk(" ");
1917 Pattern->AddPlaceholderChunk("identifier");
1918 Pattern->AddTextChunk(";"); // add ';' chunk
1919 Results.MaybeAddResult(Result(Pattern, 0));
1920
1921 // @interface name
1922 // FIXME: Could introduce the whole pattern, including superclasses and
1923 // such.
1924 Pattern = new CodeCompletionString;
1925 Pattern->AddTypedTextChunk("interface");
1926 Pattern->AddTextChunk(" ");
1927 Pattern->AddPlaceholderChunk("class");
1928 Results.MaybeAddResult(Result(Pattern, 0));
1929
1930 // @protocol name
1931 Pattern = new CodeCompletionString;
1932 Pattern->AddTypedTextChunk("protocol");
1933 Pattern->AddTextChunk(" ");
1934 Pattern->AddPlaceholderChunk("protocol");
1935 Results.MaybeAddResult(Result(Pattern, 0));
1936
1937 // @implementation name
1938 Pattern = new CodeCompletionString;
1939 Pattern->AddTypedTextChunk("implementation");
1940 Pattern->AddTextChunk(" ");
1941 Pattern->AddPlaceholderChunk("class");
1942 Results.MaybeAddResult(Result(Pattern, 0));
1943
1944 // @compatibility_alias name
1945 Pattern = new CodeCompletionString;
1946 Pattern->AddTypedTextChunk("compatibility_alias");
1947 Pattern->AddTextChunk(" ");
1948 Pattern->AddPlaceholderChunk("alias");
1949 Pattern->AddTextChunk(" ");
1950 Pattern->AddPlaceholderChunk("class");
1951 Results.MaybeAddResult(Result(Pattern, 0));
1952 }
1953 Results.ExitScope();
1954 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
1955}
1956
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00001957static void AddObjCExpressionResults(unsigned Rank, ResultBuilder &Results) {
1958 typedef CodeCompleteConsumer::Result Result;
1959 CodeCompletionString *Pattern = 0;
1960
1961 // @encode ( type-name )
1962 Pattern = new CodeCompletionString;
1963 Pattern->AddTypedTextChunk("encode");
1964 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1965 Pattern->AddPlaceholderChunk("type-name");
1966 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1967 Results.MaybeAddResult(Result(Pattern, Rank));
1968
1969 // @protocol ( protocol-name )
1970 Pattern = new CodeCompletionString;
1971 Pattern->AddTypedTextChunk("protocol");
1972 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1973 Pattern->AddPlaceholderChunk("protocol-name");
1974 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1975 Results.MaybeAddResult(Result(Pattern, Rank));
1976
1977 // @selector ( selector )
1978 Pattern = new CodeCompletionString;
1979 Pattern->AddTypedTextChunk("selector");
1980 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1981 Pattern->AddPlaceholderChunk("selector");
1982 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1983 Results.MaybeAddResult(Result(Pattern, Rank));
1984}
1985
1986void Sema::CodeCompleteObjCAtStatement(Scope *S) {
1987 typedef CodeCompleteConsumer::Result Result;
1988 ResultBuilder Results(*this);
1989 Results.EnterNewScope();
1990
1991 CodeCompletionString *Pattern = 0;
1992
1993 // @try { statements } @catch ( declaration ) { statements } @finally
1994 // { statements }
1995 Pattern = new CodeCompletionString;
1996 Pattern->AddTypedTextChunk("try");
1997 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1998 Pattern->AddPlaceholderChunk("statements");
1999 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2000 Pattern->AddTextChunk("@catch");
2001 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2002 Pattern->AddPlaceholderChunk("parameter");
2003 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2004 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2005 Pattern->AddPlaceholderChunk("statements");
2006 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2007 Pattern->AddTextChunk("@finally");
2008 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2009 Pattern->AddPlaceholderChunk("statements");
2010 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2011 Results.MaybeAddResult(Result(Pattern, 0));
2012
2013 // @throw
2014 Pattern = new CodeCompletionString;
2015 Pattern->AddTypedTextChunk("throw");
2016 Pattern->AddTextChunk(" ");
2017 Pattern->AddPlaceholderChunk("expression");
2018 Pattern->AddTextChunk(";");
2019 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2020
2021 // @synchronized ( expression ) { statements }
2022 Pattern = new CodeCompletionString;
2023 Pattern->AddTypedTextChunk("synchronized");
2024 Pattern->AddTextChunk(" ");
2025 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2026 Pattern->AddPlaceholderChunk("expression");
2027 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2028 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2029 Pattern->AddPlaceholderChunk("statements");
2030 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2031 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2032
2033 AddObjCExpressionResults(0, Results);
2034 Results.ExitScope();
2035 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2036}
2037
2038void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2039 ResultBuilder Results(*this);
2040 Results.EnterNewScope();
2041 AddObjCExpressionResults(0, Results);
2042 Results.ExitScope();
2043 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2044}
2045
Douglas Gregor988358f2009-11-19 00:14:45 +00002046/// \brief Determine whether the addition of the given flag to an Objective-C
2047/// property's attributes will cause a conflict.
2048static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2049 // Check if we've already added this flag.
2050 if (Attributes & NewFlag)
2051 return true;
2052
2053 Attributes |= NewFlag;
2054
2055 // Check for collisions with "readonly".
2056 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2057 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2058 ObjCDeclSpec::DQ_PR_assign |
2059 ObjCDeclSpec::DQ_PR_copy |
2060 ObjCDeclSpec::DQ_PR_retain)))
2061 return true;
2062
2063 // Check for more than one of { assign, copy, retain }.
2064 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2065 ObjCDeclSpec::DQ_PR_copy |
2066 ObjCDeclSpec::DQ_PR_retain);
2067 if (AssignCopyRetMask &&
2068 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2069 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2070 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2071 return true;
2072
2073 return false;
2074}
2075
Douglas Gregora93b1082009-11-18 23:08:07 +00002076void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00002077 if (!CodeCompleter)
2078 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00002079
Steve Naroffece8e712009-10-08 21:55:05 +00002080 unsigned Attributes = ODS.getPropertyAttributes();
2081
2082 typedef CodeCompleteConsumer::Result Result;
2083 ResultBuilder Results(*this);
2084 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00002085 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Steve Naroffece8e712009-10-08 21:55:05 +00002086 Results.MaybeAddResult(CodeCompleteConsumer::Result("readonly", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002087 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Steve Naroffece8e712009-10-08 21:55:05 +00002088 Results.MaybeAddResult(CodeCompleteConsumer::Result("assign", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002089 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Steve Naroffece8e712009-10-08 21:55:05 +00002090 Results.MaybeAddResult(CodeCompleteConsumer::Result("readwrite", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002091 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Steve Naroffece8e712009-10-08 21:55:05 +00002092 Results.MaybeAddResult(CodeCompleteConsumer::Result("retain", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002093 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Steve Naroffece8e712009-10-08 21:55:05 +00002094 Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002095 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Steve Naroffece8e712009-10-08 21:55:05 +00002096 Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002097 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002098 CodeCompletionString *Setter = new CodeCompletionString;
2099 Setter->AddTypedTextChunk("setter");
2100 Setter->AddTextChunk(" = ");
2101 Setter->AddPlaceholderChunk("method");
2102 Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
2103 }
Douglas Gregor988358f2009-11-19 00:14:45 +00002104 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002105 CodeCompletionString *Getter = new CodeCompletionString;
2106 Getter->AddTypedTextChunk("getter");
2107 Getter->AddTextChunk(" = ");
2108 Getter->AddPlaceholderChunk("method");
2109 Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
2110 }
Steve Naroffece8e712009-10-08 21:55:05 +00002111 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002112 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00002113}
Steve Naroffc4df6d22009-11-07 02:08:14 +00002114
Douglas Gregor4ad96852009-11-19 07:41:15 +00002115/// \brief Descripts the kind of Objective-C method that we want to find
2116/// via code completion.
2117enum ObjCMethodKind {
2118 MK_Any, //< Any kind of method, provided it means other specified criteria.
2119 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2120 MK_OneArgSelector //< One-argument selector.
2121};
2122
2123static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2124 ObjCMethodKind WantKind,
2125 IdentifierInfo **SelIdents,
2126 unsigned NumSelIdents) {
2127 Selector Sel = Method->getSelector();
2128 if (NumSelIdents > Sel.getNumArgs())
2129 return false;
2130
2131 switch (WantKind) {
2132 case MK_Any: break;
2133 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2134 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2135 }
2136
2137 for (unsigned I = 0; I != NumSelIdents; ++I)
2138 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2139 return false;
2140
2141 return true;
2142}
2143
Douglas Gregor36ecb042009-11-17 23:22:23 +00002144/// \brief Add all of the Objective-C methods in the given Objective-C
2145/// container to the set of results.
2146///
2147/// The container will be a class, protocol, category, or implementation of
2148/// any of the above. This mether will recurse to include methods from
2149/// the superclasses of classes along with their categories, protocols, and
2150/// implementations.
2151///
2152/// \param Container the container in which we'll look to find methods.
2153///
2154/// \param WantInstance whether to add instance methods (only); if false, this
2155/// routine will add factory methods (only).
2156///
2157/// \param CurContext the context in which we're performing the lookup that
2158/// finds methods.
2159///
2160/// \param Results the structure into which we'll add results.
2161static void AddObjCMethods(ObjCContainerDecl *Container,
2162 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00002163 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00002164 IdentifierInfo **SelIdents,
2165 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00002166 DeclContext *CurContext,
2167 ResultBuilder &Results) {
2168 typedef CodeCompleteConsumer::Result Result;
2169 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2170 MEnd = Container->meth_end();
2171 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002172 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2173 // Check whether the selector identifiers we've been given are a
2174 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002175 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00002176 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002177
Douglas Gregord3c68542009-11-19 01:08:35 +00002178 Result R = Result(*M, 0);
2179 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002180 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00002181 Results.MaybeAddResult(R, CurContext);
2182 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00002183 }
2184
2185 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2186 if (!IFace)
2187 return;
2188
2189 // Add methods in protocols.
2190 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2191 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2192 E = Protocols.end();
2193 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002194 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00002195 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002196
2197 // Add methods in categories.
2198 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2199 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00002200 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2201 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002202
2203 // Add a categories protocol methods.
2204 const ObjCList<ObjCProtocolDecl> &Protocols
2205 = CatDecl->getReferencedProtocols();
2206 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2207 E = Protocols.end();
2208 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002209 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2210 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002211
2212 // Add methods in category implementations.
2213 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002214 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2215 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002216 }
2217
2218 // Add methods in superclass.
2219 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002220 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2221 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002222
2223 // Add methods in our implementation, if any.
2224 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002225 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2226 NumSelIdents, CurContext, Results);
2227}
2228
2229
2230void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2231 DeclPtrTy *Methods,
2232 unsigned NumMethods) {
2233 typedef CodeCompleteConsumer::Result Result;
2234
2235 // Try to find the interface where getters might live.
2236 ObjCInterfaceDecl *Class
2237 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2238 if (!Class) {
2239 if (ObjCCategoryDecl *Category
2240 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2241 Class = Category->getClassInterface();
2242
2243 if (!Class)
2244 return;
2245 }
2246
2247 // Find all of the potential getters.
2248 ResultBuilder Results(*this);
2249 Results.EnterNewScope();
2250
2251 // FIXME: We need to do this because Objective-C methods don't get
2252 // pushed into DeclContexts early enough. Argh!
2253 for (unsigned I = 0; I != NumMethods; ++I) {
2254 if (ObjCMethodDecl *Method
2255 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2256 if (Method->isInstanceMethod() &&
2257 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2258 Result R = Result(Method, 0);
2259 R.AllParametersAreInformative = true;
2260 Results.MaybeAddResult(R, CurContext);
2261 }
2262 }
2263
2264 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2265 Results.ExitScope();
2266 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2267}
2268
2269void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2270 DeclPtrTy *Methods,
2271 unsigned NumMethods) {
2272 typedef CodeCompleteConsumer::Result Result;
2273
2274 // Try to find the interface where setters might live.
2275 ObjCInterfaceDecl *Class
2276 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2277 if (!Class) {
2278 if (ObjCCategoryDecl *Category
2279 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2280 Class = Category->getClassInterface();
2281
2282 if (!Class)
2283 return;
2284 }
2285
2286 // Find all of the potential getters.
2287 ResultBuilder Results(*this);
2288 Results.EnterNewScope();
2289
2290 // FIXME: We need to do this because Objective-C methods don't get
2291 // pushed into DeclContexts early enough. Argh!
2292 for (unsigned I = 0; I != NumMethods; ++I) {
2293 if (ObjCMethodDecl *Method
2294 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2295 if (Method->isInstanceMethod() &&
2296 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2297 Result R = Result(Method, 0);
2298 R.AllParametersAreInformative = true;
2299 Results.MaybeAddResult(R, CurContext);
2300 }
2301 }
2302
2303 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2304
2305 Results.ExitScope();
2306 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00002307}
2308
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002309void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregord3c68542009-11-19 01:08:35 +00002310 SourceLocation FNameLoc,
2311 IdentifierInfo **SelIdents,
2312 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002313 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00002314 ObjCInterfaceDecl *CDecl = 0;
2315
Douglas Gregor24a069f2009-11-17 17:59:40 +00002316 if (FName->isStr("super")) {
2317 // We're sending a message to "super".
2318 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2319 // Figure out which interface we're in.
2320 CDecl = CurMethod->getClassInterface();
2321 if (!CDecl)
2322 return;
2323
2324 // Find the superclass of this class.
2325 CDecl = CDecl->getSuperClass();
2326 if (!CDecl)
2327 return;
2328
2329 if (CurMethod->isInstanceMethod()) {
2330 // We are inside an instance method, which means that the message
2331 // send [super ...] is actually calling an instance method on the
2332 // current object. Build the super expression and handle this like
2333 // an instance method.
2334 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2335 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2336 OwningExprResult Super
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002337 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregord3c68542009-11-19 01:08:35 +00002338 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2339 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002340 }
2341
2342 // Okay, we're calling a factory method in our superclass.
2343 }
2344 }
2345
2346 // If the given name refers to an interface type, retrieve the
2347 // corresponding declaration.
2348 if (!CDecl)
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002349 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor24a069f2009-11-17 17:59:40 +00002350 QualType T = GetTypeFromParser(Ty, 0);
2351 if (!T.isNull())
2352 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
2353 CDecl = Interface->getDecl();
2354 }
2355
2356 if (!CDecl && FName->isStr("super")) {
2357 // "super" may be the name of a variable, in which case we are
2358 // probably calling an instance method.
John McCallf7a1a742009-11-24 19:00:30 +00002359 CXXScopeSpec SS;
2360 UnqualifiedId id;
2361 id.setIdentifier(FName, FNameLoc);
2362 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregord3c68542009-11-19 01:08:35 +00002363 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2364 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002365 }
2366
Douglas Gregor36ecb042009-11-17 23:22:23 +00002367 // Add all of the factory methods in this Objective-C class, its protocols,
2368 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00002369 ResultBuilder Results(*this);
2370 Results.EnterNewScope();
Douglas Gregor4ad96852009-11-19 07:41:15 +00002371 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
2372 Results);
Steve Naroffc4df6d22009-11-07 02:08:14 +00002373 Results.ExitScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00002374
Steve Naroffc4df6d22009-11-07 02:08:14 +00002375 // This also suppresses remaining diagnostics.
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002376 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00002377}
2378
Douglas Gregord3c68542009-11-19 01:08:35 +00002379void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
2380 IdentifierInfo **SelIdents,
2381 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002382 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00002383
2384 Expr *RecExpr = static_cast<Expr *>(Receiver);
2385 QualType RecType = RecExpr->getType();
2386
Douglas Gregor36ecb042009-11-17 23:22:23 +00002387 // If necessary, apply function/array conversion to the receiver.
2388 // C99 6.7.5.3p[7,8].
2389 DefaultFunctionArrayConversion(RecExpr);
2390 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00002391
Douglas Gregor36ecb042009-11-17 23:22:23 +00002392 if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType()) {
2393 // FIXME: We're messaging 'id'. Do we actually want to look up every method
2394 // in the universe?
2395 return;
2396 }
2397
Douglas Gregor36ecb042009-11-17 23:22:23 +00002398 // Build the set of methods we can see.
2399 ResultBuilder Results(*this);
2400 Results.EnterNewScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00002401
Douglas Gregorf74a4192009-11-18 00:06:18 +00002402 // Handle messages to Class. This really isn't a message to an instance
2403 // method, so we treat it the same way we would treat a message send to a
2404 // class method.
2405 if (ReceiverType->isObjCClassType() ||
2406 ReceiverType->isObjCQualifiedClassType()) {
2407 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2408 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002409 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
2410 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002411 }
2412 }
2413 // Handle messages to a qualified ID ("id<foo>").
2414 else if (const ObjCObjectPointerType *QualID
2415 = ReceiverType->getAsObjCQualifiedIdType()) {
2416 // Search protocols for instance methods.
2417 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
2418 E = QualID->qual_end();
2419 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002420 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2421 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002422 }
2423 // Handle messages to a pointer to interface type.
2424 else if (const ObjCObjectPointerType *IFacePtr
2425 = ReceiverType->getAsObjCInterfacePointerType()) {
2426 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002427 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
2428 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002429
2430 // Search protocols for instance methods.
2431 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
2432 E = IFacePtr->qual_end();
2433 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002434 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2435 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002436 }
2437
Steve Naroffc4df6d22009-11-07 02:08:14 +00002438 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002439 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00002440}
Douglas Gregor55385fe2009-11-18 04:19:12 +00002441
2442/// \brief Add all of the protocol declarations that we find in the given
2443/// (translation unit) context.
2444static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00002445 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00002446 ResultBuilder &Results) {
2447 typedef CodeCompleteConsumer::Result Result;
2448
2449 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2450 DEnd = Ctx->decls_end();
2451 D != DEnd; ++D) {
2452 // Record any protocols we find.
2453 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00002454 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
2455 Results.MaybeAddResult(Result(Proto, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002456
2457 // Record any forward-declared protocols we find.
2458 if (ObjCForwardProtocolDecl *Forward
2459 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
2460 for (ObjCForwardProtocolDecl::protocol_iterator
2461 P = Forward->protocol_begin(),
2462 PEnd = Forward->protocol_end();
2463 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00002464 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
2465 Results.MaybeAddResult(Result(*P, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002466 }
2467 }
2468}
2469
2470void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
2471 unsigned NumProtocols) {
2472 ResultBuilder Results(*this);
2473 Results.EnterNewScope();
2474
2475 // Tell the result set to ignore all of the protocols we have
2476 // already seen.
2477 for (unsigned I = 0; I != NumProtocols; ++I)
2478 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
2479 Results.Ignore(Protocol);
2480
2481 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00002482 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
2483 Results);
2484
2485 Results.ExitScope();
2486 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2487}
2488
2489void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
2490 ResultBuilder Results(*this);
2491 Results.EnterNewScope();
2492
2493 // Add all protocols.
2494 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
2495 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002496
2497 Results.ExitScope();
2498 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2499}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00002500
2501/// \brief Add all of the Objective-C interface declarations that we find in
2502/// the given (translation unit) context.
2503static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
2504 bool OnlyForwardDeclarations,
2505 bool OnlyUnimplemented,
2506 ResultBuilder &Results) {
2507 typedef CodeCompleteConsumer::Result Result;
2508
2509 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2510 DEnd = Ctx->decls_end();
2511 D != DEnd; ++D) {
2512 // Record any interfaces we find.
2513 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
2514 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
2515 (!OnlyUnimplemented || !Class->getImplementation()))
2516 Results.MaybeAddResult(Result(Class, 0), CurContext);
2517
2518 // Record any forward-declared interfaces we find.
2519 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
2520 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
2521 C != CEnd; ++C)
2522 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
2523 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
2524 Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
2525 }
2526 }
2527}
2528
2529void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
2530 ResultBuilder Results(*this);
2531 Results.EnterNewScope();
2532
2533 // Add all classes.
2534 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
2535 false, Results);
2536
2537 Results.ExitScope();
2538 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2539}
2540
2541void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
2542 ResultBuilder Results(*this);
2543 Results.EnterNewScope();
2544
2545 // Make sure that we ignore the class we're currently defining.
2546 NamedDecl *CurClass
2547 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00002548 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00002549 Results.Ignore(CurClass);
2550
2551 // Add all classes.
2552 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2553 false, Results);
2554
2555 Results.ExitScope();
2556 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2557}
2558
2559void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
2560 ResultBuilder Results(*this);
2561 Results.EnterNewScope();
2562
2563 // Add all unimplemented classes.
2564 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2565 true, Results);
2566
2567 Results.ExitScope();
2568 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2569}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00002570
2571void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
2572 IdentifierInfo *ClassName) {
2573 typedef CodeCompleteConsumer::Result Result;
2574
2575 ResultBuilder Results(*this);
2576
2577 // Ignore any categories we find that have already been implemented by this
2578 // interface.
2579 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2580 NamedDecl *CurClass
2581 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2582 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
2583 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2584 Category = Category->getNextClassCategory())
2585 CategoryNames.insert(Category->getIdentifier());
2586
2587 // Add all of the categories we know about.
2588 Results.EnterNewScope();
2589 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
2590 for (DeclContext::decl_iterator D = TU->decls_begin(),
2591 DEnd = TU->decls_end();
2592 D != DEnd; ++D)
2593 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
2594 if (CategoryNames.insert(Category->getIdentifier()))
2595 Results.MaybeAddResult(Result(Category, 0), CurContext);
2596 Results.ExitScope();
2597
2598 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2599}
2600
2601void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
2602 IdentifierInfo *ClassName) {
2603 typedef CodeCompleteConsumer::Result Result;
2604
2605 // Find the corresponding interface. If we couldn't find the interface, the
2606 // program itself is ill-formed. However, we'll try to be helpful still by
2607 // providing the list of all of the categories we know about.
2608 NamedDecl *CurClass
2609 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2610 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
2611 if (!Class)
2612 return CodeCompleteObjCInterfaceCategory(S, ClassName);
2613
2614 ResultBuilder Results(*this);
2615
2616 // Add all of the categories that have have corresponding interface
2617 // declarations in this class and any of its superclasses, except for
2618 // already-implemented categories in the class itself.
2619 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2620 Results.EnterNewScope();
2621 bool IgnoreImplemented = true;
2622 while (Class) {
2623 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2624 Category = Category->getNextClassCategory())
2625 if ((!IgnoreImplemented || !Category->getImplementation()) &&
2626 CategoryNames.insert(Category->getIdentifier()))
2627 Results.MaybeAddResult(Result(Category, 0), CurContext);
2628
2629 Class = Class->getSuperClass();
2630 IgnoreImplemented = false;
2631 }
2632 Results.ExitScope();
2633
2634 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2635}
Douglas Gregor322328b2009-11-18 22:32:06 +00002636
Douglas Gregor424b2a52009-11-18 22:56:13 +00002637void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00002638 typedef CodeCompleteConsumer::Result Result;
2639 ResultBuilder Results(*this);
2640
2641 // Figure out where this @synthesize lives.
2642 ObjCContainerDecl *Container
2643 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2644 if (!Container ||
2645 (!isa<ObjCImplementationDecl>(Container) &&
2646 !isa<ObjCCategoryImplDecl>(Container)))
2647 return;
2648
2649 // Ignore any properties that have already been implemented.
2650 for (DeclContext::decl_iterator D = Container->decls_begin(),
2651 DEnd = Container->decls_end();
2652 D != DEnd; ++D)
2653 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
2654 Results.Ignore(PropertyImpl->getPropertyDecl());
2655
2656 // Add any properties that we find.
2657 Results.EnterNewScope();
2658 if (ObjCImplementationDecl *ClassImpl
2659 = dyn_cast<ObjCImplementationDecl>(Container))
2660 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
2661 Results);
2662 else
2663 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
2664 false, CurContext, Results);
2665 Results.ExitScope();
2666
2667 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2668}
2669
2670void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
2671 IdentifierInfo *PropertyName,
2672 DeclPtrTy ObjCImpDecl) {
2673 typedef CodeCompleteConsumer::Result Result;
2674 ResultBuilder Results(*this);
2675
2676 // Figure out where this @synthesize lives.
2677 ObjCContainerDecl *Container
2678 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2679 if (!Container ||
2680 (!isa<ObjCImplementationDecl>(Container) &&
2681 !isa<ObjCCategoryImplDecl>(Container)))
2682 return;
2683
2684 // Figure out which interface we're looking into.
2685 ObjCInterfaceDecl *Class = 0;
2686 if (ObjCImplementationDecl *ClassImpl
2687 = dyn_cast<ObjCImplementationDecl>(Container))
2688 Class = ClassImpl->getClassInterface();
2689 else
2690 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
2691 ->getClassInterface();
2692
2693 // Add all of the instance variables in this class and its superclasses.
2694 Results.EnterNewScope();
2695 for(; Class; Class = Class->getSuperClass()) {
2696 // FIXME: We could screen the type of each ivar for compatibility with
2697 // the property, but is that being too paternal?
2698 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
2699 IVarEnd = Class->ivar_end();
2700 IVar != IVarEnd; ++IVar)
2701 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
2702 }
2703 Results.ExitScope();
2704
2705 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2706}