blob: b1452b9152876804b0e126d34414194fb5cd3fb3 [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
Douglas Gregor76282942009-12-11 17:31:05 +0000367 // Class template (partial) specializations are never added as results.
Douglas Gregore29ffaa2009-12-11 16:18:54 +0000368 if (isa<ClassTemplateSpecializationDecl>(CanonDecl) ||
369 isa<ClassTemplatePartialSpecializationDecl>(CanonDecl))
370 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000371
Douglas Gregor76282942009-12-11 17:31:05 +0000372 // Using declarations themselves are never added as results.
373 if (isa<UsingDecl>(CanonDecl))
374 return;
375
Douglas Gregor86d9a522009-09-21 16:56:56 +0000376 if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) {
377 // __va_list_tag is a freak of nature. Find it and skip it.
378 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
379 return;
380
Douglas Gregorf52cede2009-10-09 22:16:47 +0000381 // Filter out names reserved for the implementation (C99 7.1.3,
382 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbare013d682009-10-18 20:26:12 +0000383 //
384 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000385 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000386 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000387 if (Name[0] == '_' &&
388 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
389 return;
390 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000391 }
392
393 // C++ constructors are never found by name lookup.
394 if (isa<CXXConstructorDecl>(CanonDecl))
395 return;
396
397 // Filter out any unwanted results.
398 if (Filter && !(this->*Filter)(R.Declaration))
399 return;
400
401 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000402 ShadowMapEntry::iterator I, IEnd;
403 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
404 if (NamePos != SMap.end()) {
405 I = NamePos->second.begin();
406 IEnd = NamePos->second.end();
407 }
408
409 for (; I != IEnd; ++I) {
410 NamedDecl *ND = I->first;
411 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000412 if (ND->getCanonicalDecl() == CanonDecl) {
413 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000414 Results[Index].Declaration = R.Declaration;
415
416 // Pick the best rank of the two.
417 Results[Index].Rank = std::min(Results[Index].Rank, R.Rank);
418
419 // We're done.
420 return;
421 }
422 }
423
424 // This is a new declaration in this scope. However, check whether this
425 // declaration name is hidden by a similarly-named declaration in an outer
426 // scope.
427 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
428 --SMEnd;
429 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000430 ShadowMapEntry::iterator I, IEnd;
431 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
432 if (NamePos != SM->end()) {
433 I = NamePos->second.begin();
434 IEnd = NamePos->second.end();
435 }
436 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000437 // A tag declaration does not hide a non-tag declaration.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000438 if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000439 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
440 Decl::IDNS_ObjCProtocol)))
441 continue;
442
443 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000444 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000445 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000446 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000447 continue;
448
449 // The newly-added result is hidden by an entry in the shadow map.
450 if (canHiddenResultBeFound(SemaRef.getLangOptions(), R.Declaration,
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000451 I->first)) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000452 // Note that this result was hidden.
453 R.Hidden = true;
Douglas Gregor0563c262009-09-22 23:15:58 +0000454 R.QualifierIsInformative = false;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000455
456 if (!R.Qualifier)
457 R.Qualifier = getRequiredQualification(SemaRef.Context,
458 CurContext,
459 R.Declaration->getDeclContext());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000460 } else {
461 // This result was hidden and cannot be found; don't bother adding
462 // it.
463 return;
464 }
465
466 break;
467 }
468 }
469
470 // Make sure that any given declaration only shows up in the result set once.
471 if (!AllDeclsFound.insert(CanonDecl))
472 return;
473
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000474 // If the filter is for nested-name-specifiers, then this result starts a
475 // nested-name-specifier.
476 if ((Filter == &ResultBuilder::IsNestedNameSpecifier) ||
477 (Filter == &ResultBuilder::IsMember &&
478 isa<CXXRecordDecl>(R.Declaration) &&
479 cast<CXXRecordDecl>(R.Declaration)->isInjectedClassName()))
480 R.StartsNestedNameSpecifier = true;
481
Douglas Gregor0563c262009-09-22 23:15:58 +0000482 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000483 if (R.QualifierIsInformative && !R.Qualifier &&
484 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000485 DeclContext *Ctx = R.Declaration->getDeclContext();
486 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
487 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
488 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
489 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
490 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
491 else
492 R.QualifierIsInformative = false;
493 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000494
Douglas Gregor86d9a522009-09-21 16:56:56 +0000495 // Insert this result into the set of results and into the current shadow
496 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000497 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000498 Results.push_back(R);
499}
500
501/// \brief Enter into a new scope.
502void ResultBuilder::EnterNewScope() {
503 ShadowMaps.push_back(ShadowMap());
504}
505
506/// \brief Exit from the current scope.
507void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000508 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
509 EEnd = ShadowMaps.back().end();
510 E != EEnd;
511 ++E)
512 E->second.Destroy();
513
Douglas Gregor86d9a522009-09-21 16:56:56 +0000514 ShadowMaps.pop_back();
515}
516
Douglas Gregor791215b2009-09-21 20:51:25 +0000517/// \brief Determines whether this given declaration will be found by
518/// ordinary name lookup.
519bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
520 unsigned IDNS = Decl::IDNS_Ordinary;
521 if (SemaRef.getLangOptions().CPlusPlus)
522 IDNS |= Decl::IDNS_Tag;
523
524 return ND->getIdentifierNamespace() & IDNS;
525}
526
Douglas Gregor86d9a522009-09-21 16:56:56 +0000527/// \brief Determines whether the given declaration is suitable as the
528/// start of a C++ nested-name-specifier, e.g., a class or namespace.
529bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
530 // Allow us to find class templates, too.
531 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
532 ND = ClassTemplate->getTemplatedDecl();
533
534 return SemaRef.isAcceptableNestedNameSpecifier(ND);
535}
536
537/// \brief Determines whether the given declaration is an enumeration.
538bool ResultBuilder::IsEnum(NamedDecl *ND) const {
539 return isa<EnumDecl>(ND);
540}
541
542/// \brief Determines whether the given declaration is a class or struct.
543bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
544 // Allow us to find class templates, too.
545 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
546 ND = ClassTemplate->getTemplatedDecl();
547
548 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
549 return RD->getTagKind() == TagDecl::TK_class ||
550 RD->getTagKind() == TagDecl::TK_struct;
551
552 return false;
553}
554
555/// \brief Determines whether the given declaration is a union.
556bool ResultBuilder::IsUnion(NamedDecl *ND) const {
557 // Allow us to find class templates, too.
558 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
559 ND = ClassTemplate->getTemplatedDecl();
560
561 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
562 return RD->getTagKind() == TagDecl::TK_union;
563
564 return false;
565}
566
567/// \brief Determines whether the given declaration is a namespace.
568bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
569 return isa<NamespaceDecl>(ND);
570}
571
572/// \brief Determines whether the given declaration is a namespace or
573/// namespace alias.
574bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
575 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
576}
577
Douglas Gregor76282942009-12-11 17:31:05 +0000578/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000579bool ResultBuilder::IsType(NamedDecl *ND) const {
580 return isa<TypeDecl>(ND);
581}
582
Douglas Gregor76282942009-12-11 17:31:05 +0000583/// \brief Determines which members of a class should be visible via
584/// "." or "->". Only value declarations, nested name specifiers, and
585/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000586bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000587 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
588 ND = Using->getTargetDecl();
589
590 return isa<ValueDecl>(ND) || isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000591}
592
Douglas Gregor86d9a522009-09-21 16:56:56 +0000593// Find the next outer declaration context corresponding to this scope.
594static DeclContext *findOuterContext(Scope *S) {
595 for (S = S->getParent(); S; S = S->getParent())
596 if (S->getEntity())
597 return static_cast<DeclContext *>(S->getEntity())->getPrimaryContext();
598
599 return 0;
600}
601
602/// \brief Collect the results of searching for members within the given
603/// declaration context.
604///
605/// \param Ctx the declaration context from which we will gather results.
606///
Douglas Gregor0563c262009-09-22 23:15:58 +0000607/// \param Rank the rank given to results in this declaration context.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000608///
609/// \param Visited the set of declaration contexts that have already been
610/// visited. Declaration contexts will only be visited once.
611///
612/// \param Results the result set that will be extended with any results
613/// found within this declaration context (and, for a C++ class, its bases).
614///
Douglas Gregor0563c262009-09-22 23:15:58 +0000615/// \param InBaseClass whether we are in a base class.
616///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000617/// \returns the next higher rank value, after considering all of the
618/// names within this declaration context.
619static unsigned CollectMemberLookupResults(DeclContext *Ctx,
Douglas Gregor0563c262009-09-22 23:15:58 +0000620 unsigned Rank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000621 DeclContext *CurContext,
622 llvm::SmallPtrSet<DeclContext *, 16> &Visited,
Douglas Gregor0563c262009-09-22 23:15:58 +0000623 ResultBuilder &Results,
624 bool InBaseClass = false) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000625 // Make sure we don't visit the same context twice.
626 if (!Visited.insert(Ctx->getPrimaryContext()))
Douglas Gregor0563c262009-09-22 23:15:58 +0000627 return Rank;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000628
629 // Enumerate all of the results in this context.
Douglas Gregor0563c262009-09-22 23:15:58 +0000630 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000631 Results.EnterNewScope();
632 for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
633 CurCtx = CurCtx->getNextContext()) {
634 for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000635 DEnd = CurCtx->decls_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000636 D != DEnd; ++D) {
637 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
Douglas Gregor0563c262009-09-22 23:15:58 +0000638 Results.MaybeAddResult(Result(ND, Rank, 0, InBaseClass), CurContext);
Douglas Gregorff4393c2009-11-09 21:35:27 +0000639
640 // Visit transparent contexts inside this context.
641 if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
642 if (InnerCtx->isTransparentContext())
643 CollectMemberLookupResults(InnerCtx, Rank, CurContext, Visited,
644 Results, InBaseClass);
645 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000646 }
647 }
648
649 // Traverse the contexts of inherited classes.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000650 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
651 for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000652 BEnd = Record->bases_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000653 B != BEnd; ++B) {
654 QualType BaseType = B->getType();
655
656 // Don't look into dependent bases, because name lookup can't look
657 // there anyway.
658 if (BaseType->isDependentType())
659 continue;
660
661 const RecordType *Record = BaseType->getAs<RecordType>();
662 if (!Record)
663 continue;
664
665 // FIXME: It would be nice to be able to determine whether referencing
666 // a particular member would be ambiguous. For example, given
667 //
668 // struct A { int member; };
669 // struct B { int member; };
670 // struct C : A, B { };
671 //
672 // void f(C *c) { c->### }
673 // accessing 'member' would result in an ambiguity. However, code
674 // completion could be smart enough to qualify the member with the
675 // base class, e.g.,
676 //
677 // c->B::member
678 //
679 // or
680 //
681 // c->A::member
682
683 // Collect results from this base class (and its bases).
Douglas Gregor0563c262009-09-22 23:15:58 +0000684 CollectMemberLookupResults(Record->getDecl(), Rank, CurContext, Visited,
685 Results, /*InBaseClass=*/true);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000686 }
687 }
688
689 // FIXME: Look into base classes in Objective-C!
690
691 Results.ExitScope();
Douglas Gregor0563c262009-09-22 23:15:58 +0000692 return Rank + 1;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000693}
694
695/// \brief Collect the results of searching for members within the given
696/// declaration context.
697///
698/// \param Ctx the declaration context from which we will gather results.
699///
700/// \param InitialRank the initial rank given to results in this declaration
701/// context. Larger rank values will be used for, e.g., members found in
702/// base classes.
703///
704/// \param Results the result set that will be extended with any results
705/// found within this declaration context (and, for a C++ class, its bases).
706///
707/// \returns the next higher rank value, after considering all of the
708/// names within this declaration context.
709static unsigned CollectMemberLookupResults(DeclContext *Ctx,
710 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000711 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000712 ResultBuilder &Results) {
713 llvm::SmallPtrSet<DeclContext *, 16> Visited;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000714 return CollectMemberLookupResults(Ctx, InitialRank, CurContext, Visited,
715 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000716}
717
718/// \brief Collect the results of searching for declarations within the given
719/// scope and its parent scopes.
720///
721/// \param S the scope in which we will start looking for declarations.
722///
723/// \param InitialRank the initial rank given to results in this scope.
724/// Larger rank values will be used for results found in parent scopes.
725///
Douglas Gregor456c4a12009-09-21 20:12:40 +0000726/// \param CurContext the context from which lookup results will be found.
727///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000728/// \param Results the builder object that will receive each result.
729static unsigned CollectLookupResults(Scope *S,
730 TranslationUnitDecl *TranslationUnit,
731 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000732 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000733 ResultBuilder &Results) {
734 if (!S)
735 return InitialRank;
736
737 // FIXME: Using directives!
738
739 unsigned NextRank = InitialRank;
740 Results.EnterNewScope();
741 if (S->getEntity() &&
742 !((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
743 // Look into this scope's declaration context, along with any of its
744 // parent lookup contexts (e.g., enclosing classes), up to the point
745 // where we hit the context stored in the next outer scope.
746 DeclContext *Ctx = (DeclContext *)S->getEntity();
747 DeclContext *OuterCtx = findOuterContext(S);
748
749 for (; Ctx && Ctx->getPrimaryContext() != OuterCtx;
750 Ctx = Ctx->getLookupParent()) {
751 if (Ctx->isFunctionOrMethod())
752 continue;
753
Douglas Gregor456c4a12009-09-21 20:12:40 +0000754 NextRank = CollectMemberLookupResults(Ctx, NextRank + 1, CurContext,
755 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000756 }
757 } else if (!S->getParent()) {
758 // Look into the translation unit scope. We walk through the translation
759 // unit's declaration context, because the Scope itself won't have all of
760 // the declarations if we loaded a precompiled header.
761 // FIXME: We would like the translation unit's Scope object to point to the
762 // translation unit, so we don't need this special "if" branch. However,
763 // doing so would force the normal C++ name-lookup code to look into the
764 // translation unit decl when the IdentifierInfo chains would suffice.
765 // Once we fix that problem (which is part of a more general "don't look
766 // in DeclContexts unless we have to" optimization), we can eliminate the
767 // TranslationUnit parameter entirely.
768 NextRank = CollectMemberLookupResults(TranslationUnit, NextRank + 1,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000769 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000770 } else {
771 // Walk through the declarations in this Scope.
772 for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
773 D != DEnd; ++D) {
774 if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
Douglas Gregor456c4a12009-09-21 20:12:40 +0000775 Results.MaybeAddResult(CodeCompleteConsumer::Result(ND, NextRank),
776 CurContext);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000777 }
778
779 NextRank = NextRank + 1;
780 }
781
782 // Lookup names in the parent scope.
783 NextRank = CollectLookupResults(S->getParent(), TranslationUnit, NextRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000784 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000785 Results.ExitScope();
786
787 return NextRank;
788}
789
790/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregor9a0c85e2009-12-07 09:51:25 +0000791static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000792 ResultBuilder &Results) {
793 typedef CodeCompleteConsumer::Result Result;
794 Results.MaybeAddResult(Result("short", Rank));
795 Results.MaybeAddResult(Result("long", Rank));
796 Results.MaybeAddResult(Result("signed", Rank));
797 Results.MaybeAddResult(Result("unsigned", Rank));
798 Results.MaybeAddResult(Result("void", Rank));
799 Results.MaybeAddResult(Result("char", Rank));
800 Results.MaybeAddResult(Result("int", Rank));
801 Results.MaybeAddResult(Result("float", Rank));
802 Results.MaybeAddResult(Result("double", Rank));
803 Results.MaybeAddResult(Result("enum", Rank));
804 Results.MaybeAddResult(Result("struct", Rank));
805 Results.MaybeAddResult(Result("union", Rank));
806
807 if (LangOpts.C99) {
808 // C99-specific
809 Results.MaybeAddResult(Result("_Complex", Rank));
810 Results.MaybeAddResult(Result("_Imaginary", Rank));
811 Results.MaybeAddResult(Result("_Bool", Rank));
812 }
813
814 if (LangOpts.CPlusPlus) {
815 // C++-specific
816 Results.MaybeAddResult(Result("bool", Rank));
817 Results.MaybeAddResult(Result("class", Rank));
818 Results.MaybeAddResult(Result("typename", Rank));
819 Results.MaybeAddResult(Result("wchar_t", Rank));
820
821 if (LangOpts.CPlusPlus0x) {
822 Results.MaybeAddResult(Result("char16_t", Rank));
823 Results.MaybeAddResult(Result("char32_t", Rank));
824 Results.MaybeAddResult(Result("decltype", Rank));
825 }
826 }
827
828 // GNU extensions
829 if (LangOpts.GNUMode) {
830 // FIXME: Enable when we actually support decimal floating point.
831 // Results.MaybeAddResult(Result("_Decimal32", Rank));
832 // Results.MaybeAddResult(Result("_Decimal64", Rank));
833 // Results.MaybeAddResult(Result("_Decimal128", Rank));
834 Results.MaybeAddResult(Result("typeof", Rank));
835 }
836}
837
838/// \brief Add function parameter chunks to the given code completion string.
839static void AddFunctionParameterChunks(ASTContext &Context,
840 FunctionDecl *Function,
841 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000842 typedef CodeCompletionString::Chunk Chunk;
843
Douglas Gregor86d9a522009-09-21 16:56:56 +0000844 CodeCompletionString *CCStr = Result;
845
846 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
847 ParmVarDecl *Param = Function->getParamDecl(P);
848
849 if (Param->hasDefaultArg()) {
850 // When we see an optional default argument, put that argument and
851 // the remaining default arguments into a new, optional string.
852 CodeCompletionString *Opt = new CodeCompletionString;
853 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
854 CCStr = Opt;
855 }
856
857 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000858 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000859
860 // Format the placeholder string.
861 std::string PlaceholderStr;
862 if (Param->getIdentifier())
863 PlaceholderStr = Param->getIdentifier()->getName();
864
865 Param->getType().getAsStringInternal(PlaceholderStr,
866 Context.PrintingPolicy);
867
868 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +0000869 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000870 }
Douglas Gregorb3d45252009-09-22 21:42:17 +0000871
872 if (const FunctionProtoType *Proto
873 = Function->getType()->getAs<FunctionProtoType>())
874 if (Proto->isVariadic())
875 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +0000876}
877
878/// \brief Add template parameter chunks to the given code completion string.
879static void AddTemplateParameterChunks(ASTContext &Context,
880 TemplateDecl *Template,
881 CodeCompletionString *Result,
882 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000883 typedef CodeCompletionString::Chunk Chunk;
884
Douglas Gregor86d9a522009-09-21 16:56:56 +0000885 CodeCompletionString *CCStr = Result;
886 bool FirstParameter = true;
887
888 TemplateParameterList *Params = Template->getTemplateParameters();
889 TemplateParameterList::iterator PEnd = Params->end();
890 if (MaxParameters)
891 PEnd = Params->begin() + MaxParameters;
892 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
893 bool HasDefaultArg = false;
894 std::string PlaceholderStr;
895 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
896 if (TTP->wasDeclaredWithTypename())
897 PlaceholderStr = "typename";
898 else
899 PlaceholderStr = "class";
900
901 if (TTP->getIdentifier()) {
902 PlaceholderStr += ' ';
903 PlaceholderStr += TTP->getIdentifier()->getName();
904 }
905
906 HasDefaultArg = TTP->hasDefaultArgument();
907 } else if (NonTypeTemplateParmDecl *NTTP
908 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
909 if (NTTP->getIdentifier())
910 PlaceholderStr = NTTP->getIdentifier()->getName();
911 NTTP->getType().getAsStringInternal(PlaceholderStr,
912 Context.PrintingPolicy);
913 HasDefaultArg = NTTP->hasDefaultArgument();
914 } else {
915 assert(isa<TemplateTemplateParmDecl>(*P));
916 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
917
918 // Since putting the template argument list into the placeholder would
919 // be very, very long, we just use an abbreviation.
920 PlaceholderStr = "template<...> class";
921 if (TTP->getIdentifier()) {
922 PlaceholderStr += ' ';
923 PlaceholderStr += TTP->getIdentifier()->getName();
924 }
925
926 HasDefaultArg = TTP->hasDefaultArgument();
927 }
928
929 if (HasDefaultArg) {
930 // When we see an optional default argument, put that argument and
931 // the remaining default arguments into a new, optional string.
932 CodeCompletionString *Opt = new CodeCompletionString;
933 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
934 CCStr = Opt;
935 }
936
937 if (FirstParameter)
938 FirstParameter = false;
939 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000940 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000941
942 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +0000943 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000944 }
945}
946
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000947/// \brief Add a qualifier to the given code-completion string, if the
948/// provided nested-name-specifier is non-NULL.
949void AddQualifierToCompletionString(CodeCompletionString *Result,
950 NestedNameSpecifier *Qualifier,
Douglas Gregor0563c262009-09-22 23:15:58 +0000951 bool QualifierIsInformative,
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000952 ASTContext &Context) {
953 if (!Qualifier)
954 return;
955
956 std::string PrintedNNS;
957 {
958 llvm::raw_string_ostream OS(PrintedNNS);
959 Qualifier->print(OS, Context.PrintingPolicy);
960 }
Douglas Gregor0563c262009-09-22 23:15:58 +0000961 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +0000962 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +0000963 else
Benjamin Kramer660cc182009-11-29 20:18:50 +0000964 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000965}
966
Douglas Gregor86d9a522009-09-21 16:56:56 +0000967/// \brief If possible, create a new code completion string for the given
968/// result.
969///
970/// \returns Either a new, heap-allocated code completion string describing
971/// how to use this result, or NULL to indicate that the string or name of the
972/// result is all that is needed.
973CodeCompletionString *
974CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000975 typedef CodeCompletionString::Chunk Chunk;
976
Douglas Gregor2b4074f2009-12-01 05:55:20 +0000977 if (Kind == RK_Pattern)
978 return Pattern->Clone();
979
980 CodeCompletionString *Result = new CodeCompletionString;
981
982 if (Kind == RK_Keyword) {
983 Result->AddTypedTextChunk(Keyword);
984 return Result;
985 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000986
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000987 if (Kind == RK_Macro) {
988 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +0000989 assert(MI && "Not a macro?");
990
991 Result->AddTypedTextChunk(Macro->getName());
992
993 if (!MI->isFunctionLike())
994 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000995
996 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000997 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +0000998 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
999 A != AEnd; ++A) {
1000 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001001 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001002
1003 if (!MI->isVariadic() || A != AEnd - 1) {
1004 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001005 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001006 continue;
1007 }
1008
1009 // Variadic argument; cope with the different between GNU and C99
1010 // variadic macros, providing a single placeholder for the rest of the
1011 // arguments.
1012 if ((*A)->isStr("__VA_ARGS__"))
1013 Result->AddPlaceholderChunk("...");
1014 else {
1015 std::string Arg = (*A)->getName();
1016 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001017 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001018 }
1019 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001020 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001021 return Result;
1022 }
1023
1024 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001025 NamedDecl *ND = Declaration;
1026
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001027 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001028 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001029 Result->AddTextChunk("::");
1030 return Result;
1031 }
1032
Douglas Gregor86d9a522009-09-21 16:56:56 +00001033 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001034 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1035 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001036 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001037 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001038 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001039 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001040 return Result;
1041 }
1042
1043 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001044 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1045 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001046 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001047 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001048
1049 // Figure out which template parameters are deduced (or have default
1050 // arguments).
1051 llvm::SmallVector<bool, 16> Deduced;
1052 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1053 unsigned LastDeducibleArgument;
1054 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1055 --LastDeducibleArgument) {
1056 if (!Deduced[LastDeducibleArgument - 1]) {
1057 // C++0x: Figure out if the template argument has a default. If so,
1058 // the user doesn't need to type this argument.
1059 // FIXME: We need to abstract template parameters better!
1060 bool HasDefaultArg = false;
1061 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1062 LastDeducibleArgument - 1);
1063 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1064 HasDefaultArg = TTP->hasDefaultArgument();
1065 else if (NonTypeTemplateParmDecl *NTTP
1066 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1067 HasDefaultArg = NTTP->hasDefaultArgument();
1068 else {
1069 assert(isa<TemplateTemplateParmDecl>(Param));
1070 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001071 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001072 }
1073
1074 if (!HasDefaultArg)
1075 break;
1076 }
1077 }
1078
1079 if (LastDeducibleArgument) {
1080 // Some of the function template arguments cannot be deduced from a
1081 // function call, so we introduce an explicit template argument list
1082 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001083 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001084 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1085 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001086 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001087 }
1088
1089 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001090 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001091 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001092 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001093 return Result;
1094 }
1095
1096 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001097 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1098 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001099 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001100 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001101 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001102 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001103 return Result;
1104 }
1105
Douglas Gregor9630eb62009-11-17 16:44:22 +00001106 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001107 Selector Sel = Method->getSelector();
1108 if (Sel.isUnarySelector()) {
1109 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1110 return Result;
1111 }
1112
Douglas Gregord3c68542009-11-19 01:08:35 +00001113 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1114 SelName += ':';
1115 if (StartParameter == 0)
1116 Result->AddTypedTextChunk(SelName);
1117 else {
1118 Result->AddInformativeChunk(SelName);
1119
1120 // If there is only one parameter, and we're past it, add an empty
1121 // typed-text chunk since there is nothing to type.
1122 if (Method->param_size() == 1)
1123 Result->AddTypedTextChunk("");
1124 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001125 unsigned Idx = 0;
1126 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1127 PEnd = Method->param_end();
1128 P != PEnd; (void)++P, ++Idx) {
1129 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001130 std::string Keyword;
1131 if (Idx > StartParameter)
1132 Keyword = " ";
Douglas Gregor9630eb62009-11-17 16:44:22 +00001133 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1134 Keyword += II->getName().str();
1135 Keyword += ":";
Douglas Gregor4ad96852009-11-19 07:41:15 +00001136 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001137 Result->AddInformativeChunk(Keyword);
1138 } else if (Idx == StartParameter)
1139 Result->AddTypedTextChunk(Keyword);
1140 else
1141 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001142 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001143
1144 // If we're before the starting parameter, skip the placeholder.
1145 if (Idx < StartParameter)
1146 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001147
1148 std::string Arg;
1149 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1150 Arg = "(" + Arg + ")";
1151 if (IdentifierInfo *II = (*P)->getIdentifier())
1152 Arg += II->getName().str();
Douglas Gregor4ad96852009-11-19 07:41:15 +00001153 if (AllParametersAreInformative)
1154 Result->AddInformativeChunk(Arg);
1155 else
1156 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001157 }
1158
1159 return Result;
1160 }
1161
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001162 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00001163 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1164 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001165
1166 Result->AddTypedTextChunk(ND->getNameAsString());
1167 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001168}
1169
Douglas Gregor86d802e2009-09-23 00:34:09 +00001170CodeCompletionString *
1171CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1172 unsigned CurrentArg,
1173 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001174 typedef CodeCompletionString::Chunk Chunk;
1175
Douglas Gregor86d802e2009-09-23 00:34:09 +00001176 CodeCompletionString *Result = new CodeCompletionString;
1177 FunctionDecl *FDecl = getFunction();
1178 const FunctionProtoType *Proto
1179 = dyn_cast<FunctionProtoType>(getFunctionType());
1180 if (!FDecl && !Proto) {
1181 // Function without a prototype. Just give the return type and a
1182 // highlighted ellipsis.
1183 const FunctionType *FT = getFunctionType();
1184 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001185 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001186 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1187 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1188 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001189 return Result;
1190 }
1191
1192 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001193 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00001194 else
1195 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001196 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001197
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001198 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001199 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1200 for (unsigned I = 0; I != NumParams; ++I) {
1201 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001202 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001203
1204 std::string ArgString;
1205 QualType ArgType;
1206
1207 if (FDecl) {
1208 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1209 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1210 } else {
1211 ArgType = Proto->getArgType(I);
1212 }
1213
1214 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1215
1216 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001217 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00001218 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001219 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001220 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001221 }
1222
1223 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001224 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001225 if (CurrentArg < NumParams)
1226 Result->AddTextChunk("...");
1227 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001228 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001229 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001230 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001231
1232 return Result;
1233}
1234
Douglas Gregor86d9a522009-09-21 16:56:56 +00001235namespace {
1236 struct SortCodeCompleteResult {
1237 typedef CodeCompleteConsumer::Result Result;
1238
Douglas Gregor6a684032009-09-28 03:51:44 +00001239 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001240 Selector XSel = X.getObjCSelector();
1241 Selector YSel = Y.getObjCSelector();
1242 if (!XSel.isNull() && !YSel.isNull()) {
1243 // We are comparing two selectors.
1244 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1245 if (N == 0)
1246 ++N;
1247 for (unsigned I = 0; I != N; ++I) {
1248 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1249 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1250 if (!XId || !YId)
1251 return XId && !YId;
1252
1253 switch (XId->getName().compare_lower(YId->getName())) {
1254 case -1: return true;
1255 case 1: return false;
1256 default: break;
1257 }
1258 }
1259
1260 return XSel.getNumArgs() < YSel.getNumArgs();
1261 }
1262
1263 // For non-selectors, order by kind.
1264 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00001265 return X.getNameKind() < Y.getNameKind();
1266
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001267 // Order identifiers by comparison of their lowercased names.
1268 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1269 return XId->getName().compare_lower(
1270 Y.getAsIdentifierInfo()->getName()) < 0;
1271
1272 // Order overloaded operators by the order in which they appear
1273 // in our list of operators.
1274 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1275 return XOp < Y.getCXXOverloadedOperator();
1276
1277 // Order C++0x user-defined literal operators lexically by their
1278 // lowercased suffixes.
1279 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1280 return XLit->getName().compare_lower(
1281 Y.getCXXLiteralIdentifier()->getName()) < 0;
1282
1283 // The only stable ordering we have is to turn the name into a
1284 // string and then compare the lower-case strings. This is
1285 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00001286 return llvm::StringRef(X.getAsString()).compare_lower(
1287 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00001288 }
1289
Douglas Gregor86d9a522009-09-21 16:56:56 +00001290 bool operator()(const Result &X, const Result &Y) const {
1291 // Sort first by rank.
1292 if (X.Rank < Y.Rank)
1293 return true;
1294 else if (X.Rank > Y.Rank)
1295 return false;
1296
Douglas Gregor54f01612009-11-19 00:01:57 +00001297 // We use a special ordering for keywords and patterns, based on the
1298 // typed text.
1299 if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
1300 (Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
1301 const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword
1302 : X.Pattern->getTypedText();
1303 const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
1304 : Y.Pattern->getTypedText();
Benjamin Kramerf42d4882009-12-05 10:07:04 +00001305 return llvm::StringRef(XStr).compare_lower(YStr) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001306 }
1307
Douglas Gregor86d9a522009-09-21 16:56:56 +00001308 // Result kinds are ordered by decreasing importance.
1309 if (X.Kind < Y.Kind)
1310 return true;
1311 else if (X.Kind > Y.Kind)
1312 return false;
1313
1314 // Non-hidden names precede hidden names.
1315 if (X.Hidden != Y.Hidden)
1316 return !X.Hidden;
1317
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001318 // Non-nested-name-specifiers precede nested-name-specifiers.
1319 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1320 return !X.StartsNestedNameSpecifier;
1321
Douglas Gregor86d9a522009-09-21 16:56:56 +00001322 // Ordering depends on the kind of result.
1323 switch (X.Kind) {
1324 case Result::RK_Declaration:
1325 // Order based on the declaration names.
Douglas Gregor6a684032009-09-28 03:51:44 +00001326 return isEarlierDeclarationName(X.Declaration->getDeclName(),
1327 Y.Declaration->getDeclName());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001328
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001329 case Result::RK_Macro:
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001330 return X.Macro->getName().compare_lower(Y.Macro->getName()) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001331
1332 case Result::RK_Keyword:
1333 case Result::RK_Pattern:
1334 llvm::llvm_unreachable("Result kinds handled above");
1335 break;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001336 }
1337
1338 // Silence GCC warning.
1339 return false;
1340 }
1341 };
1342}
1343
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001344static void AddMacroResults(Preprocessor &PP, unsigned Rank,
1345 ResultBuilder &Results) {
1346 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001347 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1348 MEnd = PP.macro_end();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001349 M != MEnd; ++M)
1350 Results.MaybeAddResult(CodeCompleteConsumer::Result(M->first, Rank));
1351 Results.ExitScope();
1352}
1353
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001354static void HandleCodeCompleteResults(Sema *S,
1355 CodeCompleteConsumer *CodeCompleter,
1356 CodeCompleteConsumer::Result *Results,
1357 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001358 // Sort the results by rank/kind/etc.
1359 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1360
1361 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001362 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00001363
1364 for (unsigned I = 0; I != NumResults; ++I)
1365 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001366}
1367
Douglas Gregor791215b2009-09-21 20:51:25 +00001368void Sema::CodeCompleteOrdinaryName(Scope *S) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001369 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor791215b2009-09-21 20:51:25 +00001370 ResultBuilder Results(*this, &ResultBuilder::IsOrdinaryName);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001371 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1372 0, CurContext, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001373
1374 Results.EnterNewScope();
1375 AddTypeSpecifierResults(getLangOptions(), NextRank, Results);
1376
1377 if (getLangOptions().ObjC1) {
1378 // Add the "super" keyword, if appropriate.
1379 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
1380 if (Method->getClassInterface()->getSuperClass())
1381 Results.MaybeAddResult(Result("super", NextRank));
1382 }
1383
1384 Results.ExitScope();
1385
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001386 if (CodeCompleter->includeMacros())
1387 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001388 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00001389}
1390
Douglas Gregor95ac6552009-11-18 01:29:26 +00001391static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00001392 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00001393 DeclContext *CurContext,
1394 ResultBuilder &Results) {
1395 typedef CodeCompleteConsumer::Result Result;
1396
1397 // Add properties in this container.
1398 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1399 PEnd = Container->prop_end();
1400 P != PEnd;
1401 ++P)
1402 Results.MaybeAddResult(Result(*P, 0), CurContext);
1403
1404 // Add properties in referenced protocols.
1405 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1406 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1407 PEnd = Protocol->protocol_end();
1408 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001409 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001410 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00001411 if (AllowCategories) {
1412 // Look through categories.
1413 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1414 Category; Category = Category->getNextClassCategory())
1415 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1416 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001417
1418 // Look through protocols.
1419 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1420 E = IFace->protocol_end();
1421 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001422 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001423
1424 // Look in the superclass.
1425 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00001426 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
1427 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001428 } else if (const ObjCCategoryDecl *Category
1429 = dyn_cast<ObjCCategoryDecl>(Container)) {
1430 // Look through protocols.
1431 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
1432 PEnd = Category->protocol_end();
1433 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001434 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001435 }
1436}
1437
Douglas Gregor81b747b2009-09-17 21:32:03 +00001438void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
1439 SourceLocation OpLoc,
1440 bool IsArrow) {
1441 if (!BaseE || !CodeCompleter)
1442 return;
1443
Douglas Gregor86d9a522009-09-21 16:56:56 +00001444 typedef CodeCompleteConsumer::Result Result;
1445
Douglas Gregor81b747b2009-09-17 21:32:03 +00001446 Expr *Base = static_cast<Expr *>(BaseE);
1447 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001448
1449 if (IsArrow) {
1450 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1451 BaseType = Ptr->getPointeeType();
1452 else if (BaseType->isObjCObjectPointerType())
1453 /*Do nothing*/ ;
1454 else
1455 return;
1456 }
1457
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001458 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001459 unsigned NextRank = 0;
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001460
Douglas Gregor95ac6552009-11-18 01:29:26 +00001461 Results.EnterNewScope();
1462 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
1463 // Access to a C/C++ class, struct, or union.
1464 NextRank = CollectMemberLookupResults(Record->getDecl(), NextRank,
1465 Record->getDecl(), Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001466
Douglas Gregor95ac6552009-11-18 01:29:26 +00001467 if (getLangOptions().CPlusPlus) {
1468 if (!Results.empty()) {
1469 // The "template" keyword can follow "->" or "." in the grammar.
1470 // However, we only want to suggest the template keyword if something
1471 // is dependent.
1472 bool IsDependent = BaseType->isDependentType();
1473 if (!IsDependent) {
1474 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
1475 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
1476 IsDependent = Ctx->isDependentContext();
1477 break;
1478 }
1479 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001480
Douglas Gregor95ac6552009-11-18 01:29:26 +00001481 if (IsDependent)
1482 Results.MaybeAddResult(Result("template", NextRank++));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001483 }
1484
Douglas Gregor95ac6552009-11-18 01:29:26 +00001485 // We could have the start of a nested-name-specifier. Add those
1486 // results as well.
Douglas Gregor76282942009-12-11 17:31:05 +00001487 // FIXME: We should really walk base classes to produce
1488 // nested-name-specifiers so that we produce more-precise results.
Douglas Gregor95ac6552009-11-18 01:29:26 +00001489 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
1490 CollectLookupResults(S, Context.getTranslationUnitDecl(), NextRank,
1491 CurContext, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001492 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001493 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
1494 // Objective-C property reference.
1495
1496 // Add property results based on our interface.
1497 const ObjCObjectPointerType *ObjCPtr
1498 = BaseType->getAsObjCInterfacePointerType();
1499 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00001500 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001501
1502 // Add properties from the protocols in a qualified interface.
1503 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
1504 E = ObjCPtr->qual_end();
1505 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001506 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001507
1508 // FIXME: We could (should?) also look for "implicit" properties, identified
1509 // only by the presence of nullary and unary selectors.
1510 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
1511 (!IsArrow && BaseType->isObjCInterfaceType())) {
1512 // Objective-C instance variable access.
1513 ObjCInterfaceDecl *Class = 0;
1514 if (const ObjCObjectPointerType *ObjCPtr
1515 = BaseType->getAs<ObjCObjectPointerType>())
1516 Class = ObjCPtr->getInterfaceDecl();
1517 else
1518 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
1519
1520 // Add all ivars from this class and its superclasses.
1521 for (; Class; Class = Class->getSuperClass()) {
1522 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
1523 IVarEnd = Class->ivar_end();
1524 IVar != IVarEnd; ++IVar)
1525 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
1526 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001527 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001528
1529 // FIXME: How do we cope with isa?
1530
1531 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001532
1533 // Add macros
1534 if (CodeCompleter->includeMacros())
1535 AddMacroResults(PP, NextRank, Results);
1536
1537 // Hand off the results found for code completion.
1538 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00001539}
1540
Douglas Gregor374929f2009-09-18 15:37:17 +00001541void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
1542 if (!CodeCompleter)
1543 return;
1544
Douglas Gregor86d9a522009-09-21 16:56:56 +00001545 typedef CodeCompleteConsumer::Result Result;
1546 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00001547 switch ((DeclSpec::TST)TagSpec) {
1548 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001549 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00001550 break;
1551
1552 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001553 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00001554 break;
1555
1556 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00001557 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001558 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00001559 break;
1560
1561 default:
1562 assert(false && "Unknown type specifier kind in CodeCompleteTag");
1563 return;
1564 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001565
1566 ResultBuilder Results(*this, Filter);
1567 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00001568 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001569
1570 if (getLangOptions().CPlusPlus) {
1571 // We could have the start of a nested-name-specifier. Add those
1572 // results as well.
1573 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001574 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1575 NextRank, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001576 }
1577
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001578 if (CodeCompleter->includeMacros())
1579 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001580 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00001581}
1582
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001583void Sema::CodeCompleteCase(Scope *S) {
1584 if (getSwitchStack().empty() || !CodeCompleter)
1585 return;
1586
1587 SwitchStmt *Switch = getSwitchStack().back();
1588 if (!Switch->getCond()->getType()->isEnumeralType())
1589 return;
1590
1591 // Code-complete the cases of a switch statement over an enumeration type
1592 // by providing the list of
1593 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
1594
1595 // Determine which enumerators we have already seen in the switch statement.
1596 // FIXME: Ideally, we would also be able to look *past* the code-completion
1597 // token, in case we are code-completing in the middle of the switch and not
1598 // at the end. However, we aren't able to do so at the moment.
1599 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001600 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001601 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
1602 SC = SC->getNextSwitchCase()) {
1603 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
1604 if (!Case)
1605 continue;
1606
1607 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
1608 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
1609 if (EnumConstantDecl *Enumerator
1610 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
1611 // We look into the AST of the case statement to determine which
1612 // enumerator was named. Alternatively, we could compute the value of
1613 // the integral constant expression, then compare it against the
1614 // values of each enumerator. However, value-based approach would not
1615 // work as well with C++ templates where enumerators declared within a
1616 // template are type- and value-dependent.
1617 EnumeratorsSeen.insert(Enumerator);
1618
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001619 // If this is a qualified-id, keep track of the nested-name-specifier
1620 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001621 //
1622 // switch (TagD.getKind()) {
1623 // case TagDecl::TK_enum:
1624 // break;
1625 // case XXX
1626 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001627 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001628 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
1629 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00001630 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001631 }
1632 }
1633
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001634 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
1635 // If there are no prior enumerators in C++, check whether we have to
1636 // qualify the names of the enumerators that we suggest, because they
1637 // may not be visible in this scope.
1638 Qualifier = getRequiredQualification(Context, CurContext,
1639 Enum->getDeclContext());
1640
1641 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
1642 }
1643
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001644 // Add any enumerators that have not yet been mentioned.
1645 ResultBuilder Results(*this);
1646 Results.EnterNewScope();
1647 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
1648 EEnd = Enum->enumerator_end();
1649 E != EEnd; ++E) {
1650 if (EnumeratorsSeen.count(*E))
1651 continue;
1652
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001653 Results.MaybeAddResult(CodeCompleteConsumer::Result(*E, 0, Qualifier));
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001654 }
1655 Results.ExitScope();
1656
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001657 if (CodeCompleter->includeMacros())
1658 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001659 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001660}
1661
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001662namespace {
1663 struct IsBetterOverloadCandidate {
1664 Sema &S;
1665
1666 public:
1667 explicit IsBetterOverloadCandidate(Sema &S) : S(S) { }
1668
1669 bool
1670 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
1671 return S.isBetterOverloadCandidate(X, Y);
1672 }
1673 };
1674}
1675
1676void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
1677 ExprTy **ArgsIn, unsigned NumArgs) {
1678 if (!CodeCompleter)
1679 return;
1680
1681 Expr *Fn = (Expr *)FnIn;
1682 Expr **Args = (Expr **)ArgsIn;
1683
1684 // Ignore type-dependent call expressions entirely.
1685 if (Fn->isTypeDependent() ||
1686 Expr::hasAnyTypeDependentArguments(Args, NumArgs))
1687 return;
1688
John McCallba135432009-11-21 08:51:07 +00001689 llvm::SmallVector<NamedDecl*,8> Fns;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001690 DeclarationName UnqualifiedName;
1691 NestedNameSpecifier *Qualifier;
1692 SourceRange QualifierRange;
1693 bool ArgumentDependentLookup;
John McCall7453ed42009-11-22 00:44:51 +00001694 bool Overloaded;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001695 bool HasExplicitTemplateArgs;
John McCalld5532b62009-11-23 01:53:49 +00001696 TemplateArgumentListInfo ExplicitTemplateArgs;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001697
John McCallba135432009-11-21 08:51:07 +00001698 DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
John McCall7453ed42009-11-22 00:44:51 +00001699 ArgumentDependentLookup, Overloaded,
John McCalld5532b62009-11-23 01:53:49 +00001700 HasExplicitTemplateArgs, ExplicitTemplateArgs);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001701
1702
1703 // FIXME: What if we're calling something that isn't a function declaration?
1704 // FIXME: What if we're calling a pseudo-destructor?
1705 // FIXME: What if we're calling a member function?
1706
1707 // Build an overload candidate set based on the functions we find.
1708 OverloadCandidateSet CandidateSet;
John McCallba135432009-11-21 08:51:07 +00001709 AddOverloadedCallCandidates(Fns, UnqualifiedName,
John McCalld5532b62009-11-23 01:53:49 +00001710 ArgumentDependentLookup,
1711 (HasExplicitTemplateArgs ? &ExplicitTemplateArgs : 0),
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001712 Args, NumArgs,
1713 CandidateSet,
1714 /*PartialOverloading=*/true);
1715
1716 // Sort the overload candidate set by placing the best overloads first.
1717 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
1718 IsBetterOverloadCandidate(*this));
1719
1720 // Add the remaining viable overload candidates as code-completion reslults.
Douglas Gregor05944382009-09-23 00:16:58 +00001721 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
1722 llvm::SmallVector<ResultCandidate, 8> Results;
Anders Carlsson90756302009-09-22 17:29:51 +00001723
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001724 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
1725 CandEnd = CandidateSet.end();
1726 Cand != CandEnd; ++Cand) {
1727 if (Cand->Viable)
Douglas Gregor05944382009-09-23 00:16:58 +00001728 Results.push_back(ResultCandidate(Cand->Function));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001729 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001730 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
Douglas Gregor05944382009-09-23 00:16:58 +00001731 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001732}
1733
Douglas Gregor81b747b2009-09-17 21:32:03 +00001734void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
1735 bool EnteringContext) {
1736 if (!SS.getScopeRep() || !CodeCompleter)
1737 return;
1738
Douglas Gregor86d9a522009-09-21 16:56:56 +00001739 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
1740 if (!Ctx)
1741 return;
1742
1743 ResultBuilder Results(*this);
Douglas Gregor456c4a12009-09-21 20:12:40 +00001744 unsigned NextRank = CollectMemberLookupResults(Ctx, 0, Ctx, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001745
1746 // The "template" keyword can follow "::" in the grammar, but only
1747 // put it into the grammar if the nested-name-specifier is dependent.
1748 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
1749 if (!Results.empty() && NNS->isDependent())
1750 Results.MaybeAddResult(CodeCompleteConsumer::Result("template", NextRank));
1751
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001752 if (CodeCompleter->includeMacros())
1753 AddMacroResults(PP, NextRank + 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001754 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00001755}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001756
1757void Sema::CodeCompleteUsing(Scope *S) {
1758 if (!CodeCompleter)
1759 return;
1760
Douglas Gregor86d9a522009-09-21 16:56:56 +00001761 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001762 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001763
1764 // If we aren't in class scope, we could see the "namespace" keyword.
1765 if (!S->isClassScope())
1766 Results.MaybeAddResult(CodeCompleteConsumer::Result("namespace", 0));
1767
1768 // After "using", we can see anything that would start a
1769 // nested-name-specifier.
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001770 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1771 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001772 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001773
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001774 if (CodeCompleter->includeMacros())
1775 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001776 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001777}
1778
1779void Sema::CodeCompleteUsingDirective(Scope *S) {
1780 if (!CodeCompleter)
1781 return;
1782
Douglas Gregor86d9a522009-09-21 16:56:56 +00001783 // After "using namespace", we expect to see a namespace name or namespace
1784 // alias.
1785 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001786 Results.EnterNewScope();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001787 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1788 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001789 Results.ExitScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001790 if (CodeCompleter->includeMacros())
1791 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001792 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001793}
1794
1795void Sema::CodeCompleteNamespaceDecl(Scope *S) {
1796 if (!CodeCompleter)
1797 return;
1798
Douglas Gregor86d9a522009-09-21 16:56:56 +00001799 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
1800 DeclContext *Ctx = (DeclContext *)S->getEntity();
1801 if (!S->getParent())
1802 Ctx = Context.getTranslationUnitDecl();
1803
1804 if (Ctx && Ctx->isFileContext()) {
1805 // We only want to see those namespaces that have already been defined
1806 // within this scope, because its likely that the user is creating an
1807 // extended namespace declaration. Keep track of the most recent
1808 // definition of each namespace.
1809 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
1810 for (DeclContext::specific_decl_iterator<NamespaceDecl>
1811 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
1812 NS != NSEnd; ++NS)
1813 OrigToLatest[NS->getOriginalNamespace()] = *NS;
1814
1815 // Add the most recent definition (or extended definition) of each
1816 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001817 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001818 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
1819 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
1820 NS != NSEnd; ++NS)
Douglas Gregor456c4a12009-09-21 20:12:40 +00001821 Results.MaybeAddResult(CodeCompleteConsumer::Result(NS->second, 0),
1822 CurContext);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001823 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001824 }
1825
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001826 if (CodeCompleter->includeMacros())
1827 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001828 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001829}
1830
1831void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
1832 if (!CodeCompleter)
1833 return;
1834
Douglas Gregor86d9a522009-09-21 16:56:56 +00001835 // After "namespace", we expect to see a namespace or alias.
1836 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001837 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1838 0, CurContext, Results);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001839 if (CodeCompleter->includeMacros())
1840 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001841 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001842}
1843
Douglas Gregored8d3222009-09-18 20:05:18 +00001844void Sema::CodeCompleteOperatorName(Scope *S) {
1845 if (!CodeCompleter)
1846 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001847
1848 typedef CodeCompleteConsumer::Result Result;
1849 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001850 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00001851
Douglas Gregor86d9a522009-09-21 16:56:56 +00001852 // Add the names of overloadable operators.
1853#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1854 if (std::strcmp(Spelling, "?")) \
1855 Results.MaybeAddResult(Result(Spelling, 0));
1856#include "clang/Basic/OperatorKinds.def"
1857
1858 // Add any type names visible from the current scope
1859 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00001860 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001861
1862 // Add any type specifiers
1863 AddTypeSpecifierResults(getLangOptions(), 0, Results);
1864
1865 // Add any nested-name-specifiers
1866 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001867 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1868 NextRank + 1, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001869 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001870
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001871 if (CodeCompleter->includeMacros())
1872 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001873 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00001874}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001875
Douglas Gregorc464ae82009-12-07 09:27:33 +00001876void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
1877 bool InInterface) {
1878 typedef CodeCompleteConsumer::Result Result;
1879 ResultBuilder Results(*this);
1880 Results.EnterNewScope();
1881 if (ObjCImpDecl) {
1882 // Since we have an implementation, we can end it.
1883 Results.MaybeAddResult(Result("end", 0));
1884
1885 CodeCompletionString *Pattern = 0;
1886 Decl *ImpDecl = ObjCImpDecl.getAs<Decl>();
1887 if (isa<ObjCImplementationDecl>(ImpDecl) ||
1888 isa<ObjCCategoryImplDecl>(ImpDecl)) {
1889 // @dynamic
1890 Pattern = new CodeCompletionString;
1891 Pattern->AddTypedTextChunk("dynamic");
1892 Pattern->AddTextChunk(" ");
1893 Pattern->AddPlaceholderChunk("property");
1894 Results.MaybeAddResult(Result(Pattern, 0));
1895
1896 // @synthesize
1897 Pattern = new CodeCompletionString;
1898 Pattern->AddTypedTextChunk("synthesize");
1899 Pattern->AddTextChunk(" ");
1900 Pattern->AddPlaceholderChunk("property");
1901 Results.MaybeAddResult(Result(Pattern, 0));
1902 }
1903 } else if (InInterface) {
1904 // Since we have an interface or protocol, we can end it.
1905 Results.MaybeAddResult(Result("end", 0));
1906
1907 if (LangOpts.ObjC2) {
1908 // @property
1909 Results.MaybeAddResult(Result("property", 0));
1910 }
1911
1912 // @required
1913 Results.MaybeAddResult(Result("required", 0));
1914
1915 // @optional
1916 Results.MaybeAddResult(Result("optional", 0));
1917 } else {
1918 CodeCompletionString *Pattern = 0;
1919
1920 // @class name ;
1921 Pattern = new CodeCompletionString;
1922 Pattern->AddTypedTextChunk("class");
1923 Pattern->AddTextChunk(" ");
1924 Pattern->AddPlaceholderChunk("identifier");
1925 Pattern->AddTextChunk(";"); // add ';' chunk
1926 Results.MaybeAddResult(Result(Pattern, 0));
1927
1928 // @interface name
1929 // FIXME: Could introduce the whole pattern, including superclasses and
1930 // such.
1931 Pattern = new CodeCompletionString;
1932 Pattern->AddTypedTextChunk("interface");
1933 Pattern->AddTextChunk(" ");
1934 Pattern->AddPlaceholderChunk("class");
1935 Results.MaybeAddResult(Result(Pattern, 0));
1936
1937 // @protocol name
1938 Pattern = new CodeCompletionString;
1939 Pattern->AddTypedTextChunk("protocol");
1940 Pattern->AddTextChunk(" ");
1941 Pattern->AddPlaceholderChunk("protocol");
1942 Results.MaybeAddResult(Result(Pattern, 0));
1943
1944 // @implementation name
1945 Pattern = new CodeCompletionString;
1946 Pattern->AddTypedTextChunk("implementation");
1947 Pattern->AddTextChunk(" ");
1948 Pattern->AddPlaceholderChunk("class");
1949 Results.MaybeAddResult(Result(Pattern, 0));
1950
1951 // @compatibility_alias name
1952 Pattern = new CodeCompletionString;
1953 Pattern->AddTypedTextChunk("compatibility_alias");
1954 Pattern->AddTextChunk(" ");
1955 Pattern->AddPlaceholderChunk("alias");
1956 Pattern->AddTextChunk(" ");
1957 Pattern->AddPlaceholderChunk("class");
1958 Results.MaybeAddResult(Result(Pattern, 0));
1959 }
1960 Results.ExitScope();
1961 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
1962}
1963
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00001964static void AddObjCExpressionResults(unsigned Rank, ResultBuilder &Results) {
1965 typedef CodeCompleteConsumer::Result Result;
1966 CodeCompletionString *Pattern = 0;
1967
1968 // @encode ( type-name )
1969 Pattern = new CodeCompletionString;
1970 Pattern->AddTypedTextChunk("encode");
1971 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1972 Pattern->AddPlaceholderChunk("type-name");
1973 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1974 Results.MaybeAddResult(Result(Pattern, Rank));
1975
1976 // @protocol ( protocol-name )
1977 Pattern = new CodeCompletionString;
1978 Pattern->AddTypedTextChunk("protocol");
1979 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1980 Pattern->AddPlaceholderChunk("protocol-name");
1981 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1982 Results.MaybeAddResult(Result(Pattern, Rank));
1983
1984 // @selector ( selector )
1985 Pattern = new CodeCompletionString;
1986 Pattern->AddTypedTextChunk("selector");
1987 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1988 Pattern->AddPlaceholderChunk("selector");
1989 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1990 Results.MaybeAddResult(Result(Pattern, Rank));
1991}
1992
1993void Sema::CodeCompleteObjCAtStatement(Scope *S) {
1994 typedef CodeCompleteConsumer::Result Result;
1995 ResultBuilder Results(*this);
1996 Results.EnterNewScope();
1997
1998 CodeCompletionString *Pattern = 0;
1999
2000 // @try { statements } @catch ( declaration ) { statements } @finally
2001 // { statements }
2002 Pattern = new CodeCompletionString;
2003 Pattern->AddTypedTextChunk("try");
2004 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2005 Pattern->AddPlaceholderChunk("statements");
2006 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2007 Pattern->AddTextChunk("@catch");
2008 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2009 Pattern->AddPlaceholderChunk("parameter");
2010 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2011 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2012 Pattern->AddPlaceholderChunk("statements");
2013 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2014 Pattern->AddTextChunk("@finally");
2015 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2016 Pattern->AddPlaceholderChunk("statements");
2017 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2018 Results.MaybeAddResult(Result(Pattern, 0));
2019
2020 // @throw
2021 Pattern = new CodeCompletionString;
2022 Pattern->AddTypedTextChunk("throw");
2023 Pattern->AddTextChunk(" ");
2024 Pattern->AddPlaceholderChunk("expression");
2025 Pattern->AddTextChunk(";");
2026 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2027
2028 // @synchronized ( expression ) { statements }
2029 Pattern = new CodeCompletionString;
2030 Pattern->AddTypedTextChunk("synchronized");
2031 Pattern->AddTextChunk(" ");
2032 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2033 Pattern->AddPlaceholderChunk("expression");
2034 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2035 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2036 Pattern->AddPlaceholderChunk("statements");
2037 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2038 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2039
2040 AddObjCExpressionResults(0, Results);
2041 Results.ExitScope();
2042 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2043}
2044
2045void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2046 ResultBuilder Results(*this);
2047 Results.EnterNewScope();
2048 AddObjCExpressionResults(0, Results);
2049 Results.ExitScope();
2050 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2051}
2052
Douglas Gregor988358f2009-11-19 00:14:45 +00002053/// \brief Determine whether the addition of the given flag to an Objective-C
2054/// property's attributes will cause a conflict.
2055static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2056 // Check if we've already added this flag.
2057 if (Attributes & NewFlag)
2058 return true;
2059
2060 Attributes |= NewFlag;
2061
2062 // Check for collisions with "readonly".
2063 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2064 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2065 ObjCDeclSpec::DQ_PR_assign |
2066 ObjCDeclSpec::DQ_PR_copy |
2067 ObjCDeclSpec::DQ_PR_retain)))
2068 return true;
2069
2070 // Check for more than one of { assign, copy, retain }.
2071 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2072 ObjCDeclSpec::DQ_PR_copy |
2073 ObjCDeclSpec::DQ_PR_retain);
2074 if (AssignCopyRetMask &&
2075 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2076 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2077 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2078 return true;
2079
2080 return false;
2081}
2082
Douglas Gregora93b1082009-11-18 23:08:07 +00002083void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00002084 if (!CodeCompleter)
2085 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00002086
Steve Naroffece8e712009-10-08 21:55:05 +00002087 unsigned Attributes = ODS.getPropertyAttributes();
2088
2089 typedef CodeCompleteConsumer::Result Result;
2090 ResultBuilder Results(*this);
2091 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00002092 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Steve Naroffece8e712009-10-08 21:55:05 +00002093 Results.MaybeAddResult(CodeCompleteConsumer::Result("readonly", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002094 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Steve Naroffece8e712009-10-08 21:55:05 +00002095 Results.MaybeAddResult(CodeCompleteConsumer::Result("assign", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002096 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Steve Naroffece8e712009-10-08 21:55:05 +00002097 Results.MaybeAddResult(CodeCompleteConsumer::Result("readwrite", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002098 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Steve Naroffece8e712009-10-08 21:55:05 +00002099 Results.MaybeAddResult(CodeCompleteConsumer::Result("retain", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002100 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Steve Naroffece8e712009-10-08 21:55:05 +00002101 Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002102 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Steve Naroffece8e712009-10-08 21:55:05 +00002103 Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002104 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002105 CodeCompletionString *Setter = new CodeCompletionString;
2106 Setter->AddTypedTextChunk("setter");
2107 Setter->AddTextChunk(" = ");
2108 Setter->AddPlaceholderChunk("method");
2109 Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
2110 }
Douglas Gregor988358f2009-11-19 00:14:45 +00002111 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002112 CodeCompletionString *Getter = new CodeCompletionString;
2113 Getter->AddTypedTextChunk("getter");
2114 Getter->AddTextChunk(" = ");
2115 Getter->AddPlaceholderChunk("method");
2116 Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
2117 }
Steve Naroffece8e712009-10-08 21:55:05 +00002118 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002119 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00002120}
Steve Naroffc4df6d22009-11-07 02:08:14 +00002121
Douglas Gregor4ad96852009-11-19 07:41:15 +00002122/// \brief Descripts the kind of Objective-C method that we want to find
2123/// via code completion.
2124enum ObjCMethodKind {
2125 MK_Any, //< Any kind of method, provided it means other specified criteria.
2126 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2127 MK_OneArgSelector //< One-argument selector.
2128};
2129
2130static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2131 ObjCMethodKind WantKind,
2132 IdentifierInfo **SelIdents,
2133 unsigned NumSelIdents) {
2134 Selector Sel = Method->getSelector();
2135 if (NumSelIdents > Sel.getNumArgs())
2136 return false;
2137
2138 switch (WantKind) {
2139 case MK_Any: break;
2140 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2141 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2142 }
2143
2144 for (unsigned I = 0; I != NumSelIdents; ++I)
2145 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2146 return false;
2147
2148 return true;
2149}
2150
Douglas Gregor36ecb042009-11-17 23:22:23 +00002151/// \brief Add all of the Objective-C methods in the given Objective-C
2152/// container to the set of results.
2153///
2154/// The container will be a class, protocol, category, or implementation of
2155/// any of the above. This mether will recurse to include methods from
2156/// the superclasses of classes along with their categories, protocols, and
2157/// implementations.
2158///
2159/// \param Container the container in which we'll look to find methods.
2160///
2161/// \param WantInstance whether to add instance methods (only); if false, this
2162/// routine will add factory methods (only).
2163///
2164/// \param CurContext the context in which we're performing the lookup that
2165/// finds methods.
2166///
2167/// \param Results the structure into which we'll add results.
2168static void AddObjCMethods(ObjCContainerDecl *Container,
2169 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00002170 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00002171 IdentifierInfo **SelIdents,
2172 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00002173 DeclContext *CurContext,
2174 ResultBuilder &Results) {
2175 typedef CodeCompleteConsumer::Result Result;
2176 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2177 MEnd = Container->meth_end();
2178 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002179 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2180 // Check whether the selector identifiers we've been given are a
2181 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002182 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00002183 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002184
Douglas Gregord3c68542009-11-19 01:08:35 +00002185 Result R = Result(*M, 0);
2186 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002187 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00002188 Results.MaybeAddResult(R, CurContext);
2189 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00002190 }
2191
2192 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2193 if (!IFace)
2194 return;
2195
2196 // Add methods in protocols.
2197 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2198 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2199 E = Protocols.end();
2200 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002201 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00002202 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002203
2204 // Add methods in categories.
2205 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2206 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00002207 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2208 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002209
2210 // Add a categories protocol methods.
2211 const ObjCList<ObjCProtocolDecl> &Protocols
2212 = CatDecl->getReferencedProtocols();
2213 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2214 E = Protocols.end();
2215 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002216 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2217 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002218
2219 // Add methods in category implementations.
2220 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002221 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2222 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002223 }
2224
2225 // Add methods in superclass.
2226 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002227 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2228 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002229
2230 // Add methods in our implementation, if any.
2231 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002232 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2233 NumSelIdents, CurContext, Results);
2234}
2235
2236
2237void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2238 DeclPtrTy *Methods,
2239 unsigned NumMethods) {
2240 typedef CodeCompleteConsumer::Result Result;
2241
2242 // Try to find the interface where getters might live.
2243 ObjCInterfaceDecl *Class
2244 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2245 if (!Class) {
2246 if (ObjCCategoryDecl *Category
2247 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2248 Class = Category->getClassInterface();
2249
2250 if (!Class)
2251 return;
2252 }
2253
2254 // Find all of the potential getters.
2255 ResultBuilder Results(*this);
2256 Results.EnterNewScope();
2257
2258 // FIXME: We need to do this because Objective-C methods don't get
2259 // pushed into DeclContexts early enough. Argh!
2260 for (unsigned I = 0; I != NumMethods; ++I) {
2261 if (ObjCMethodDecl *Method
2262 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2263 if (Method->isInstanceMethod() &&
2264 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2265 Result R = Result(Method, 0);
2266 R.AllParametersAreInformative = true;
2267 Results.MaybeAddResult(R, CurContext);
2268 }
2269 }
2270
2271 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2272 Results.ExitScope();
2273 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2274}
2275
2276void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2277 DeclPtrTy *Methods,
2278 unsigned NumMethods) {
2279 typedef CodeCompleteConsumer::Result Result;
2280
2281 // Try to find the interface where setters might live.
2282 ObjCInterfaceDecl *Class
2283 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2284 if (!Class) {
2285 if (ObjCCategoryDecl *Category
2286 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2287 Class = Category->getClassInterface();
2288
2289 if (!Class)
2290 return;
2291 }
2292
2293 // Find all of the potential getters.
2294 ResultBuilder Results(*this);
2295 Results.EnterNewScope();
2296
2297 // FIXME: We need to do this because Objective-C methods don't get
2298 // pushed into DeclContexts early enough. Argh!
2299 for (unsigned I = 0; I != NumMethods; ++I) {
2300 if (ObjCMethodDecl *Method
2301 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2302 if (Method->isInstanceMethod() &&
2303 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2304 Result R = Result(Method, 0);
2305 R.AllParametersAreInformative = true;
2306 Results.MaybeAddResult(R, CurContext);
2307 }
2308 }
2309
2310 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2311
2312 Results.ExitScope();
2313 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00002314}
2315
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002316void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregord3c68542009-11-19 01:08:35 +00002317 SourceLocation FNameLoc,
2318 IdentifierInfo **SelIdents,
2319 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002320 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00002321 ObjCInterfaceDecl *CDecl = 0;
2322
Douglas Gregor24a069f2009-11-17 17:59:40 +00002323 if (FName->isStr("super")) {
2324 // We're sending a message to "super".
2325 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2326 // Figure out which interface we're in.
2327 CDecl = CurMethod->getClassInterface();
2328 if (!CDecl)
2329 return;
2330
2331 // Find the superclass of this class.
2332 CDecl = CDecl->getSuperClass();
2333 if (!CDecl)
2334 return;
2335
2336 if (CurMethod->isInstanceMethod()) {
2337 // We are inside an instance method, which means that the message
2338 // send [super ...] is actually calling an instance method on the
2339 // current object. Build the super expression and handle this like
2340 // an instance method.
2341 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2342 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2343 OwningExprResult Super
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002344 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregord3c68542009-11-19 01:08:35 +00002345 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2346 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002347 }
2348
2349 // Okay, we're calling a factory method in our superclass.
2350 }
2351 }
2352
2353 // If the given name refers to an interface type, retrieve the
2354 // corresponding declaration.
2355 if (!CDecl)
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002356 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor24a069f2009-11-17 17:59:40 +00002357 QualType T = GetTypeFromParser(Ty, 0);
2358 if (!T.isNull())
2359 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
2360 CDecl = Interface->getDecl();
2361 }
2362
2363 if (!CDecl && FName->isStr("super")) {
2364 // "super" may be the name of a variable, in which case we are
2365 // probably calling an instance method.
John McCallf7a1a742009-11-24 19:00:30 +00002366 CXXScopeSpec SS;
2367 UnqualifiedId id;
2368 id.setIdentifier(FName, FNameLoc);
2369 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregord3c68542009-11-19 01:08:35 +00002370 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2371 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002372 }
2373
Douglas Gregor36ecb042009-11-17 23:22:23 +00002374 // Add all of the factory methods in this Objective-C class, its protocols,
2375 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00002376 ResultBuilder Results(*this);
2377 Results.EnterNewScope();
Douglas Gregor4ad96852009-11-19 07:41:15 +00002378 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
2379 Results);
Steve Naroffc4df6d22009-11-07 02:08:14 +00002380 Results.ExitScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00002381
Steve Naroffc4df6d22009-11-07 02:08:14 +00002382 // This also suppresses remaining diagnostics.
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002383 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00002384}
2385
Douglas Gregord3c68542009-11-19 01:08:35 +00002386void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
2387 IdentifierInfo **SelIdents,
2388 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002389 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00002390
2391 Expr *RecExpr = static_cast<Expr *>(Receiver);
2392 QualType RecType = RecExpr->getType();
2393
Douglas Gregor36ecb042009-11-17 23:22:23 +00002394 // If necessary, apply function/array conversion to the receiver.
2395 // C99 6.7.5.3p[7,8].
2396 DefaultFunctionArrayConversion(RecExpr);
2397 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00002398
Douglas Gregor36ecb042009-11-17 23:22:23 +00002399 if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType()) {
2400 // FIXME: We're messaging 'id'. Do we actually want to look up every method
2401 // in the universe?
2402 return;
2403 }
2404
Douglas Gregor36ecb042009-11-17 23:22:23 +00002405 // Build the set of methods we can see.
2406 ResultBuilder Results(*this);
2407 Results.EnterNewScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00002408
Douglas Gregorf74a4192009-11-18 00:06:18 +00002409 // Handle messages to Class. This really isn't a message to an instance
2410 // method, so we treat it the same way we would treat a message send to a
2411 // class method.
2412 if (ReceiverType->isObjCClassType() ||
2413 ReceiverType->isObjCQualifiedClassType()) {
2414 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2415 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002416 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
2417 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002418 }
2419 }
2420 // Handle messages to a qualified ID ("id<foo>").
2421 else if (const ObjCObjectPointerType *QualID
2422 = ReceiverType->getAsObjCQualifiedIdType()) {
2423 // Search protocols for instance methods.
2424 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
2425 E = QualID->qual_end();
2426 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002427 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2428 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002429 }
2430 // Handle messages to a pointer to interface type.
2431 else if (const ObjCObjectPointerType *IFacePtr
2432 = ReceiverType->getAsObjCInterfacePointerType()) {
2433 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002434 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
2435 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002436
2437 // Search protocols for instance methods.
2438 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
2439 E = IFacePtr->qual_end();
2440 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002441 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2442 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002443 }
2444
Steve Naroffc4df6d22009-11-07 02:08:14 +00002445 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002446 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00002447}
Douglas Gregor55385fe2009-11-18 04:19:12 +00002448
2449/// \brief Add all of the protocol declarations that we find in the given
2450/// (translation unit) context.
2451static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00002452 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00002453 ResultBuilder &Results) {
2454 typedef CodeCompleteConsumer::Result Result;
2455
2456 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2457 DEnd = Ctx->decls_end();
2458 D != DEnd; ++D) {
2459 // Record any protocols we find.
2460 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00002461 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
2462 Results.MaybeAddResult(Result(Proto, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002463
2464 // Record any forward-declared protocols we find.
2465 if (ObjCForwardProtocolDecl *Forward
2466 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
2467 for (ObjCForwardProtocolDecl::protocol_iterator
2468 P = Forward->protocol_begin(),
2469 PEnd = Forward->protocol_end();
2470 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00002471 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
2472 Results.MaybeAddResult(Result(*P, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002473 }
2474 }
2475}
2476
2477void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
2478 unsigned NumProtocols) {
2479 ResultBuilder Results(*this);
2480 Results.EnterNewScope();
2481
2482 // Tell the result set to ignore all of the protocols we have
2483 // already seen.
2484 for (unsigned I = 0; I != NumProtocols; ++I)
2485 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
2486 Results.Ignore(Protocol);
2487
2488 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00002489 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
2490 Results);
2491
2492 Results.ExitScope();
2493 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2494}
2495
2496void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
2497 ResultBuilder Results(*this);
2498 Results.EnterNewScope();
2499
2500 // Add all protocols.
2501 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
2502 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002503
2504 Results.ExitScope();
2505 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2506}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00002507
2508/// \brief Add all of the Objective-C interface declarations that we find in
2509/// the given (translation unit) context.
2510static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
2511 bool OnlyForwardDeclarations,
2512 bool OnlyUnimplemented,
2513 ResultBuilder &Results) {
2514 typedef CodeCompleteConsumer::Result Result;
2515
2516 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2517 DEnd = Ctx->decls_end();
2518 D != DEnd; ++D) {
2519 // Record any interfaces we find.
2520 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
2521 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
2522 (!OnlyUnimplemented || !Class->getImplementation()))
2523 Results.MaybeAddResult(Result(Class, 0), CurContext);
2524
2525 // Record any forward-declared interfaces we find.
2526 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
2527 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
2528 C != CEnd; ++C)
2529 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
2530 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
2531 Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
2532 }
2533 }
2534}
2535
2536void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
2537 ResultBuilder Results(*this);
2538 Results.EnterNewScope();
2539
2540 // Add all classes.
2541 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
2542 false, Results);
2543
2544 Results.ExitScope();
2545 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2546}
2547
2548void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
2549 ResultBuilder Results(*this);
2550 Results.EnterNewScope();
2551
2552 // Make sure that we ignore the class we're currently defining.
2553 NamedDecl *CurClass
2554 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00002555 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00002556 Results.Ignore(CurClass);
2557
2558 // Add all classes.
2559 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2560 false, Results);
2561
2562 Results.ExitScope();
2563 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2564}
2565
2566void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
2567 ResultBuilder Results(*this);
2568 Results.EnterNewScope();
2569
2570 // Add all unimplemented classes.
2571 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2572 true, Results);
2573
2574 Results.ExitScope();
2575 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2576}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00002577
2578void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
2579 IdentifierInfo *ClassName) {
2580 typedef CodeCompleteConsumer::Result Result;
2581
2582 ResultBuilder Results(*this);
2583
2584 // Ignore any categories we find that have already been implemented by this
2585 // interface.
2586 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2587 NamedDecl *CurClass
2588 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2589 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
2590 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2591 Category = Category->getNextClassCategory())
2592 CategoryNames.insert(Category->getIdentifier());
2593
2594 // Add all of the categories we know about.
2595 Results.EnterNewScope();
2596 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
2597 for (DeclContext::decl_iterator D = TU->decls_begin(),
2598 DEnd = TU->decls_end();
2599 D != DEnd; ++D)
2600 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
2601 if (CategoryNames.insert(Category->getIdentifier()))
2602 Results.MaybeAddResult(Result(Category, 0), CurContext);
2603 Results.ExitScope();
2604
2605 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2606}
2607
2608void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
2609 IdentifierInfo *ClassName) {
2610 typedef CodeCompleteConsumer::Result Result;
2611
2612 // Find the corresponding interface. If we couldn't find the interface, the
2613 // program itself is ill-formed. However, we'll try to be helpful still by
2614 // providing the list of all of the categories we know about.
2615 NamedDecl *CurClass
2616 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2617 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
2618 if (!Class)
2619 return CodeCompleteObjCInterfaceCategory(S, ClassName);
2620
2621 ResultBuilder Results(*this);
2622
2623 // Add all of the categories that have have corresponding interface
2624 // declarations in this class and any of its superclasses, except for
2625 // already-implemented categories in the class itself.
2626 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2627 Results.EnterNewScope();
2628 bool IgnoreImplemented = true;
2629 while (Class) {
2630 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2631 Category = Category->getNextClassCategory())
2632 if ((!IgnoreImplemented || !Category->getImplementation()) &&
2633 CategoryNames.insert(Category->getIdentifier()))
2634 Results.MaybeAddResult(Result(Category, 0), CurContext);
2635
2636 Class = Class->getSuperClass();
2637 IgnoreImplemented = false;
2638 }
2639 Results.ExitScope();
2640
2641 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2642}
Douglas Gregor322328b2009-11-18 22:32:06 +00002643
Douglas Gregor424b2a52009-11-18 22:56:13 +00002644void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00002645 typedef CodeCompleteConsumer::Result Result;
2646 ResultBuilder Results(*this);
2647
2648 // Figure out where this @synthesize lives.
2649 ObjCContainerDecl *Container
2650 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2651 if (!Container ||
2652 (!isa<ObjCImplementationDecl>(Container) &&
2653 !isa<ObjCCategoryImplDecl>(Container)))
2654 return;
2655
2656 // Ignore any properties that have already been implemented.
2657 for (DeclContext::decl_iterator D = Container->decls_begin(),
2658 DEnd = Container->decls_end();
2659 D != DEnd; ++D)
2660 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
2661 Results.Ignore(PropertyImpl->getPropertyDecl());
2662
2663 // Add any properties that we find.
2664 Results.EnterNewScope();
2665 if (ObjCImplementationDecl *ClassImpl
2666 = dyn_cast<ObjCImplementationDecl>(Container))
2667 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
2668 Results);
2669 else
2670 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
2671 false, CurContext, Results);
2672 Results.ExitScope();
2673
2674 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2675}
2676
2677void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
2678 IdentifierInfo *PropertyName,
2679 DeclPtrTy ObjCImpDecl) {
2680 typedef CodeCompleteConsumer::Result Result;
2681 ResultBuilder Results(*this);
2682
2683 // Figure out where this @synthesize lives.
2684 ObjCContainerDecl *Container
2685 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2686 if (!Container ||
2687 (!isa<ObjCImplementationDecl>(Container) &&
2688 !isa<ObjCCategoryImplDecl>(Container)))
2689 return;
2690
2691 // Figure out which interface we're looking into.
2692 ObjCInterfaceDecl *Class = 0;
2693 if (ObjCImplementationDecl *ClassImpl
2694 = dyn_cast<ObjCImplementationDecl>(Container))
2695 Class = ClassImpl->getClassInterface();
2696 else
2697 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
2698 ->getClassInterface();
2699
2700 // Add all of the instance variables in this class and its superclasses.
2701 Results.EnterNewScope();
2702 for(; Class; Class = Class->getSuperClass()) {
2703 // FIXME: We could screen the type of each ivar for compatibility with
2704 // the property, but is that being too paternal?
2705 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
2706 IVarEnd = Class->ivar_end();
2707 IVar != IVarEnd; ++IVar)
2708 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
2709 }
2710 Results.ExitScope();
2711
2712 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2713}