blob: 42ac6f19b0e5248820a76e7780efb64717ebf02f [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
Douglas Gregorce821962009-12-11 18:14:22 +0000590 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
591 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000592}
593
Douglas Gregor86d9a522009-09-21 16:56:56 +0000594// Find the next outer declaration context corresponding to this scope.
595static DeclContext *findOuterContext(Scope *S) {
596 for (S = S->getParent(); S; S = S->getParent())
597 if (S->getEntity())
598 return static_cast<DeclContext *>(S->getEntity())->getPrimaryContext();
599
600 return 0;
601}
602
603/// \brief Collect the results of searching for members within the given
604/// declaration context.
605///
606/// \param Ctx the declaration context from which we will gather results.
607///
Douglas Gregor0563c262009-09-22 23:15:58 +0000608/// \param Rank the rank given to results in this declaration context.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000609///
610/// \param Visited the set of declaration contexts that have already been
611/// visited. Declaration contexts will only be visited once.
612///
613/// \param Results the result set that will be extended with any results
614/// found within this declaration context (and, for a C++ class, its bases).
615///
Douglas Gregor0563c262009-09-22 23:15:58 +0000616/// \param InBaseClass whether we are in a base class.
617///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000618/// \returns the next higher rank value, after considering all of the
619/// names within this declaration context.
620static unsigned CollectMemberLookupResults(DeclContext *Ctx,
Douglas Gregor0563c262009-09-22 23:15:58 +0000621 unsigned Rank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000622 DeclContext *CurContext,
623 llvm::SmallPtrSet<DeclContext *, 16> &Visited,
Douglas Gregor0563c262009-09-22 23:15:58 +0000624 ResultBuilder &Results,
625 bool InBaseClass = false) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000626 // Make sure we don't visit the same context twice.
627 if (!Visited.insert(Ctx->getPrimaryContext()))
Douglas Gregor0563c262009-09-22 23:15:58 +0000628 return Rank;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000629
630 // Enumerate all of the results in this context.
Douglas Gregor0563c262009-09-22 23:15:58 +0000631 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000632 Results.EnterNewScope();
633 for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
634 CurCtx = CurCtx->getNextContext()) {
635 for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000636 DEnd = CurCtx->decls_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000637 D != DEnd; ++D) {
638 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
Douglas Gregor0563c262009-09-22 23:15:58 +0000639 Results.MaybeAddResult(Result(ND, Rank, 0, InBaseClass), CurContext);
Douglas Gregorff4393c2009-11-09 21:35:27 +0000640
641 // Visit transparent contexts inside this context.
642 if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
643 if (InnerCtx->isTransparentContext())
644 CollectMemberLookupResults(InnerCtx, Rank, CurContext, Visited,
645 Results, InBaseClass);
646 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000647 }
648 }
649
650 // Traverse the contexts of inherited classes.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000651 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
652 for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000653 BEnd = Record->bases_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000654 B != BEnd; ++B) {
655 QualType BaseType = B->getType();
656
657 // Don't look into dependent bases, because name lookup can't look
658 // there anyway.
659 if (BaseType->isDependentType())
660 continue;
661
662 const RecordType *Record = BaseType->getAs<RecordType>();
663 if (!Record)
664 continue;
665
666 // FIXME: It would be nice to be able to determine whether referencing
667 // a particular member would be ambiguous. For example, given
668 //
669 // struct A { int member; };
670 // struct B { int member; };
671 // struct C : A, B { };
672 //
673 // void f(C *c) { c->### }
674 // accessing 'member' would result in an ambiguity. However, code
675 // completion could be smart enough to qualify the member with the
676 // base class, e.g.,
677 //
678 // c->B::member
679 //
680 // or
681 //
682 // c->A::member
683
684 // Collect results from this base class (and its bases).
Douglas Gregor0563c262009-09-22 23:15:58 +0000685 CollectMemberLookupResults(Record->getDecl(), Rank, CurContext, Visited,
686 Results, /*InBaseClass=*/true);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000687 }
688 }
689
690 // FIXME: Look into base classes in Objective-C!
691
692 Results.ExitScope();
Douglas Gregor0563c262009-09-22 23:15:58 +0000693 return Rank + 1;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000694}
695
696/// \brief Collect the results of searching for members within the given
697/// declaration context.
698///
699/// \param Ctx the declaration context from which we will gather results.
700///
701/// \param InitialRank the initial rank given to results in this declaration
702/// context. Larger rank values will be used for, e.g., members found in
703/// base classes.
704///
705/// \param Results the result set that will be extended with any results
706/// found within this declaration context (and, for a C++ class, its bases).
707///
708/// \returns the next higher rank value, after considering all of the
709/// names within this declaration context.
710static unsigned CollectMemberLookupResults(DeclContext *Ctx,
711 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000712 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000713 ResultBuilder &Results) {
714 llvm::SmallPtrSet<DeclContext *, 16> Visited;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000715 return CollectMemberLookupResults(Ctx, InitialRank, CurContext, Visited,
716 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000717}
718
719/// \brief Collect the results of searching for declarations within the given
720/// scope and its parent scopes.
721///
722/// \param S the scope in which we will start looking for declarations.
723///
724/// \param InitialRank the initial rank given to results in this scope.
725/// Larger rank values will be used for results found in parent scopes.
726///
Douglas Gregor456c4a12009-09-21 20:12:40 +0000727/// \param CurContext the context from which lookup results will be found.
728///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000729/// \param Results the builder object that will receive each result.
730static unsigned CollectLookupResults(Scope *S,
731 TranslationUnitDecl *TranslationUnit,
732 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000733 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000734 ResultBuilder &Results) {
735 if (!S)
736 return InitialRank;
737
738 // FIXME: Using directives!
739
740 unsigned NextRank = InitialRank;
741 Results.EnterNewScope();
742 if (S->getEntity() &&
743 !((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
744 // Look into this scope's declaration context, along with any of its
745 // parent lookup contexts (e.g., enclosing classes), up to the point
746 // where we hit the context stored in the next outer scope.
747 DeclContext *Ctx = (DeclContext *)S->getEntity();
748 DeclContext *OuterCtx = findOuterContext(S);
749
750 for (; Ctx && Ctx->getPrimaryContext() != OuterCtx;
751 Ctx = Ctx->getLookupParent()) {
752 if (Ctx->isFunctionOrMethod())
753 continue;
754
Douglas Gregor456c4a12009-09-21 20:12:40 +0000755 NextRank = CollectMemberLookupResults(Ctx, NextRank + 1, CurContext,
756 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000757 }
758 } else if (!S->getParent()) {
759 // Look into the translation unit scope. We walk through the translation
760 // unit's declaration context, because the Scope itself won't have all of
761 // the declarations if we loaded a precompiled header.
762 // FIXME: We would like the translation unit's Scope object to point to the
763 // translation unit, so we don't need this special "if" branch. However,
764 // doing so would force the normal C++ name-lookup code to look into the
765 // translation unit decl when the IdentifierInfo chains would suffice.
766 // Once we fix that problem (which is part of a more general "don't look
767 // in DeclContexts unless we have to" optimization), we can eliminate the
768 // TranslationUnit parameter entirely.
769 NextRank = CollectMemberLookupResults(TranslationUnit, NextRank + 1,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000770 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000771 } else {
772 // Walk through the declarations in this Scope.
773 for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
774 D != DEnd; ++D) {
775 if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
Douglas Gregor456c4a12009-09-21 20:12:40 +0000776 Results.MaybeAddResult(CodeCompleteConsumer::Result(ND, NextRank),
777 CurContext);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000778 }
779
780 NextRank = NextRank + 1;
781 }
782
783 // Lookup names in the parent scope.
784 NextRank = CollectLookupResults(S->getParent(), TranslationUnit, NextRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000785 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000786 Results.ExitScope();
787
788 return NextRank;
789}
790
791/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregor9a0c85e2009-12-07 09:51:25 +0000792static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000793 ResultBuilder &Results) {
794 typedef CodeCompleteConsumer::Result Result;
795 Results.MaybeAddResult(Result("short", Rank));
796 Results.MaybeAddResult(Result("long", Rank));
797 Results.MaybeAddResult(Result("signed", Rank));
798 Results.MaybeAddResult(Result("unsigned", Rank));
799 Results.MaybeAddResult(Result("void", Rank));
800 Results.MaybeAddResult(Result("char", Rank));
801 Results.MaybeAddResult(Result("int", Rank));
802 Results.MaybeAddResult(Result("float", Rank));
803 Results.MaybeAddResult(Result("double", Rank));
804 Results.MaybeAddResult(Result("enum", Rank));
805 Results.MaybeAddResult(Result("struct", Rank));
806 Results.MaybeAddResult(Result("union", Rank));
807
808 if (LangOpts.C99) {
809 // C99-specific
810 Results.MaybeAddResult(Result("_Complex", Rank));
811 Results.MaybeAddResult(Result("_Imaginary", Rank));
812 Results.MaybeAddResult(Result("_Bool", Rank));
813 }
814
815 if (LangOpts.CPlusPlus) {
816 // C++-specific
817 Results.MaybeAddResult(Result("bool", Rank));
818 Results.MaybeAddResult(Result("class", Rank));
819 Results.MaybeAddResult(Result("typename", Rank));
820 Results.MaybeAddResult(Result("wchar_t", Rank));
821
822 if (LangOpts.CPlusPlus0x) {
823 Results.MaybeAddResult(Result("char16_t", Rank));
824 Results.MaybeAddResult(Result("char32_t", Rank));
825 Results.MaybeAddResult(Result("decltype", Rank));
826 }
827 }
828
829 // GNU extensions
830 if (LangOpts.GNUMode) {
831 // FIXME: Enable when we actually support decimal floating point.
832 // Results.MaybeAddResult(Result("_Decimal32", Rank));
833 // Results.MaybeAddResult(Result("_Decimal64", Rank));
834 // Results.MaybeAddResult(Result("_Decimal128", Rank));
835 Results.MaybeAddResult(Result("typeof", Rank));
836 }
837}
838
839/// \brief Add function parameter chunks to the given code completion string.
840static void AddFunctionParameterChunks(ASTContext &Context,
841 FunctionDecl *Function,
842 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000843 typedef CodeCompletionString::Chunk Chunk;
844
Douglas Gregor86d9a522009-09-21 16:56:56 +0000845 CodeCompletionString *CCStr = Result;
846
847 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
848 ParmVarDecl *Param = Function->getParamDecl(P);
849
850 if (Param->hasDefaultArg()) {
851 // When we see an optional default argument, put that argument and
852 // the remaining default arguments into a new, optional string.
853 CodeCompletionString *Opt = new CodeCompletionString;
854 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
855 CCStr = Opt;
856 }
857
858 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000859 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000860
861 // Format the placeholder string.
862 std::string PlaceholderStr;
863 if (Param->getIdentifier())
864 PlaceholderStr = Param->getIdentifier()->getName();
865
866 Param->getType().getAsStringInternal(PlaceholderStr,
867 Context.PrintingPolicy);
868
869 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +0000870 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000871 }
Douglas Gregorb3d45252009-09-22 21:42:17 +0000872
873 if (const FunctionProtoType *Proto
874 = Function->getType()->getAs<FunctionProtoType>())
875 if (Proto->isVariadic())
876 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +0000877}
878
879/// \brief Add template parameter chunks to the given code completion string.
880static void AddTemplateParameterChunks(ASTContext &Context,
881 TemplateDecl *Template,
882 CodeCompletionString *Result,
883 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000884 typedef CodeCompletionString::Chunk Chunk;
885
Douglas Gregor86d9a522009-09-21 16:56:56 +0000886 CodeCompletionString *CCStr = Result;
887 bool FirstParameter = true;
888
889 TemplateParameterList *Params = Template->getTemplateParameters();
890 TemplateParameterList::iterator PEnd = Params->end();
891 if (MaxParameters)
892 PEnd = Params->begin() + MaxParameters;
893 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
894 bool HasDefaultArg = false;
895 std::string PlaceholderStr;
896 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
897 if (TTP->wasDeclaredWithTypename())
898 PlaceholderStr = "typename";
899 else
900 PlaceholderStr = "class";
901
902 if (TTP->getIdentifier()) {
903 PlaceholderStr += ' ';
904 PlaceholderStr += TTP->getIdentifier()->getName();
905 }
906
907 HasDefaultArg = TTP->hasDefaultArgument();
908 } else if (NonTypeTemplateParmDecl *NTTP
909 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
910 if (NTTP->getIdentifier())
911 PlaceholderStr = NTTP->getIdentifier()->getName();
912 NTTP->getType().getAsStringInternal(PlaceholderStr,
913 Context.PrintingPolicy);
914 HasDefaultArg = NTTP->hasDefaultArgument();
915 } else {
916 assert(isa<TemplateTemplateParmDecl>(*P));
917 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
918
919 // Since putting the template argument list into the placeholder would
920 // be very, very long, we just use an abbreviation.
921 PlaceholderStr = "template<...> class";
922 if (TTP->getIdentifier()) {
923 PlaceholderStr += ' ';
924 PlaceholderStr += TTP->getIdentifier()->getName();
925 }
926
927 HasDefaultArg = TTP->hasDefaultArgument();
928 }
929
930 if (HasDefaultArg) {
931 // When we see an optional default argument, put that argument and
932 // the remaining default arguments into a new, optional string.
933 CodeCompletionString *Opt = new CodeCompletionString;
934 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
935 CCStr = Opt;
936 }
937
938 if (FirstParameter)
939 FirstParameter = false;
940 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000941 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000942
943 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +0000944 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000945 }
946}
947
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000948/// \brief Add a qualifier to the given code-completion string, if the
949/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +0000950static void
951AddQualifierToCompletionString(CodeCompletionString *Result,
952 NestedNameSpecifier *Qualifier,
953 bool QualifierIsInformative,
954 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000955 if (!Qualifier)
956 return;
957
958 std::string PrintedNNS;
959 {
960 llvm::raw_string_ostream OS(PrintedNNS);
961 Qualifier->print(OS, Context.PrintingPolicy);
962 }
Douglas Gregor0563c262009-09-22 23:15:58 +0000963 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +0000964 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +0000965 else
Benjamin Kramer660cc182009-11-29 20:18:50 +0000966 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000967}
968
Douglas Gregora61a8792009-12-11 18:44:16 +0000969static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
970 FunctionDecl *Function) {
971 const FunctionProtoType *Proto
972 = Function->getType()->getAs<FunctionProtoType>();
973 if (!Proto || !Proto->getTypeQuals())
974 return;
975
976 std::string QualsStr;
977 if (Proto->getTypeQuals() & Qualifiers::Const)
978 QualsStr += " const";
979 if (Proto->getTypeQuals() & Qualifiers::Volatile)
980 QualsStr += " volatile";
981 if (Proto->getTypeQuals() & Qualifiers::Restrict)
982 QualsStr += " restrict";
983 Result->AddInformativeChunk(QualsStr);
984}
985
Douglas Gregor86d9a522009-09-21 16:56:56 +0000986/// \brief If possible, create a new code completion string for the given
987/// result.
988///
989/// \returns Either a new, heap-allocated code completion string describing
990/// how to use this result, or NULL to indicate that the string or name of the
991/// result is all that is needed.
992CodeCompletionString *
993CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000994 typedef CodeCompletionString::Chunk Chunk;
995
Douglas Gregor2b4074f2009-12-01 05:55:20 +0000996 if (Kind == RK_Pattern)
997 return Pattern->Clone();
998
999 CodeCompletionString *Result = new CodeCompletionString;
1000
1001 if (Kind == RK_Keyword) {
1002 Result->AddTypedTextChunk(Keyword);
1003 return Result;
1004 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001005
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001006 if (Kind == RK_Macro) {
1007 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001008 assert(MI && "Not a macro?");
1009
1010 Result->AddTypedTextChunk(Macro->getName());
1011
1012 if (!MI->isFunctionLike())
1013 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001014
1015 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001016 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001017 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1018 A != AEnd; ++A) {
1019 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001020 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001021
1022 if (!MI->isVariadic() || A != AEnd - 1) {
1023 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001024 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001025 continue;
1026 }
1027
1028 // Variadic argument; cope with the different between GNU and C99
1029 // variadic macros, providing a single placeholder for the rest of the
1030 // arguments.
1031 if ((*A)->isStr("__VA_ARGS__"))
1032 Result->AddPlaceholderChunk("...");
1033 else {
1034 std::string Arg = (*A)->getName();
1035 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001036 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001037 }
1038 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001039 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001040 return Result;
1041 }
1042
1043 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001044 NamedDecl *ND = Declaration;
1045
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001046 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001047 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001048 Result->AddTextChunk("::");
1049 return Result;
1050 }
1051
Douglas Gregor86d9a522009-09-21 16:56:56 +00001052 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001053 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1054 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001055 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001056 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001057 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001058 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001059 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001060 return Result;
1061 }
1062
1063 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001064 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1065 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001066 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001067 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001068
1069 // Figure out which template parameters are deduced (or have default
1070 // arguments).
1071 llvm::SmallVector<bool, 16> Deduced;
1072 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1073 unsigned LastDeducibleArgument;
1074 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1075 --LastDeducibleArgument) {
1076 if (!Deduced[LastDeducibleArgument - 1]) {
1077 // C++0x: Figure out if the template argument has a default. If so,
1078 // the user doesn't need to type this argument.
1079 // FIXME: We need to abstract template parameters better!
1080 bool HasDefaultArg = false;
1081 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1082 LastDeducibleArgument - 1);
1083 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1084 HasDefaultArg = TTP->hasDefaultArgument();
1085 else if (NonTypeTemplateParmDecl *NTTP
1086 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1087 HasDefaultArg = NTTP->hasDefaultArgument();
1088 else {
1089 assert(isa<TemplateTemplateParmDecl>(Param));
1090 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001091 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001092 }
1093
1094 if (!HasDefaultArg)
1095 break;
1096 }
1097 }
1098
1099 if (LastDeducibleArgument) {
1100 // Some of the function template arguments cannot be deduced from a
1101 // function call, so we introduce an explicit template argument list
1102 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001103 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001104 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1105 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001106 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001107 }
1108
1109 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001110 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001111 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001112 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001113 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001114 return Result;
1115 }
1116
1117 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001118 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1119 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001120 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001121 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001122 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001123 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001124 return Result;
1125 }
1126
Douglas Gregor9630eb62009-11-17 16:44:22 +00001127 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001128 Selector Sel = Method->getSelector();
1129 if (Sel.isUnarySelector()) {
1130 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1131 return Result;
1132 }
1133
Douglas Gregord3c68542009-11-19 01:08:35 +00001134 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1135 SelName += ':';
1136 if (StartParameter == 0)
1137 Result->AddTypedTextChunk(SelName);
1138 else {
1139 Result->AddInformativeChunk(SelName);
1140
1141 // If there is only one parameter, and we're past it, add an empty
1142 // typed-text chunk since there is nothing to type.
1143 if (Method->param_size() == 1)
1144 Result->AddTypedTextChunk("");
1145 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001146 unsigned Idx = 0;
1147 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1148 PEnd = Method->param_end();
1149 P != PEnd; (void)++P, ++Idx) {
1150 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001151 std::string Keyword;
1152 if (Idx > StartParameter)
1153 Keyword = " ";
Douglas Gregor9630eb62009-11-17 16:44:22 +00001154 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1155 Keyword += II->getName().str();
1156 Keyword += ":";
Douglas Gregor4ad96852009-11-19 07:41:15 +00001157 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001158 Result->AddInformativeChunk(Keyword);
1159 } else if (Idx == StartParameter)
1160 Result->AddTypedTextChunk(Keyword);
1161 else
1162 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001163 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001164
1165 // If we're before the starting parameter, skip the placeholder.
1166 if (Idx < StartParameter)
1167 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001168
1169 std::string Arg;
1170 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1171 Arg = "(" + Arg + ")";
1172 if (IdentifierInfo *II = (*P)->getIdentifier())
1173 Arg += II->getName().str();
Douglas Gregor4ad96852009-11-19 07:41:15 +00001174 if (AllParametersAreInformative)
1175 Result->AddInformativeChunk(Arg);
1176 else
1177 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001178 }
1179
1180 return Result;
1181 }
1182
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001183 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00001184 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1185 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001186
1187 Result->AddTypedTextChunk(ND->getNameAsString());
1188 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001189}
1190
Douglas Gregor86d802e2009-09-23 00:34:09 +00001191CodeCompletionString *
1192CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1193 unsigned CurrentArg,
1194 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001195 typedef CodeCompletionString::Chunk Chunk;
1196
Douglas Gregor86d802e2009-09-23 00:34:09 +00001197 CodeCompletionString *Result = new CodeCompletionString;
1198 FunctionDecl *FDecl = getFunction();
1199 const FunctionProtoType *Proto
1200 = dyn_cast<FunctionProtoType>(getFunctionType());
1201 if (!FDecl && !Proto) {
1202 // Function without a prototype. Just give the return type and a
1203 // highlighted ellipsis.
1204 const FunctionType *FT = getFunctionType();
1205 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001206 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001207 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1208 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1209 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001210 return Result;
1211 }
1212
1213 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001214 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00001215 else
1216 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001217 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001218
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001219 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001220 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1221 for (unsigned I = 0; I != NumParams; ++I) {
1222 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001223 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001224
1225 std::string ArgString;
1226 QualType ArgType;
1227
1228 if (FDecl) {
1229 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1230 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1231 } else {
1232 ArgType = Proto->getArgType(I);
1233 }
1234
1235 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1236
1237 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001238 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00001239 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001240 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001241 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001242 }
1243
1244 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001245 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001246 if (CurrentArg < NumParams)
1247 Result->AddTextChunk("...");
1248 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001249 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001250 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001251 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001252
1253 return Result;
1254}
1255
Douglas Gregor86d9a522009-09-21 16:56:56 +00001256namespace {
1257 struct SortCodeCompleteResult {
1258 typedef CodeCompleteConsumer::Result Result;
1259
Douglas Gregor6a684032009-09-28 03:51:44 +00001260 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001261 Selector XSel = X.getObjCSelector();
1262 Selector YSel = Y.getObjCSelector();
1263 if (!XSel.isNull() && !YSel.isNull()) {
1264 // We are comparing two selectors.
1265 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1266 if (N == 0)
1267 ++N;
1268 for (unsigned I = 0; I != N; ++I) {
1269 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1270 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1271 if (!XId || !YId)
1272 return XId && !YId;
1273
1274 switch (XId->getName().compare_lower(YId->getName())) {
1275 case -1: return true;
1276 case 1: return false;
1277 default: break;
1278 }
1279 }
1280
1281 return XSel.getNumArgs() < YSel.getNumArgs();
1282 }
1283
1284 // For non-selectors, order by kind.
1285 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00001286 return X.getNameKind() < Y.getNameKind();
1287
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001288 // Order identifiers by comparison of their lowercased names.
1289 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1290 return XId->getName().compare_lower(
1291 Y.getAsIdentifierInfo()->getName()) < 0;
1292
1293 // Order overloaded operators by the order in which they appear
1294 // in our list of operators.
1295 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1296 return XOp < Y.getCXXOverloadedOperator();
1297
1298 // Order C++0x user-defined literal operators lexically by their
1299 // lowercased suffixes.
1300 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1301 return XLit->getName().compare_lower(
1302 Y.getCXXLiteralIdentifier()->getName()) < 0;
1303
1304 // The only stable ordering we have is to turn the name into a
1305 // string and then compare the lower-case strings. This is
1306 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00001307 return llvm::StringRef(X.getAsString()).compare_lower(
1308 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00001309 }
1310
Douglas Gregor86d9a522009-09-21 16:56:56 +00001311 bool operator()(const Result &X, const Result &Y) const {
1312 // Sort first by rank.
1313 if (X.Rank < Y.Rank)
1314 return true;
1315 else if (X.Rank > Y.Rank)
1316 return false;
1317
Douglas Gregor54f01612009-11-19 00:01:57 +00001318 // We use a special ordering for keywords and patterns, based on the
1319 // typed text.
1320 if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
1321 (Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
1322 const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword
1323 : X.Pattern->getTypedText();
1324 const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
1325 : Y.Pattern->getTypedText();
Benjamin Kramerf42d4882009-12-05 10:07:04 +00001326 return llvm::StringRef(XStr).compare_lower(YStr) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001327 }
1328
Douglas Gregor86d9a522009-09-21 16:56:56 +00001329 // Result kinds are ordered by decreasing importance.
1330 if (X.Kind < Y.Kind)
1331 return true;
1332 else if (X.Kind > Y.Kind)
1333 return false;
1334
1335 // Non-hidden names precede hidden names.
1336 if (X.Hidden != Y.Hidden)
1337 return !X.Hidden;
1338
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001339 // Non-nested-name-specifiers precede nested-name-specifiers.
1340 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1341 return !X.StartsNestedNameSpecifier;
1342
Douglas Gregor86d9a522009-09-21 16:56:56 +00001343 // Ordering depends on the kind of result.
1344 switch (X.Kind) {
1345 case Result::RK_Declaration:
1346 // Order based on the declaration names.
Douglas Gregor6a684032009-09-28 03:51:44 +00001347 return isEarlierDeclarationName(X.Declaration->getDeclName(),
1348 Y.Declaration->getDeclName());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001349
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001350 case Result::RK_Macro:
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001351 return X.Macro->getName().compare_lower(Y.Macro->getName()) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001352
1353 case Result::RK_Keyword:
1354 case Result::RK_Pattern:
Jeffrey Yasskin9f61aa92009-12-12 05:05:38 +00001355 llvm_unreachable("Result kinds handled above");
Douglas Gregor54f01612009-11-19 00:01:57 +00001356 break;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001357 }
1358
1359 // Silence GCC warning.
1360 return false;
1361 }
1362 };
1363}
1364
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001365static void AddMacroResults(Preprocessor &PP, unsigned Rank,
1366 ResultBuilder &Results) {
1367 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001368 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1369 MEnd = PP.macro_end();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001370 M != MEnd; ++M)
1371 Results.MaybeAddResult(CodeCompleteConsumer::Result(M->first, Rank));
1372 Results.ExitScope();
1373}
1374
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001375static void HandleCodeCompleteResults(Sema *S,
1376 CodeCompleteConsumer *CodeCompleter,
1377 CodeCompleteConsumer::Result *Results,
1378 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001379 // Sort the results by rank/kind/etc.
1380 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1381
1382 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001383 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00001384
1385 for (unsigned I = 0; I != NumResults; ++I)
1386 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001387}
1388
Douglas Gregor791215b2009-09-21 20:51:25 +00001389void Sema::CodeCompleteOrdinaryName(Scope *S) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001390 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor791215b2009-09-21 20:51:25 +00001391 ResultBuilder Results(*this, &ResultBuilder::IsOrdinaryName);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001392 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1393 0, CurContext, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001394
1395 Results.EnterNewScope();
1396 AddTypeSpecifierResults(getLangOptions(), NextRank, Results);
1397
1398 if (getLangOptions().ObjC1) {
1399 // Add the "super" keyword, if appropriate.
1400 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
1401 if (Method->getClassInterface()->getSuperClass())
1402 Results.MaybeAddResult(Result("super", NextRank));
1403 }
1404
1405 Results.ExitScope();
1406
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001407 if (CodeCompleter->includeMacros())
1408 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001409 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00001410}
1411
Douglas Gregor95ac6552009-11-18 01:29:26 +00001412static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00001413 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00001414 DeclContext *CurContext,
1415 ResultBuilder &Results) {
1416 typedef CodeCompleteConsumer::Result Result;
1417
1418 // Add properties in this container.
1419 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1420 PEnd = Container->prop_end();
1421 P != PEnd;
1422 ++P)
1423 Results.MaybeAddResult(Result(*P, 0), CurContext);
1424
1425 // Add properties in referenced protocols.
1426 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1427 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1428 PEnd = Protocol->protocol_end();
1429 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001430 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001431 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00001432 if (AllowCategories) {
1433 // Look through categories.
1434 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1435 Category; Category = Category->getNextClassCategory())
1436 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1437 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001438
1439 // Look through protocols.
1440 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1441 E = IFace->protocol_end();
1442 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001443 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001444
1445 // Look in the superclass.
1446 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00001447 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
1448 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001449 } else if (const ObjCCategoryDecl *Category
1450 = dyn_cast<ObjCCategoryDecl>(Container)) {
1451 // Look through protocols.
1452 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
1453 PEnd = Category->protocol_end();
1454 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001455 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001456 }
1457}
1458
Douglas Gregor81b747b2009-09-17 21:32:03 +00001459void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
1460 SourceLocation OpLoc,
1461 bool IsArrow) {
1462 if (!BaseE || !CodeCompleter)
1463 return;
1464
Douglas Gregor86d9a522009-09-21 16:56:56 +00001465 typedef CodeCompleteConsumer::Result Result;
1466
Douglas Gregor81b747b2009-09-17 21:32:03 +00001467 Expr *Base = static_cast<Expr *>(BaseE);
1468 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001469
1470 if (IsArrow) {
1471 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1472 BaseType = Ptr->getPointeeType();
1473 else if (BaseType->isObjCObjectPointerType())
1474 /*Do nothing*/ ;
1475 else
1476 return;
1477 }
1478
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001479 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001480 unsigned NextRank = 0;
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001481
Douglas Gregor95ac6552009-11-18 01:29:26 +00001482 Results.EnterNewScope();
1483 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
1484 // Access to a C/C++ class, struct, or union.
1485 NextRank = CollectMemberLookupResults(Record->getDecl(), NextRank,
1486 Record->getDecl(), Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001487
Douglas Gregor95ac6552009-11-18 01:29:26 +00001488 if (getLangOptions().CPlusPlus) {
1489 if (!Results.empty()) {
1490 // The "template" keyword can follow "->" or "." in the grammar.
1491 // However, we only want to suggest the template keyword if something
1492 // is dependent.
1493 bool IsDependent = BaseType->isDependentType();
1494 if (!IsDependent) {
1495 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
1496 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
1497 IsDependent = Ctx->isDependentContext();
1498 break;
1499 }
1500 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001501
Douglas Gregor95ac6552009-11-18 01:29:26 +00001502 if (IsDependent)
1503 Results.MaybeAddResult(Result("template", NextRank++));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001504 }
1505
Douglas Gregor95ac6552009-11-18 01:29:26 +00001506 // We could have the start of a nested-name-specifier. Add those
1507 // results as well.
Douglas Gregor76282942009-12-11 17:31:05 +00001508 // FIXME: We should really walk base classes to produce
1509 // nested-name-specifiers so that we produce more-precise results.
Douglas Gregor95ac6552009-11-18 01:29:26 +00001510 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
1511 CollectLookupResults(S, Context.getTranslationUnitDecl(), NextRank,
1512 CurContext, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001513 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001514 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
1515 // Objective-C property reference.
1516
1517 // Add property results based on our interface.
1518 const ObjCObjectPointerType *ObjCPtr
1519 = BaseType->getAsObjCInterfacePointerType();
1520 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00001521 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001522
1523 // Add properties from the protocols in a qualified interface.
1524 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
1525 E = ObjCPtr->qual_end();
1526 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001527 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001528
1529 // FIXME: We could (should?) also look for "implicit" properties, identified
1530 // only by the presence of nullary and unary selectors.
1531 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
1532 (!IsArrow && BaseType->isObjCInterfaceType())) {
1533 // Objective-C instance variable access.
1534 ObjCInterfaceDecl *Class = 0;
1535 if (const ObjCObjectPointerType *ObjCPtr
1536 = BaseType->getAs<ObjCObjectPointerType>())
1537 Class = ObjCPtr->getInterfaceDecl();
1538 else
1539 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
1540
1541 // Add all ivars from this class and its superclasses.
1542 for (; Class; Class = Class->getSuperClass()) {
1543 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
1544 IVarEnd = Class->ivar_end();
1545 IVar != IVarEnd; ++IVar)
1546 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
1547 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001548 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001549
1550 // FIXME: How do we cope with isa?
1551
1552 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001553
1554 // Add macros
1555 if (CodeCompleter->includeMacros())
1556 AddMacroResults(PP, NextRank, Results);
1557
1558 // Hand off the results found for code completion.
1559 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00001560}
1561
Douglas Gregor374929f2009-09-18 15:37:17 +00001562void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
1563 if (!CodeCompleter)
1564 return;
1565
Douglas Gregor86d9a522009-09-21 16:56:56 +00001566 typedef CodeCompleteConsumer::Result Result;
1567 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00001568 switch ((DeclSpec::TST)TagSpec) {
1569 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001570 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00001571 break;
1572
1573 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001574 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00001575 break;
1576
1577 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00001578 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001579 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00001580 break;
1581
1582 default:
1583 assert(false && "Unknown type specifier kind in CodeCompleteTag");
1584 return;
1585 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001586
1587 ResultBuilder Results(*this, Filter);
1588 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00001589 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001590
1591 if (getLangOptions().CPlusPlus) {
1592 // We could have the start of a nested-name-specifier. Add those
1593 // results as well.
1594 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001595 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1596 NextRank, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001597 }
1598
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001599 if (CodeCompleter->includeMacros())
1600 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001601 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00001602}
1603
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001604void Sema::CodeCompleteCase(Scope *S) {
1605 if (getSwitchStack().empty() || !CodeCompleter)
1606 return;
1607
1608 SwitchStmt *Switch = getSwitchStack().back();
1609 if (!Switch->getCond()->getType()->isEnumeralType())
1610 return;
1611
1612 // Code-complete the cases of a switch statement over an enumeration type
1613 // by providing the list of
1614 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
1615
1616 // Determine which enumerators we have already seen in the switch statement.
1617 // FIXME: Ideally, we would also be able to look *past* the code-completion
1618 // token, in case we are code-completing in the middle of the switch and not
1619 // at the end. However, we aren't able to do so at the moment.
1620 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001621 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001622 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
1623 SC = SC->getNextSwitchCase()) {
1624 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
1625 if (!Case)
1626 continue;
1627
1628 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
1629 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
1630 if (EnumConstantDecl *Enumerator
1631 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
1632 // We look into the AST of the case statement to determine which
1633 // enumerator was named. Alternatively, we could compute the value of
1634 // the integral constant expression, then compare it against the
1635 // values of each enumerator. However, value-based approach would not
1636 // work as well with C++ templates where enumerators declared within a
1637 // template are type- and value-dependent.
1638 EnumeratorsSeen.insert(Enumerator);
1639
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001640 // If this is a qualified-id, keep track of the nested-name-specifier
1641 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001642 //
1643 // switch (TagD.getKind()) {
1644 // case TagDecl::TK_enum:
1645 // break;
1646 // case XXX
1647 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001648 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001649 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
1650 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00001651 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001652 }
1653 }
1654
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001655 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
1656 // If there are no prior enumerators in C++, check whether we have to
1657 // qualify the names of the enumerators that we suggest, because they
1658 // may not be visible in this scope.
1659 Qualifier = getRequiredQualification(Context, CurContext,
1660 Enum->getDeclContext());
1661
1662 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
1663 }
1664
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001665 // Add any enumerators that have not yet been mentioned.
1666 ResultBuilder Results(*this);
1667 Results.EnterNewScope();
1668 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
1669 EEnd = Enum->enumerator_end();
1670 E != EEnd; ++E) {
1671 if (EnumeratorsSeen.count(*E))
1672 continue;
1673
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001674 Results.MaybeAddResult(CodeCompleteConsumer::Result(*E, 0, Qualifier));
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001675 }
1676 Results.ExitScope();
1677
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001678 if (CodeCompleter->includeMacros())
1679 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001680 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001681}
1682
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001683namespace {
1684 struct IsBetterOverloadCandidate {
1685 Sema &S;
1686
1687 public:
1688 explicit IsBetterOverloadCandidate(Sema &S) : S(S) { }
1689
1690 bool
1691 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
1692 return S.isBetterOverloadCandidate(X, Y);
1693 }
1694 };
1695}
1696
1697void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
1698 ExprTy **ArgsIn, unsigned NumArgs) {
1699 if (!CodeCompleter)
1700 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00001701
1702 // When we're code-completing for a call, we fall back to ordinary
1703 // name code-completion whenever we can't produce specific
1704 // results. We may want to revisit this strategy in the future,
1705 // e.g., by merging the two kinds of results.
1706
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001707 Expr *Fn = (Expr *)FnIn;
1708 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00001709
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001710 // Ignore type-dependent call expressions entirely.
1711 if (Fn->isTypeDependent() ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00001712 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
1713 CodeCompleteOrdinaryName(S);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001714 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00001715 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001716
John McCallba135432009-11-21 08:51:07 +00001717 llvm::SmallVector<NamedDecl*,8> Fns;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001718 DeclarationName UnqualifiedName;
1719 NestedNameSpecifier *Qualifier;
1720 SourceRange QualifierRange;
1721 bool ArgumentDependentLookup;
John McCall7453ed42009-11-22 00:44:51 +00001722 bool Overloaded;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001723 bool HasExplicitTemplateArgs;
John McCalld5532b62009-11-23 01:53:49 +00001724 TemplateArgumentListInfo ExplicitTemplateArgs;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001725
John McCallba135432009-11-21 08:51:07 +00001726 DeconstructCallFunction(Fn, Fns, UnqualifiedName, Qualifier, QualifierRange,
John McCall7453ed42009-11-22 00:44:51 +00001727 ArgumentDependentLookup, Overloaded,
John McCalld5532b62009-11-23 01:53:49 +00001728 HasExplicitTemplateArgs, ExplicitTemplateArgs);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001729
1730
1731 // FIXME: What if we're calling something that isn't a function declaration?
1732 // FIXME: What if we're calling a pseudo-destructor?
1733 // FIXME: What if we're calling a member function?
1734
1735 // Build an overload candidate set based on the functions we find.
1736 OverloadCandidateSet CandidateSet;
John McCallba135432009-11-21 08:51:07 +00001737 AddOverloadedCallCandidates(Fns, UnqualifiedName,
John McCalld5532b62009-11-23 01:53:49 +00001738 ArgumentDependentLookup,
1739 (HasExplicitTemplateArgs ? &ExplicitTemplateArgs : 0),
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001740 Args, NumArgs,
1741 CandidateSet,
1742 /*PartialOverloading=*/true);
1743
1744 // Sort the overload candidate set by placing the best overloads first.
1745 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
1746 IsBetterOverloadCandidate(*this));
1747
1748 // Add the remaining viable overload candidates as code-completion reslults.
Douglas Gregor05944382009-09-23 00:16:58 +00001749 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
1750 llvm::SmallVector<ResultCandidate, 8> Results;
Anders Carlsson90756302009-09-22 17:29:51 +00001751
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001752 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
1753 CandEnd = CandidateSet.end();
1754 Cand != CandEnd; ++Cand) {
1755 if (Cand->Viable)
Douglas Gregor05944382009-09-23 00:16:58 +00001756 Results.push_back(ResultCandidate(Cand->Function));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001757 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00001758
1759 if (Results.empty())
1760 CodeCompleteOrdinaryName(S);
1761 else
1762 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
1763 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001764}
1765
Douglas Gregor81b747b2009-09-17 21:32:03 +00001766void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
1767 bool EnteringContext) {
1768 if (!SS.getScopeRep() || !CodeCompleter)
1769 return;
1770
Douglas Gregor86d9a522009-09-21 16:56:56 +00001771 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
1772 if (!Ctx)
1773 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00001774
1775 // Try to instantiate any non-dependent declaration contexts before
1776 // we look in them.
1777 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
1778 return;
1779
Douglas Gregor86d9a522009-09-21 16:56:56 +00001780 ResultBuilder Results(*this);
Douglas Gregor456c4a12009-09-21 20:12:40 +00001781 unsigned NextRank = CollectMemberLookupResults(Ctx, 0, Ctx, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001782
1783 // The "template" keyword can follow "::" in the grammar, but only
1784 // put it into the grammar if the nested-name-specifier is dependent.
1785 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
1786 if (!Results.empty() && NNS->isDependent())
1787 Results.MaybeAddResult(CodeCompleteConsumer::Result("template", NextRank));
1788
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001789 if (CodeCompleter->includeMacros())
1790 AddMacroResults(PP, NextRank + 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001791 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00001792}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001793
1794void Sema::CodeCompleteUsing(Scope *S) {
1795 if (!CodeCompleter)
1796 return;
1797
Douglas Gregor86d9a522009-09-21 16:56:56 +00001798 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001799 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001800
1801 // If we aren't in class scope, we could see the "namespace" keyword.
1802 if (!S->isClassScope())
1803 Results.MaybeAddResult(CodeCompleteConsumer::Result("namespace", 0));
1804
1805 // After "using", we can see anything that would start a
1806 // nested-name-specifier.
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001807 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1808 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001809 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001810
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001811 if (CodeCompleter->includeMacros())
1812 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001813 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001814}
1815
1816void Sema::CodeCompleteUsingDirective(Scope *S) {
1817 if (!CodeCompleter)
1818 return;
1819
Douglas Gregor86d9a522009-09-21 16:56:56 +00001820 // After "using namespace", we expect to see a namespace name or namespace
1821 // alias.
1822 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001823 Results.EnterNewScope();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001824 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1825 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001826 Results.ExitScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001827 if (CodeCompleter->includeMacros())
1828 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001829 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001830}
1831
1832void Sema::CodeCompleteNamespaceDecl(Scope *S) {
1833 if (!CodeCompleter)
1834 return;
1835
Douglas Gregor86d9a522009-09-21 16:56:56 +00001836 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
1837 DeclContext *Ctx = (DeclContext *)S->getEntity();
1838 if (!S->getParent())
1839 Ctx = Context.getTranslationUnitDecl();
1840
1841 if (Ctx && Ctx->isFileContext()) {
1842 // We only want to see those namespaces that have already been defined
1843 // within this scope, because its likely that the user is creating an
1844 // extended namespace declaration. Keep track of the most recent
1845 // definition of each namespace.
1846 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
1847 for (DeclContext::specific_decl_iterator<NamespaceDecl>
1848 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
1849 NS != NSEnd; ++NS)
1850 OrigToLatest[NS->getOriginalNamespace()] = *NS;
1851
1852 // Add the most recent definition (or extended definition) of each
1853 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001854 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001855 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
1856 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
1857 NS != NSEnd; ++NS)
Douglas Gregor456c4a12009-09-21 20:12:40 +00001858 Results.MaybeAddResult(CodeCompleteConsumer::Result(NS->second, 0),
1859 CurContext);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001860 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001861 }
1862
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001863 if (CodeCompleter->includeMacros())
1864 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001865 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001866}
1867
1868void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
1869 if (!CodeCompleter)
1870 return;
1871
Douglas Gregor86d9a522009-09-21 16:56:56 +00001872 // After "namespace", we expect to see a namespace or alias.
1873 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001874 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1875 0, CurContext, Results);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001876 if (CodeCompleter->includeMacros())
1877 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001878 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001879}
1880
Douglas Gregored8d3222009-09-18 20:05:18 +00001881void Sema::CodeCompleteOperatorName(Scope *S) {
1882 if (!CodeCompleter)
1883 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001884
1885 typedef CodeCompleteConsumer::Result Result;
1886 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001887 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00001888
Douglas Gregor86d9a522009-09-21 16:56:56 +00001889 // Add the names of overloadable operators.
1890#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1891 if (std::strcmp(Spelling, "?")) \
1892 Results.MaybeAddResult(Result(Spelling, 0));
1893#include "clang/Basic/OperatorKinds.def"
1894
1895 // Add any type names visible from the current scope
1896 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00001897 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001898
1899 // Add any type specifiers
1900 AddTypeSpecifierResults(getLangOptions(), 0, Results);
1901
1902 // Add any nested-name-specifiers
1903 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001904 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1905 NextRank + 1, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001906 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001907
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001908 if (CodeCompleter->includeMacros())
1909 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001910 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00001911}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001912
Douglas Gregorc464ae82009-12-07 09:27:33 +00001913void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
1914 bool InInterface) {
1915 typedef CodeCompleteConsumer::Result Result;
1916 ResultBuilder Results(*this);
1917 Results.EnterNewScope();
1918 if (ObjCImpDecl) {
1919 // Since we have an implementation, we can end it.
1920 Results.MaybeAddResult(Result("end", 0));
1921
1922 CodeCompletionString *Pattern = 0;
1923 Decl *ImpDecl = ObjCImpDecl.getAs<Decl>();
1924 if (isa<ObjCImplementationDecl>(ImpDecl) ||
1925 isa<ObjCCategoryImplDecl>(ImpDecl)) {
1926 // @dynamic
1927 Pattern = new CodeCompletionString;
1928 Pattern->AddTypedTextChunk("dynamic");
1929 Pattern->AddTextChunk(" ");
1930 Pattern->AddPlaceholderChunk("property");
1931 Results.MaybeAddResult(Result(Pattern, 0));
1932
1933 // @synthesize
1934 Pattern = new CodeCompletionString;
1935 Pattern->AddTypedTextChunk("synthesize");
1936 Pattern->AddTextChunk(" ");
1937 Pattern->AddPlaceholderChunk("property");
1938 Results.MaybeAddResult(Result(Pattern, 0));
1939 }
1940 } else if (InInterface) {
1941 // Since we have an interface or protocol, we can end it.
1942 Results.MaybeAddResult(Result("end", 0));
1943
1944 if (LangOpts.ObjC2) {
1945 // @property
1946 Results.MaybeAddResult(Result("property", 0));
1947 }
1948
1949 // @required
1950 Results.MaybeAddResult(Result("required", 0));
1951
1952 // @optional
1953 Results.MaybeAddResult(Result("optional", 0));
1954 } else {
1955 CodeCompletionString *Pattern = 0;
1956
1957 // @class name ;
1958 Pattern = new CodeCompletionString;
1959 Pattern->AddTypedTextChunk("class");
1960 Pattern->AddTextChunk(" ");
1961 Pattern->AddPlaceholderChunk("identifier");
1962 Pattern->AddTextChunk(";"); // add ';' chunk
1963 Results.MaybeAddResult(Result(Pattern, 0));
1964
1965 // @interface name
1966 // FIXME: Could introduce the whole pattern, including superclasses and
1967 // such.
1968 Pattern = new CodeCompletionString;
1969 Pattern->AddTypedTextChunk("interface");
1970 Pattern->AddTextChunk(" ");
1971 Pattern->AddPlaceholderChunk("class");
1972 Results.MaybeAddResult(Result(Pattern, 0));
1973
1974 // @protocol name
1975 Pattern = new CodeCompletionString;
1976 Pattern->AddTypedTextChunk("protocol");
1977 Pattern->AddTextChunk(" ");
1978 Pattern->AddPlaceholderChunk("protocol");
1979 Results.MaybeAddResult(Result(Pattern, 0));
1980
1981 // @implementation name
1982 Pattern = new CodeCompletionString;
1983 Pattern->AddTypedTextChunk("implementation");
1984 Pattern->AddTextChunk(" ");
1985 Pattern->AddPlaceholderChunk("class");
1986 Results.MaybeAddResult(Result(Pattern, 0));
1987
1988 // @compatibility_alias name
1989 Pattern = new CodeCompletionString;
1990 Pattern->AddTypedTextChunk("compatibility_alias");
1991 Pattern->AddTextChunk(" ");
1992 Pattern->AddPlaceholderChunk("alias");
1993 Pattern->AddTextChunk(" ");
1994 Pattern->AddPlaceholderChunk("class");
1995 Results.MaybeAddResult(Result(Pattern, 0));
1996 }
1997 Results.ExitScope();
1998 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
1999}
2000
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002001static void AddObjCExpressionResults(unsigned Rank, ResultBuilder &Results) {
2002 typedef CodeCompleteConsumer::Result Result;
2003 CodeCompletionString *Pattern = 0;
2004
2005 // @encode ( type-name )
2006 Pattern = new CodeCompletionString;
2007 Pattern->AddTypedTextChunk("encode");
2008 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2009 Pattern->AddPlaceholderChunk("type-name");
2010 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2011 Results.MaybeAddResult(Result(Pattern, Rank));
2012
2013 // @protocol ( protocol-name )
2014 Pattern = new CodeCompletionString;
2015 Pattern->AddTypedTextChunk("protocol");
2016 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2017 Pattern->AddPlaceholderChunk("protocol-name");
2018 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2019 Results.MaybeAddResult(Result(Pattern, Rank));
2020
2021 // @selector ( selector )
2022 Pattern = new CodeCompletionString;
2023 Pattern->AddTypedTextChunk("selector");
2024 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2025 Pattern->AddPlaceholderChunk("selector");
2026 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2027 Results.MaybeAddResult(Result(Pattern, Rank));
2028}
2029
2030void Sema::CodeCompleteObjCAtStatement(Scope *S) {
2031 typedef CodeCompleteConsumer::Result Result;
2032 ResultBuilder Results(*this);
2033 Results.EnterNewScope();
2034
2035 CodeCompletionString *Pattern = 0;
2036
2037 // @try { statements } @catch ( declaration ) { statements } @finally
2038 // { statements }
2039 Pattern = new CodeCompletionString;
2040 Pattern->AddTypedTextChunk("try");
2041 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2042 Pattern->AddPlaceholderChunk("statements");
2043 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2044 Pattern->AddTextChunk("@catch");
2045 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2046 Pattern->AddPlaceholderChunk("parameter");
2047 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2048 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2049 Pattern->AddPlaceholderChunk("statements");
2050 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2051 Pattern->AddTextChunk("@finally");
2052 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2053 Pattern->AddPlaceholderChunk("statements");
2054 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2055 Results.MaybeAddResult(Result(Pattern, 0));
2056
2057 // @throw
2058 Pattern = new CodeCompletionString;
2059 Pattern->AddTypedTextChunk("throw");
2060 Pattern->AddTextChunk(" ");
2061 Pattern->AddPlaceholderChunk("expression");
2062 Pattern->AddTextChunk(";");
2063 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2064
2065 // @synchronized ( expression ) { statements }
2066 Pattern = new CodeCompletionString;
2067 Pattern->AddTypedTextChunk("synchronized");
2068 Pattern->AddTextChunk(" ");
2069 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2070 Pattern->AddPlaceholderChunk("expression");
2071 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2072 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2073 Pattern->AddPlaceholderChunk("statements");
2074 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2075 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2076
2077 AddObjCExpressionResults(0, Results);
2078 Results.ExitScope();
2079 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2080}
2081
2082void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2083 ResultBuilder Results(*this);
2084 Results.EnterNewScope();
2085 AddObjCExpressionResults(0, Results);
2086 Results.ExitScope();
2087 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2088}
2089
Douglas Gregor988358f2009-11-19 00:14:45 +00002090/// \brief Determine whether the addition of the given flag to an Objective-C
2091/// property's attributes will cause a conflict.
2092static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2093 // Check if we've already added this flag.
2094 if (Attributes & NewFlag)
2095 return true;
2096
2097 Attributes |= NewFlag;
2098
2099 // Check for collisions with "readonly".
2100 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2101 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2102 ObjCDeclSpec::DQ_PR_assign |
2103 ObjCDeclSpec::DQ_PR_copy |
2104 ObjCDeclSpec::DQ_PR_retain)))
2105 return true;
2106
2107 // Check for more than one of { assign, copy, retain }.
2108 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2109 ObjCDeclSpec::DQ_PR_copy |
2110 ObjCDeclSpec::DQ_PR_retain);
2111 if (AssignCopyRetMask &&
2112 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2113 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2114 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2115 return true;
2116
2117 return false;
2118}
2119
Douglas Gregora93b1082009-11-18 23:08:07 +00002120void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00002121 if (!CodeCompleter)
2122 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00002123
Steve Naroffece8e712009-10-08 21:55:05 +00002124 unsigned Attributes = ODS.getPropertyAttributes();
2125
2126 typedef CodeCompleteConsumer::Result Result;
2127 ResultBuilder Results(*this);
2128 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00002129 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Steve Naroffece8e712009-10-08 21:55:05 +00002130 Results.MaybeAddResult(CodeCompleteConsumer::Result("readonly", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002131 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Steve Naroffece8e712009-10-08 21:55:05 +00002132 Results.MaybeAddResult(CodeCompleteConsumer::Result("assign", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002133 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Steve Naroffece8e712009-10-08 21:55:05 +00002134 Results.MaybeAddResult(CodeCompleteConsumer::Result("readwrite", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002135 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Steve Naroffece8e712009-10-08 21:55:05 +00002136 Results.MaybeAddResult(CodeCompleteConsumer::Result("retain", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002137 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Steve Naroffece8e712009-10-08 21:55:05 +00002138 Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002139 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Steve Naroffece8e712009-10-08 21:55:05 +00002140 Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002141 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002142 CodeCompletionString *Setter = new CodeCompletionString;
2143 Setter->AddTypedTextChunk("setter");
2144 Setter->AddTextChunk(" = ");
2145 Setter->AddPlaceholderChunk("method");
2146 Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
2147 }
Douglas Gregor988358f2009-11-19 00:14:45 +00002148 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002149 CodeCompletionString *Getter = new CodeCompletionString;
2150 Getter->AddTypedTextChunk("getter");
2151 Getter->AddTextChunk(" = ");
2152 Getter->AddPlaceholderChunk("method");
2153 Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
2154 }
Steve Naroffece8e712009-10-08 21:55:05 +00002155 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002156 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00002157}
Steve Naroffc4df6d22009-11-07 02:08:14 +00002158
Douglas Gregor4ad96852009-11-19 07:41:15 +00002159/// \brief Descripts the kind of Objective-C method that we want to find
2160/// via code completion.
2161enum ObjCMethodKind {
2162 MK_Any, //< Any kind of method, provided it means other specified criteria.
2163 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2164 MK_OneArgSelector //< One-argument selector.
2165};
2166
2167static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2168 ObjCMethodKind WantKind,
2169 IdentifierInfo **SelIdents,
2170 unsigned NumSelIdents) {
2171 Selector Sel = Method->getSelector();
2172 if (NumSelIdents > Sel.getNumArgs())
2173 return false;
2174
2175 switch (WantKind) {
2176 case MK_Any: break;
2177 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2178 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2179 }
2180
2181 for (unsigned I = 0; I != NumSelIdents; ++I)
2182 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2183 return false;
2184
2185 return true;
2186}
2187
Douglas Gregor36ecb042009-11-17 23:22:23 +00002188/// \brief Add all of the Objective-C methods in the given Objective-C
2189/// container to the set of results.
2190///
2191/// The container will be a class, protocol, category, or implementation of
2192/// any of the above. This mether will recurse to include methods from
2193/// the superclasses of classes along with their categories, protocols, and
2194/// implementations.
2195///
2196/// \param Container the container in which we'll look to find methods.
2197///
2198/// \param WantInstance whether to add instance methods (only); if false, this
2199/// routine will add factory methods (only).
2200///
2201/// \param CurContext the context in which we're performing the lookup that
2202/// finds methods.
2203///
2204/// \param Results the structure into which we'll add results.
2205static void AddObjCMethods(ObjCContainerDecl *Container,
2206 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00002207 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00002208 IdentifierInfo **SelIdents,
2209 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00002210 DeclContext *CurContext,
2211 ResultBuilder &Results) {
2212 typedef CodeCompleteConsumer::Result Result;
2213 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2214 MEnd = Container->meth_end();
2215 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002216 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2217 // Check whether the selector identifiers we've been given are a
2218 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002219 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00002220 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002221
Douglas Gregord3c68542009-11-19 01:08:35 +00002222 Result R = Result(*M, 0);
2223 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002224 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00002225 Results.MaybeAddResult(R, CurContext);
2226 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00002227 }
2228
2229 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2230 if (!IFace)
2231 return;
2232
2233 // Add methods in protocols.
2234 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2235 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2236 E = Protocols.end();
2237 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002238 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00002239 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002240
2241 // Add methods in categories.
2242 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2243 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00002244 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2245 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002246
2247 // Add a categories protocol methods.
2248 const ObjCList<ObjCProtocolDecl> &Protocols
2249 = CatDecl->getReferencedProtocols();
2250 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2251 E = Protocols.end();
2252 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002253 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2254 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002255
2256 // Add methods in category implementations.
2257 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002258 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2259 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002260 }
2261
2262 // Add methods in superclass.
2263 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002264 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2265 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002266
2267 // Add methods in our implementation, if any.
2268 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002269 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2270 NumSelIdents, CurContext, Results);
2271}
2272
2273
2274void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2275 DeclPtrTy *Methods,
2276 unsigned NumMethods) {
2277 typedef CodeCompleteConsumer::Result Result;
2278
2279 // Try to find the interface where getters might live.
2280 ObjCInterfaceDecl *Class
2281 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2282 if (!Class) {
2283 if (ObjCCategoryDecl *Category
2284 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2285 Class = Category->getClassInterface();
2286
2287 if (!Class)
2288 return;
2289 }
2290
2291 // Find all of the potential getters.
2292 ResultBuilder Results(*this);
2293 Results.EnterNewScope();
2294
2295 // FIXME: We need to do this because Objective-C methods don't get
2296 // pushed into DeclContexts early enough. Argh!
2297 for (unsigned I = 0; I != NumMethods; ++I) {
2298 if (ObjCMethodDecl *Method
2299 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2300 if (Method->isInstanceMethod() &&
2301 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2302 Result R = Result(Method, 0);
2303 R.AllParametersAreInformative = true;
2304 Results.MaybeAddResult(R, CurContext);
2305 }
2306 }
2307
2308 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2309 Results.ExitScope();
2310 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2311}
2312
2313void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2314 DeclPtrTy *Methods,
2315 unsigned NumMethods) {
2316 typedef CodeCompleteConsumer::Result Result;
2317
2318 // Try to find the interface where setters might live.
2319 ObjCInterfaceDecl *Class
2320 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2321 if (!Class) {
2322 if (ObjCCategoryDecl *Category
2323 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2324 Class = Category->getClassInterface();
2325
2326 if (!Class)
2327 return;
2328 }
2329
2330 // Find all of the potential getters.
2331 ResultBuilder Results(*this);
2332 Results.EnterNewScope();
2333
2334 // FIXME: We need to do this because Objective-C methods don't get
2335 // pushed into DeclContexts early enough. Argh!
2336 for (unsigned I = 0; I != NumMethods; ++I) {
2337 if (ObjCMethodDecl *Method
2338 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2339 if (Method->isInstanceMethod() &&
2340 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2341 Result R = Result(Method, 0);
2342 R.AllParametersAreInformative = true;
2343 Results.MaybeAddResult(R, CurContext);
2344 }
2345 }
2346
2347 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2348
2349 Results.ExitScope();
2350 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00002351}
2352
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002353void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregord3c68542009-11-19 01:08:35 +00002354 SourceLocation FNameLoc,
2355 IdentifierInfo **SelIdents,
2356 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002357 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00002358 ObjCInterfaceDecl *CDecl = 0;
2359
Douglas Gregor24a069f2009-11-17 17:59:40 +00002360 if (FName->isStr("super")) {
2361 // We're sending a message to "super".
2362 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2363 // Figure out which interface we're in.
2364 CDecl = CurMethod->getClassInterface();
2365 if (!CDecl)
2366 return;
2367
2368 // Find the superclass of this class.
2369 CDecl = CDecl->getSuperClass();
2370 if (!CDecl)
2371 return;
2372
2373 if (CurMethod->isInstanceMethod()) {
2374 // We are inside an instance method, which means that the message
2375 // send [super ...] is actually calling an instance method on the
2376 // current object. Build the super expression and handle this like
2377 // an instance method.
2378 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2379 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2380 OwningExprResult Super
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002381 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregord3c68542009-11-19 01:08:35 +00002382 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2383 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002384 }
2385
2386 // Okay, we're calling a factory method in our superclass.
2387 }
2388 }
2389
2390 // If the given name refers to an interface type, retrieve the
2391 // corresponding declaration.
2392 if (!CDecl)
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002393 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor24a069f2009-11-17 17:59:40 +00002394 QualType T = GetTypeFromParser(Ty, 0);
2395 if (!T.isNull())
2396 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
2397 CDecl = Interface->getDecl();
2398 }
2399
2400 if (!CDecl && FName->isStr("super")) {
2401 // "super" may be the name of a variable, in which case we are
2402 // probably calling an instance method.
John McCallf7a1a742009-11-24 19:00:30 +00002403 CXXScopeSpec SS;
2404 UnqualifiedId id;
2405 id.setIdentifier(FName, FNameLoc);
2406 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregord3c68542009-11-19 01:08:35 +00002407 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2408 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002409 }
2410
Douglas Gregor36ecb042009-11-17 23:22:23 +00002411 // Add all of the factory methods in this Objective-C class, its protocols,
2412 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00002413 ResultBuilder Results(*this);
2414 Results.EnterNewScope();
Douglas Gregor4ad96852009-11-19 07:41:15 +00002415 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
2416 Results);
Steve Naroffc4df6d22009-11-07 02:08:14 +00002417 Results.ExitScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00002418
Steve Naroffc4df6d22009-11-07 02:08:14 +00002419 // This also suppresses remaining diagnostics.
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002420 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00002421}
2422
Douglas Gregord3c68542009-11-19 01:08:35 +00002423void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
2424 IdentifierInfo **SelIdents,
2425 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002426 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00002427
2428 Expr *RecExpr = static_cast<Expr *>(Receiver);
2429 QualType RecType = RecExpr->getType();
2430
Douglas Gregor36ecb042009-11-17 23:22:23 +00002431 // If necessary, apply function/array conversion to the receiver.
2432 // C99 6.7.5.3p[7,8].
2433 DefaultFunctionArrayConversion(RecExpr);
2434 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00002435
Douglas Gregor36ecb042009-11-17 23:22:23 +00002436 if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType()) {
2437 // FIXME: We're messaging 'id'. Do we actually want to look up every method
2438 // in the universe?
2439 return;
2440 }
2441
Douglas Gregor36ecb042009-11-17 23:22:23 +00002442 // Build the set of methods we can see.
2443 ResultBuilder Results(*this);
2444 Results.EnterNewScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00002445
Douglas Gregorf74a4192009-11-18 00:06:18 +00002446 // Handle messages to Class. This really isn't a message to an instance
2447 // method, so we treat it the same way we would treat a message send to a
2448 // class method.
2449 if (ReceiverType->isObjCClassType() ||
2450 ReceiverType->isObjCQualifiedClassType()) {
2451 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2452 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002453 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
2454 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002455 }
2456 }
2457 // Handle messages to a qualified ID ("id<foo>").
2458 else if (const ObjCObjectPointerType *QualID
2459 = ReceiverType->getAsObjCQualifiedIdType()) {
2460 // Search protocols for instance methods.
2461 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
2462 E = QualID->qual_end();
2463 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002464 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2465 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002466 }
2467 // Handle messages to a pointer to interface type.
2468 else if (const ObjCObjectPointerType *IFacePtr
2469 = ReceiverType->getAsObjCInterfacePointerType()) {
2470 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002471 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
2472 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002473
2474 // Search protocols for instance methods.
2475 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
2476 E = IFacePtr->qual_end();
2477 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002478 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2479 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002480 }
2481
Steve Naroffc4df6d22009-11-07 02:08:14 +00002482 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002483 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00002484}
Douglas Gregor55385fe2009-11-18 04:19:12 +00002485
2486/// \brief Add all of the protocol declarations that we find in the given
2487/// (translation unit) context.
2488static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00002489 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00002490 ResultBuilder &Results) {
2491 typedef CodeCompleteConsumer::Result Result;
2492
2493 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2494 DEnd = Ctx->decls_end();
2495 D != DEnd; ++D) {
2496 // Record any protocols we find.
2497 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00002498 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
2499 Results.MaybeAddResult(Result(Proto, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002500
2501 // Record any forward-declared protocols we find.
2502 if (ObjCForwardProtocolDecl *Forward
2503 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
2504 for (ObjCForwardProtocolDecl::protocol_iterator
2505 P = Forward->protocol_begin(),
2506 PEnd = Forward->protocol_end();
2507 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00002508 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
2509 Results.MaybeAddResult(Result(*P, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002510 }
2511 }
2512}
2513
2514void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
2515 unsigned NumProtocols) {
2516 ResultBuilder Results(*this);
2517 Results.EnterNewScope();
2518
2519 // Tell the result set to ignore all of the protocols we have
2520 // already seen.
2521 for (unsigned I = 0; I != NumProtocols; ++I)
2522 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
2523 Results.Ignore(Protocol);
2524
2525 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00002526 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
2527 Results);
2528
2529 Results.ExitScope();
2530 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2531}
2532
2533void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
2534 ResultBuilder Results(*this);
2535 Results.EnterNewScope();
2536
2537 // Add all protocols.
2538 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
2539 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002540
2541 Results.ExitScope();
2542 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2543}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00002544
2545/// \brief Add all of the Objective-C interface declarations that we find in
2546/// the given (translation unit) context.
2547static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
2548 bool OnlyForwardDeclarations,
2549 bool OnlyUnimplemented,
2550 ResultBuilder &Results) {
2551 typedef CodeCompleteConsumer::Result Result;
2552
2553 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2554 DEnd = Ctx->decls_end();
2555 D != DEnd; ++D) {
2556 // Record any interfaces we find.
2557 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
2558 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
2559 (!OnlyUnimplemented || !Class->getImplementation()))
2560 Results.MaybeAddResult(Result(Class, 0), CurContext);
2561
2562 // Record any forward-declared interfaces we find.
2563 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
2564 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
2565 C != CEnd; ++C)
2566 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
2567 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
2568 Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
2569 }
2570 }
2571}
2572
2573void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
2574 ResultBuilder Results(*this);
2575 Results.EnterNewScope();
2576
2577 // Add all classes.
2578 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
2579 false, Results);
2580
2581 Results.ExitScope();
2582 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2583}
2584
2585void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
2586 ResultBuilder Results(*this);
2587 Results.EnterNewScope();
2588
2589 // Make sure that we ignore the class we're currently defining.
2590 NamedDecl *CurClass
2591 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00002592 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00002593 Results.Ignore(CurClass);
2594
2595 // Add all classes.
2596 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2597 false, Results);
2598
2599 Results.ExitScope();
2600 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2601}
2602
2603void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
2604 ResultBuilder Results(*this);
2605 Results.EnterNewScope();
2606
2607 // Add all unimplemented classes.
2608 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2609 true, Results);
2610
2611 Results.ExitScope();
2612 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2613}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00002614
2615void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
2616 IdentifierInfo *ClassName) {
2617 typedef CodeCompleteConsumer::Result Result;
2618
2619 ResultBuilder Results(*this);
2620
2621 // Ignore any categories we find that have already been implemented by this
2622 // interface.
2623 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2624 NamedDecl *CurClass
2625 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2626 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
2627 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2628 Category = Category->getNextClassCategory())
2629 CategoryNames.insert(Category->getIdentifier());
2630
2631 // Add all of the categories we know about.
2632 Results.EnterNewScope();
2633 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
2634 for (DeclContext::decl_iterator D = TU->decls_begin(),
2635 DEnd = TU->decls_end();
2636 D != DEnd; ++D)
2637 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
2638 if (CategoryNames.insert(Category->getIdentifier()))
2639 Results.MaybeAddResult(Result(Category, 0), CurContext);
2640 Results.ExitScope();
2641
2642 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2643}
2644
2645void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
2646 IdentifierInfo *ClassName) {
2647 typedef CodeCompleteConsumer::Result Result;
2648
2649 // Find the corresponding interface. If we couldn't find the interface, the
2650 // program itself is ill-formed. However, we'll try to be helpful still by
2651 // providing the list of all of the categories we know about.
2652 NamedDecl *CurClass
2653 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2654 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
2655 if (!Class)
2656 return CodeCompleteObjCInterfaceCategory(S, ClassName);
2657
2658 ResultBuilder Results(*this);
2659
2660 // Add all of the categories that have have corresponding interface
2661 // declarations in this class and any of its superclasses, except for
2662 // already-implemented categories in the class itself.
2663 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2664 Results.EnterNewScope();
2665 bool IgnoreImplemented = true;
2666 while (Class) {
2667 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2668 Category = Category->getNextClassCategory())
2669 if ((!IgnoreImplemented || !Category->getImplementation()) &&
2670 CategoryNames.insert(Category->getIdentifier()))
2671 Results.MaybeAddResult(Result(Category, 0), CurContext);
2672
2673 Class = Class->getSuperClass();
2674 IgnoreImplemented = false;
2675 }
2676 Results.ExitScope();
2677
2678 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2679}
Douglas Gregor322328b2009-11-18 22:32:06 +00002680
Douglas Gregor424b2a52009-11-18 22:56:13 +00002681void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00002682 typedef CodeCompleteConsumer::Result Result;
2683 ResultBuilder Results(*this);
2684
2685 // Figure out where this @synthesize lives.
2686 ObjCContainerDecl *Container
2687 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2688 if (!Container ||
2689 (!isa<ObjCImplementationDecl>(Container) &&
2690 !isa<ObjCCategoryImplDecl>(Container)))
2691 return;
2692
2693 // Ignore any properties that have already been implemented.
2694 for (DeclContext::decl_iterator D = Container->decls_begin(),
2695 DEnd = Container->decls_end();
2696 D != DEnd; ++D)
2697 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
2698 Results.Ignore(PropertyImpl->getPropertyDecl());
2699
2700 // Add any properties that we find.
2701 Results.EnterNewScope();
2702 if (ObjCImplementationDecl *ClassImpl
2703 = dyn_cast<ObjCImplementationDecl>(Container))
2704 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
2705 Results);
2706 else
2707 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
2708 false, CurContext, Results);
2709 Results.ExitScope();
2710
2711 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2712}
2713
2714void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
2715 IdentifierInfo *PropertyName,
2716 DeclPtrTy ObjCImpDecl) {
2717 typedef CodeCompleteConsumer::Result Result;
2718 ResultBuilder Results(*this);
2719
2720 // Figure out where this @synthesize lives.
2721 ObjCContainerDecl *Container
2722 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2723 if (!Container ||
2724 (!isa<ObjCImplementationDecl>(Container) &&
2725 !isa<ObjCCategoryImplDecl>(Container)))
2726 return;
2727
2728 // Figure out which interface we're looking into.
2729 ObjCInterfaceDecl *Class = 0;
2730 if (ObjCImplementationDecl *ClassImpl
2731 = dyn_cast<ObjCImplementationDecl>(Container))
2732 Class = ClassImpl->getClassInterface();
2733 else
2734 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
2735 ->getClassInterface();
2736
2737 // Add all of the instance variables in this class and its superclasses.
2738 Results.EnterNewScope();
2739 for(; Class; Class = Class->getSuperClass()) {
2740 // FIXME: We could screen the type of each ivar for compatibility with
2741 // the property, but is that being too paternal?
2742 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
2743 IVarEnd = Class->ivar_end();
2744 IVar != IVarEnd; ++IVar)
2745 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
2746 }
2747 Results.ExitScope();
2748
2749 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2750}