blob: ef82a941b5a5de97a5ae803fe260e5d6ec21f29a [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
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000243ResultBuilder::ShadowMapEntry::iterator
244ResultBuilder::ShadowMapEntry::begin() const {
245 if (DeclOrVector.isNull())
246 return iterator();
247
248 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
249 return iterator(ND, SingleDeclIndex);
250
251 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
252}
253
254ResultBuilder::ShadowMapEntry::iterator
255ResultBuilder::ShadowMapEntry::end() const {
256 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
257 return iterator();
258
259 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
260}
261
Douglas Gregor86d9a522009-09-21 16:56:56 +0000262/// \brief Determines whether the given hidden result could be found with
263/// some extra work, e.g., by qualifying the name.
264///
265/// \param Hidden the declaration that is hidden by the currenly \p Visible
266/// declaration.
267///
268/// \param Visible the declaration with the same name that is already visible.
269///
270/// \returns true if the hidden result can be found by some mechanism,
271/// false otherwise.
272static bool canHiddenResultBeFound(const LangOptions &LangOpts,
273 NamedDecl *Hidden, NamedDecl *Visible) {
274 // In C, there is no way to refer to a hidden name.
275 if (!LangOpts.CPlusPlus)
276 return false;
277
278 DeclContext *HiddenCtx = Hidden->getDeclContext()->getLookupContext();
279
280 // There is no way to qualify a name declared in a function or method.
281 if (HiddenCtx->isFunctionOrMethod())
282 return false;
283
Douglas Gregor86d9a522009-09-21 16:56:56 +0000284 return HiddenCtx != Visible->getDeclContext()->getLookupContext();
285}
286
Douglas Gregor456c4a12009-09-21 20:12:40 +0000287/// \brief Compute the qualification required to get from the current context
288/// (\p CurContext) to the target context (\p TargetContext).
289///
290/// \param Context the AST context in which the qualification will be used.
291///
292/// \param CurContext the context where an entity is being named, which is
293/// typically based on the current scope.
294///
295/// \param TargetContext the context in which the named entity actually
296/// resides.
297///
298/// \returns a nested name specifier that refers into the target context, or
299/// NULL if no qualification is needed.
300static NestedNameSpecifier *
301getRequiredQualification(ASTContext &Context,
302 DeclContext *CurContext,
303 DeclContext *TargetContext) {
304 llvm::SmallVector<DeclContext *, 4> TargetParents;
305
306 for (DeclContext *CommonAncestor = TargetContext;
307 CommonAncestor && !CommonAncestor->Encloses(CurContext);
308 CommonAncestor = CommonAncestor->getLookupParent()) {
309 if (CommonAncestor->isTransparentContext() ||
310 CommonAncestor->isFunctionOrMethod())
311 continue;
312
313 TargetParents.push_back(CommonAncestor);
314 }
315
316 NestedNameSpecifier *Result = 0;
317 while (!TargetParents.empty()) {
318 DeclContext *Parent = TargetParents.back();
319 TargetParents.pop_back();
320
321 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
322 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
323 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
324 Result = NestedNameSpecifier::Create(Context, Result,
325 false,
326 Context.getTypeDeclType(TD).getTypePtr());
327 else
328 assert(Parent->isTranslationUnit());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000329 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000330 return Result;
331}
332
333void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
Douglas Gregor8e0a0e42009-09-22 23:31:26 +0000334 assert(!ShadowMaps.empty() && "Must enter into a results scope");
335
Douglas Gregor86d9a522009-09-21 16:56:56 +0000336 if (R.Kind != Result::RK_Declaration) {
337 // For non-declaration results, just add the result.
338 Results.push_back(R);
339 return;
340 }
Douglas Gregorf52cede2009-10-09 22:16:47 +0000341
342 // Skip unnamed entities.
343 if (!R.Declaration->getDeclName())
344 return;
345
Douglas Gregor86d9a522009-09-21 16:56:56 +0000346 // Look through using declarations.
John McCall9488ea12009-11-17 05:59:44 +0000347 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration))
Douglas Gregor0563c262009-09-22 23:15:58 +0000348 MaybeAddResult(Result(Using->getTargetDecl(), R.Rank, R.Qualifier),
349 CurContext);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000350
Douglas Gregor86d9a522009-09-21 16:56:56 +0000351 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
352 unsigned IDNS = CanonDecl->getIdentifierNamespace();
353
354 // Friend declarations and declarations introduced due to friends are never
355 // added as results.
356 if (isa<FriendDecl>(CanonDecl) ||
357 (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend)))
358 return;
Douglas Gregore29ffaa2009-12-11 16:18:54 +0000359
Douglas Gregor76282942009-12-11 17:31:05 +0000360 // Class template (partial) specializations are never added as results.
Douglas Gregore29ffaa2009-12-11 16:18:54 +0000361 if (isa<ClassTemplateSpecializationDecl>(CanonDecl) ||
362 isa<ClassTemplatePartialSpecializationDecl>(CanonDecl))
363 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000364
Douglas Gregor76282942009-12-11 17:31:05 +0000365 // Using declarations themselves are never added as results.
366 if (isa<UsingDecl>(CanonDecl))
367 return;
368
Douglas Gregor86d9a522009-09-21 16:56:56 +0000369 if (const IdentifierInfo *Id = R.Declaration->getIdentifier()) {
370 // __va_list_tag is a freak of nature. Find it and skip it.
371 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
372 return;
373
Douglas Gregorf52cede2009-10-09 22:16:47 +0000374 // Filter out names reserved for the implementation (C99 7.1.3,
375 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbare013d682009-10-18 20:26:12 +0000376 //
377 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000378 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000379 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000380 if (Name[0] == '_' &&
381 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
382 return;
383 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000384 }
385
386 // C++ constructors are never found by name lookup.
387 if (isa<CXXConstructorDecl>(CanonDecl))
388 return;
389
390 // Filter out any unwanted results.
391 if (Filter && !(this->*Filter)(R.Declaration))
392 return;
393
394 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000395 ShadowMapEntry::iterator I, IEnd;
396 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
397 if (NamePos != SMap.end()) {
398 I = NamePos->second.begin();
399 IEnd = NamePos->second.end();
400 }
401
402 for (; I != IEnd; ++I) {
403 NamedDecl *ND = I->first;
404 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000405 if (ND->getCanonicalDecl() == CanonDecl) {
406 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000407 Results[Index].Declaration = R.Declaration;
408
409 // Pick the best rank of the two.
410 Results[Index].Rank = std::min(Results[Index].Rank, R.Rank);
411
412 // We're done.
413 return;
414 }
415 }
416
417 // This is a new declaration in this scope. However, check whether this
418 // declaration name is hidden by a similarly-named declaration in an outer
419 // scope.
420 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
421 --SMEnd;
422 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000423 ShadowMapEntry::iterator I, IEnd;
424 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
425 if (NamePos != SM->end()) {
426 I = NamePos->second.begin();
427 IEnd = NamePos->second.end();
428 }
429 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000430 // A tag declaration does not hide a non-tag declaration.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000431 if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000432 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
433 Decl::IDNS_ObjCProtocol)))
434 continue;
435
436 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000437 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000438 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000439 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000440 continue;
441
442 // The newly-added result is hidden by an entry in the shadow map.
443 if (canHiddenResultBeFound(SemaRef.getLangOptions(), R.Declaration,
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000444 I->first)) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000445 // Note that this result was hidden.
446 R.Hidden = true;
Douglas Gregor0563c262009-09-22 23:15:58 +0000447 R.QualifierIsInformative = false;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000448
449 if (!R.Qualifier)
450 R.Qualifier = getRequiredQualification(SemaRef.Context,
451 CurContext,
452 R.Declaration->getDeclContext());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000453 } else {
454 // This result was hidden and cannot be found; don't bother adding
455 // it.
456 return;
457 }
458
459 break;
460 }
461 }
462
463 // Make sure that any given declaration only shows up in the result set once.
464 if (!AllDeclsFound.insert(CanonDecl))
465 return;
466
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000467 // If the filter is for nested-name-specifiers, then this result starts a
468 // nested-name-specifier.
469 if ((Filter == &ResultBuilder::IsNestedNameSpecifier) ||
470 (Filter == &ResultBuilder::IsMember &&
471 isa<CXXRecordDecl>(R.Declaration) &&
472 cast<CXXRecordDecl>(R.Declaration)->isInjectedClassName()))
473 R.StartsNestedNameSpecifier = true;
474
Douglas Gregor0563c262009-09-22 23:15:58 +0000475 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000476 if (R.QualifierIsInformative && !R.Qualifier &&
477 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000478 DeclContext *Ctx = R.Declaration->getDeclContext();
479 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
480 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
481 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
482 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
483 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
484 else
485 R.QualifierIsInformative = false;
486 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000487
Douglas Gregor86d9a522009-09-21 16:56:56 +0000488 // Insert this result into the set of results and into the current shadow
489 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000490 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000491 Results.push_back(R);
492}
493
494/// \brief Enter into a new scope.
495void ResultBuilder::EnterNewScope() {
496 ShadowMaps.push_back(ShadowMap());
497}
498
499/// \brief Exit from the current scope.
500void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000501 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
502 EEnd = ShadowMaps.back().end();
503 E != EEnd;
504 ++E)
505 E->second.Destroy();
506
Douglas Gregor86d9a522009-09-21 16:56:56 +0000507 ShadowMaps.pop_back();
508}
509
Douglas Gregor791215b2009-09-21 20:51:25 +0000510/// \brief Determines whether this given declaration will be found by
511/// ordinary name lookup.
512bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
513 unsigned IDNS = Decl::IDNS_Ordinary;
514 if (SemaRef.getLangOptions().CPlusPlus)
515 IDNS |= Decl::IDNS_Tag;
516
517 return ND->getIdentifierNamespace() & IDNS;
518}
519
Douglas Gregor86d9a522009-09-21 16:56:56 +0000520/// \brief Determines whether the given declaration is suitable as the
521/// start of a C++ nested-name-specifier, e.g., a class or namespace.
522bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
523 // Allow us to find class templates, too.
524 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
525 ND = ClassTemplate->getTemplatedDecl();
526
527 return SemaRef.isAcceptableNestedNameSpecifier(ND);
528}
529
530/// \brief Determines whether the given declaration is an enumeration.
531bool ResultBuilder::IsEnum(NamedDecl *ND) const {
532 return isa<EnumDecl>(ND);
533}
534
535/// \brief Determines whether the given declaration is a class or struct.
536bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
537 // Allow us to find class templates, too.
538 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
539 ND = ClassTemplate->getTemplatedDecl();
540
541 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
542 return RD->getTagKind() == TagDecl::TK_class ||
543 RD->getTagKind() == TagDecl::TK_struct;
544
545 return false;
546}
547
548/// \brief Determines whether the given declaration is a union.
549bool ResultBuilder::IsUnion(NamedDecl *ND) const {
550 // Allow us to find class templates, too.
551 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
552 ND = ClassTemplate->getTemplatedDecl();
553
554 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
555 return RD->getTagKind() == TagDecl::TK_union;
556
557 return false;
558}
559
560/// \brief Determines whether the given declaration is a namespace.
561bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
562 return isa<NamespaceDecl>(ND);
563}
564
565/// \brief Determines whether the given declaration is a namespace or
566/// namespace alias.
567bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
568 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
569}
570
Douglas Gregor76282942009-12-11 17:31:05 +0000571/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000572bool ResultBuilder::IsType(NamedDecl *ND) const {
573 return isa<TypeDecl>(ND);
574}
575
Douglas Gregor76282942009-12-11 17:31:05 +0000576/// \brief Determines which members of a class should be visible via
577/// "." or "->". Only value declarations, nested name specifiers, and
578/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000579bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000580 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
581 ND = Using->getTargetDecl();
582
Douglas Gregorce821962009-12-11 18:14:22 +0000583 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
584 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000585}
586
Douglas Gregor86d9a522009-09-21 16:56:56 +0000587// Find the next outer declaration context corresponding to this scope.
588static DeclContext *findOuterContext(Scope *S) {
589 for (S = S->getParent(); S; S = S->getParent())
590 if (S->getEntity())
591 return static_cast<DeclContext *>(S->getEntity())->getPrimaryContext();
592
593 return 0;
594}
595
596/// \brief Collect the results of searching for members within the given
597/// declaration context.
598///
599/// \param Ctx the declaration context from which we will gather results.
600///
Douglas Gregor0563c262009-09-22 23:15:58 +0000601/// \param Rank the rank given to results in this declaration context.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000602///
603/// \param Visited the set of declaration contexts that have already been
604/// visited. Declaration contexts will only be visited once.
605///
606/// \param Results the result set that will be extended with any results
607/// found within this declaration context (and, for a C++ class, its bases).
608///
Douglas Gregor0563c262009-09-22 23:15:58 +0000609/// \param InBaseClass whether we are in a base class.
610///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000611/// \returns the next higher rank value, after considering all of the
612/// names within this declaration context.
613static unsigned CollectMemberLookupResults(DeclContext *Ctx,
Douglas Gregor0563c262009-09-22 23:15:58 +0000614 unsigned Rank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000615 DeclContext *CurContext,
616 llvm::SmallPtrSet<DeclContext *, 16> &Visited,
Douglas Gregor0563c262009-09-22 23:15:58 +0000617 ResultBuilder &Results,
618 bool InBaseClass = false) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000619 // Make sure we don't visit the same context twice.
620 if (!Visited.insert(Ctx->getPrimaryContext()))
Douglas Gregor0563c262009-09-22 23:15:58 +0000621 return Rank;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000622
623 // Enumerate all of the results in this context.
Douglas Gregor0563c262009-09-22 23:15:58 +0000624 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000625 Results.EnterNewScope();
626 for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
627 CurCtx = CurCtx->getNextContext()) {
628 for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000629 DEnd = CurCtx->decls_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000630 D != DEnd; ++D) {
631 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
Douglas Gregor0563c262009-09-22 23:15:58 +0000632 Results.MaybeAddResult(Result(ND, Rank, 0, InBaseClass), CurContext);
Douglas Gregorff4393c2009-11-09 21:35:27 +0000633
634 // Visit transparent contexts inside this context.
635 if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
636 if (InnerCtx->isTransparentContext())
637 CollectMemberLookupResults(InnerCtx, Rank, CurContext, Visited,
638 Results, InBaseClass);
639 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000640 }
641 }
642
643 // Traverse the contexts of inherited classes.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000644 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
645 for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000646 BEnd = Record->bases_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000647 B != BEnd; ++B) {
648 QualType BaseType = B->getType();
649
650 // Don't look into dependent bases, because name lookup can't look
651 // there anyway.
652 if (BaseType->isDependentType())
653 continue;
654
655 const RecordType *Record = BaseType->getAs<RecordType>();
656 if (!Record)
657 continue;
658
659 // FIXME: It would be nice to be able to determine whether referencing
660 // a particular member would be ambiguous. For example, given
661 //
662 // struct A { int member; };
663 // struct B { int member; };
664 // struct C : A, B { };
665 //
666 // void f(C *c) { c->### }
667 // accessing 'member' would result in an ambiguity. However, code
668 // completion could be smart enough to qualify the member with the
669 // base class, e.g.,
670 //
671 // c->B::member
672 //
673 // or
674 //
675 // c->A::member
676
677 // Collect results from this base class (and its bases).
Douglas Gregor0563c262009-09-22 23:15:58 +0000678 CollectMemberLookupResults(Record->getDecl(), Rank, CurContext, Visited,
679 Results, /*InBaseClass=*/true);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000680 }
681 }
682
683 // FIXME: Look into base classes in Objective-C!
684
685 Results.ExitScope();
Douglas Gregor0563c262009-09-22 23:15:58 +0000686 return Rank + 1;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000687}
688
689/// \brief Collect the results of searching for members within the given
690/// declaration context.
691///
692/// \param Ctx the declaration context from which we will gather results.
693///
694/// \param InitialRank the initial rank given to results in this declaration
695/// context. Larger rank values will be used for, e.g., members found in
696/// base classes.
697///
698/// \param Results the result set that will be extended with any results
699/// found within this declaration context (and, for a C++ class, its bases).
700///
701/// \returns the next higher rank value, after considering all of the
702/// names within this declaration context.
703static unsigned CollectMemberLookupResults(DeclContext *Ctx,
704 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000705 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000706 ResultBuilder &Results) {
707 llvm::SmallPtrSet<DeclContext *, 16> Visited;
Douglas Gregor456c4a12009-09-21 20:12:40 +0000708 return CollectMemberLookupResults(Ctx, InitialRank, CurContext, Visited,
709 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000710}
711
712/// \brief Collect the results of searching for declarations within the given
713/// scope and its parent scopes.
714///
715/// \param S the scope in which we will start looking for declarations.
716///
717/// \param InitialRank the initial rank given to results in this scope.
718/// Larger rank values will be used for results found in parent scopes.
719///
Douglas Gregor456c4a12009-09-21 20:12:40 +0000720/// \param CurContext the context from which lookup results will be found.
721///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000722/// \param Results the builder object that will receive each result.
723static unsigned CollectLookupResults(Scope *S,
724 TranslationUnitDecl *TranslationUnit,
725 unsigned InitialRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000726 DeclContext *CurContext,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000727 ResultBuilder &Results) {
728 if (!S)
729 return InitialRank;
730
731 // FIXME: Using directives!
732
733 unsigned NextRank = InitialRank;
734 Results.EnterNewScope();
735 if (S->getEntity() &&
736 !((DeclContext *)S->getEntity())->isFunctionOrMethod()) {
737 // Look into this scope's declaration context, along with any of its
738 // parent lookup contexts (e.g., enclosing classes), up to the point
739 // where we hit the context stored in the next outer scope.
740 DeclContext *Ctx = (DeclContext *)S->getEntity();
741 DeclContext *OuterCtx = findOuterContext(S);
742
743 for (; Ctx && Ctx->getPrimaryContext() != OuterCtx;
744 Ctx = Ctx->getLookupParent()) {
745 if (Ctx->isFunctionOrMethod())
746 continue;
747
Douglas Gregor456c4a12009-09-21 20:12:40 +0000748 NextRank = CollectMemberLookupResults(Ctx, NextRank + 1, CurContext,
749 Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000750 }
751 } else if (!S->getParent()) {
752 // Look into the translation unit scope. We walk through the translation
753 // unit's declaration context, because the Scope itself won't have all of
754 // the declarations if we loaded a precompiled header.
755 // FIXME: We would like the translation unit's Scope object to point to the
756 // translation unit, so we don't need this special "if" branch. However,
757 // doing so would force the normal C++ name-lookup code to look into the
758 // translation unit decl when the IdentifierInfo chains would suffice.
759 // Once we fix that problem (which is part of a more general "don't look
760 // in DeclContexts unless we have to" optimization), we can eliminate the
761 // TranslationUnit parameter entirely.
762 NextRank = CollectMemberLookupResults(TranslationUnit, NextRank + 1,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000763 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000764 } else {
765 // Walk through the declarations in this Scope.
766 for (Scope::decl_iterator D = S->decl_begin(), DEnd = S->decl_end();
767 D != DEnd; ++D) {
768 if (NamedDecl *ND = dyn_cast<NamedDecl>((Decl *)((*D).get())))
Douglas Gregor456c4a12009-09-21 20:12:40 +0000769 Results.MaybeAddResult(CodeCompleteConsumer::Result(ND, NextRank),
770 CurContext);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000771 }
772
773 NextRank = NextRank + 1;
774 }
775
776 // Lookup names in the parent scope.
777 NextRank = CollectLookupResults(S->getParent(), TranslationUnit, NextRank,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000778 CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000779 Results.ExitScope();
780
781 return NextRank;
782}
783
784/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregor9a0c85e2009-12-07 09:51:25 +0000785static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000786 ResultBuilder &Results) {
787 typedef CodeCompleteConsumer::Result Result;
788 Results.MaybeAddResult(Result("short", Rank));
789 Results.MaybeAddResult(Result("long", Rank));
790 Results.MaybeAddResult(Result("signed", Rank));
791 Results.MaybeAddResult(Result("unsigned", Rank));
792 Results.MaybeAddResult(Result("void", Rank));
793 Results.MaybeAddResult(Result("char", Rank));
794 Results.MaybeAddResult(Result("int", Rank));
795 Results.MaybeAddResult(Result("float", Rank));
796 Results.MaybeAddResult(Result("double", Rank));
797 Results.MaybeAddResult(Result("enum", Rank));
798 Results.MaybeAddResult(Result("struct", Rank));
799 Results.MaybeAddResult(Result("union", Rank));
800
801 if (LangOpts.C99) {
802 // C99-specific
803 Results.MaybeAddResult(Result("_Complex", Rank));
804 Results.MaybeAddResult(Result("_Imaginary", Rank));
805 Results.MaybeAddResult(Result("_Bool", Rank));
806 }
807
808 if (LangOpts.CPlusPlus) {
809 // C++-specific
810 Results.MaybeAddResult(Result("bool", Rank));
811 Results.MaybeAddResult(Result("class", Rank));
812 Results.MaybeAddResult(Result("typename", Rank));
813 Results.MaybeAddResult(Result("wchar_t", Rank));
814
815 if (LangOpts.CPlusPlus0x) {
816 Results.MaybeAddResult(Result("char16_t", Rank));
817 Results.MaybeAddResult(Result("char32_t", Rank));
818 Results.MaybeAddResult(Result("decltype", Rank));
819 }
820 }
821
822 // GNU extensions
823 if (LangOpts.GNUMode) {
824 // FIXME: Enable when we actually support decimal floating point.
825 // Results.MaybeAddResult(Result("_Decimal32", Rank));
826 // Results.MaybeAddResult(Result("_Decimal64", Rank));
827 // Results.MaybeAddResult(Result("_Decimal128", Rank));
828 Results.MaybeAddResult(Result("typeof", Rank));
829 }
830}
831
Douglas Gregorff5ce6e2009-12-18 18:53:37 +0000832/// \brief If the given declaration has an associated type, add it as a result
833/// type chunk.
834static void AddResultTypeChunk(ASTContext &Context,
835 NamedDecl *ND,
836 CodeCompletionString *Result) {
837 if (!ND)
838 return;
839
840 // Determine the type of the declaration (if it has a type).
841 QualType T;
842 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
843 T = Function->getResultType();
844 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
845 T = Method->getResultType();
846 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
847 T = FunTmpl->getTemplatedDecl()->getResultType();
848 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
849 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
850 else if (isa<UnresolvedUsingValueDecl>(ND)) {
851 /* Do nothing: ignore unresolved using declarations*/
852 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
853 T = Value->getType();
854 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
855 T = Property->getType();
856
857 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
858 return;
859
860 std::string TypeStr;
861 T.getAsStringInternal(TypeStr, Context.PrintingPolicy);
862 Result->AddResultTypeChunk(TypeStr);
863}
864
Douglas Gregor86d9a522009-09-21 16:56:56 +0000865/// \brief Add function parameter chunks to the given code completion string.
866static void AddFunctionParameterChunks(ASTContext &Context,
867 FunctionDecl *Function,
868 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000869 typedef CodeCompletionString::Chunk Chunk;
870
Douglas Gregor86d9a522009-09-21 16:56:56 +0000871 CodeCompletionString *CCStr = Result;
872
873 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
874 ParmVarDecl *Param = Function->getParamDecl(P);
875
876 if (Param->hasDefaultArg()) {
877 // When we see an optional default argument, put that argument and
878 // the remaining default arguments into a new, optional string.
879 CodeCompletionString *Opt = new CodeCompletionString;
880 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
881 CCStr = Opt;
882 }
883
884 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000885 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000886
887 // Format the placeholder string.
888 std::string PlaceholderStr;
889 if (Param->getIdentifier())
890 PlaceholderStr = Param->getIdentifier()->getName();
891
892 Param->getType().getAsStringInternal(PlaceholderStr,
893 Context.PrintingPolicy);
894
895 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +0000896 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000897 }
Douglas Gregorb3d45252009-09-22 21:42:17 +0000898
899 if (const FunctionProtoType *Proto
900 = Function->getType()->getAs<FunctionProtoType>())
901 if (Proto->isVariadic())
902 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +0000903}
904
905/// \brief Add template parameter chunks to the given code completion string.
906static void AddTemplateParameterChunks(ASTContext &Context,
907 TemplateDecl *Template,
908 CodeCompletionString *Result,
909 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000910 typedef CodeCompletionString::Chunk Chunk;
911
Douglas Gregor86d9a522009-09-21 16:56:56 +0000912 CodeCompletionString *CCStr = Result;
913 bool FirstParameter = true;
914
915 TemplateParameterList *Params = Template->getTemplateParameters();
916 TemplateParameterList::iterator PEnd = Params->end();
917 if (MaxParameters)
918 PEnd = Params->begin() + MaxParameters;
919 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
920 bool HasDefaultArg = false;
921 std::string PlaceholderStr;
922 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
923 if (TTP->wasDeclaredWithTypename())
924 PlaceholderStr = "typename";
925 else
926 PlaceholderStr = "class";
927
928 if (TTP->getIdentifier()) {
929 PlaceholderStr += ' ';
930 PlaceholderStr += TTP->getIdentifier()->getName();
931 }
932
933 HasDefaultArg = TTP->hasDefaultArgument();
934 } else if (NonTypeTemplateParmDecl *NTTP
935 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
936 if (NTTP->getIdentifier())
937 PlaceholderStr = NTTP->getIdentifier()->getName();
938 NTTP->getType().getAsStringInternal(PlaceholderStr,
939 Context.PrintingPolicy);
940 HasDefaultArg = NTTP->hasDefaultArgument();
941 } else {
942 assert(isa<TemplateTemplateParmDecl>(*P));
943 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
944
945 // Since putting the template argument list into the placeholder would
946 // be very, very long, we just use an abbreviation.
947 PlaceholderStr = "template<...> class";
948 if (TTP->getIdentifier()) {
949 PlaceholderStr += ' ';
950 PlaceholderStr += TTP->getIdentifier()->getName();
951 }
952
953 HasDefaultArg = TTP->hasDefaultArgument();
954 }
955
956 if (HasDefaultArg) {
957 // When we see an optional default argument, put that argument and
958 // the remaining default arguments into a new, optional string.
959 CodeCompletionString *Opt = new CodeCompletionString;
960 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
961 CCStr = Opt;
962 }
963
964 if (FirstParameter)
965 FirstParameter = false;
966 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000967 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000968
969 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +0000970 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000971 }
972}
973
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000974/// \brief Add a qualifier to the given code-completion string, if the
975/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +0000976static void
977AddQualifierToCompletionString(CodeCompletionString *Result,
978 NestedNameSpecifier *Qualifier,
979 bool QualifierIsInformative,
980 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000981 if (!Qualifier)
982 return;
983
984 std::string PrintedNNS;
985 {
986 llvm::raw_string_ostream OS(PrintedNNS);
987 Qualifier->print(OS, Context.PrintingPolicy);
988 }
Douglas Gregor0563c262009-09-22 23:15:58 +0000989 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +0000990 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +0000991 else
Benjamin Kramer660cc182009-11-29 20:18:50 +0000992 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +0000993}
994
Douglas Gregora61a8792009-12-11 18:44:16 +0000995static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
996 FunctionDecl *Function) {
997 const FunctionProtoType *Proto
998 = Function->getType()->getAs<FunctionProtoType>();
999 if (!Proto || !Proto->getTypeQuals())
1000 return;
1001
1002 std::string QualsStr;
1003 if (Proto->getTypeQuals() & Qualifiers::Const)
1004 QualsStr += " const";
1005 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1006 QualsStr += " volatile";
1007 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1008 QualsStr += " restrict";
1009 Result->AddInformativeChunk(QualsStr);
1010}
1011
Douglas Gregor86d9a522009-09-21 16:56:56 +00001012/// \brief If possible, create a new code completion string for the given
1013/// result.
1014///
1015/// \returns Either a new, heap-allocated code completion string describing
1016/// how to use this result, or NULL to indicate that the string or name of the
1017/// result is all that is needed.
1018CodeCompletionString *
1019CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001020 typedef CodeCompletionString::Chunk Chunk;
1021
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001022 if (Kind == RK_Pattern)
1023 return Pattern->Clone();
1024
1025 CodeCompletionString *Result = new CodeCompletionString;
1026
1027 if (Kind == RK_Keyword) {
1028 Result->AddTypedTextChunk(Keyword);
1029 return Result;
1030 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001031
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001032 if (Kind == RK_Macro) {
1033 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001034 assert(MI && "Not a macro?");
1035
1036 Result->AddTypedTextChunk(Macro->getName());
1037
1038 if (!MI->isFunctionLike())
1039 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001040
1041 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001042 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001043 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1044 A != AEnd; ++A) {
1045 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001046 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001047
1048 if (!MI->isVariadic() || A != AEnd - 1) {
1049 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001050 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001051 continue;
1052 }
1053
1054 // Variadic argument; cope with the different between GNU and C99
1055 // variadic macros, providing a single placeholder for the rest of the
1056 // arguments.
1057 if ((*A)->isStr("__VA_ARGS__"))
1058 Result->AddPlaceholderChunk("...");
1059 else {
1060 std::string Arg = (*A)->getName();
1061 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001062 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001063 }
1064 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001065 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001066 return Result;
1067 }
1068
1069 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001070 NamedDecl *ND = Declaration;
1071
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001072 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001073 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001074 Result->AddTextChunk("::");
1075 return Result;
1076 }
1077
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001078 AddResultTypeChunk(S.Context, ND, Result);
1079
Douglas Gregor86d9a522009-09-21 16:56:56 +00001080 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001081 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1082 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001083 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001084 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001085 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001086 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001087 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001088 return Result;
1089 }
1090
1091 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001092 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1093 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001094 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001095 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001096
1097 // Figure out which template parameters are deduced (or have default
1098 // arguments).
1099 llvm::SmallVector<bool, 16> Deduced;
1100 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1101 unsigned LastDeducibleArgument;
1102 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1103 --LastDeducibleArgument) {
1104 if (!Deduced[LastDeducibleArgument - 1]) {
1105 // C++0x: Figure out if the template argument has a default. If so,
1106 // the user doesn't need to type this argument.
1107 // FIXME: We need to abstract template parameters better!
1108 bool HasDefaultArg = false;
1109 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1110 LastDeducibleArgument - 1);
1111 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1112 HasDefaultArg = TTP->hasDefaultArgument();
1113 else if (NonTypeTemplateParmDecl *NTTP
1114 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1115 HasDefaultArg = NTTP->hasDefaultArgument();
1116 else {
1117 assert(isa<TemplateTemplateParmDecl>(Param));
1118 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001119 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001120 }
1121
1122 if (!HasDefaultArg)
1123 break;
1124 }
1125 }
1126
1127 if (LastDeducibleArgument) {
1128 // Some of the function template arguments cannot be deduced from a
1129 // function call, so we introduce an explicit template argument list
1130 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001131 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001132 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1133 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001134 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001135 }
1136
1137 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001138 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001139 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001140 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001141 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001142 return Result;
1143 }
1144
1145 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001146 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1147 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001148 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001149 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001150 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001151 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001152 return Result;
1153 }
1154
Douglas Gregor9630eb62009-11-17 16:44:22 +00001155 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001156 Selector Sel = Method->getSelector();
1157 if (Sel.isUnarySelector()) {
1158 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1159 return Result;
1160 }
1161
Douglas Gregord3c68542009-11-19 01:08:35 +00001162 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1163 SelName += ':';
1164 if (StartParameter == 0)
1165 Result->AddTypedTextChunk(SelName);
1166 else {
1167 Result->AddInformativeChunk(SelName);
1168
1169 // If there is only one parameter, and we're past it, add an empty
1170 // typed-text chunk since there is nothing to type.
1171 if (Method->param_size() == 1)
1172 Result->AddTypedTextChunk("");
1173 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001174 unsigned Idx = 0;
1175 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1176 PEnd = Method->param_end();
1177 P != PEnd; (void)++P, ++Idx) {
1178 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001179 std::string Keyword;
1180 if (Idx > StartParameter)
1181 Keyword = " ";
Douglas Gregor9630eb62009-11-17 16:44:22 +00001182 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1183 Keyword += II->getName().str();
1184 Keyword += ":";
Douglas Gregor4ad96852009-11-19 07:41:15 +00001185 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001186 Result->AddInformativeChunk(Keyword);
1187 } else if (Idx == StartParameter)
1188 Result->AddTypedTextChunk(Keyword);
1189 else
1190 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001191 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001192
1193 // If we're before the starting parameter, skip the placeholder.
1194 if (Idx < StartParameter)
1195 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001196
1197 std::string Arg;
1198 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1199 Arg = "(" + Arg + ")";
1200 if (IdentifierInfo *II = (*P)->getIdentifier())
1201 Arg += II->getName().str();
Douglas Gregor4ad96852009-11-19 07:41:15 +00001202 if (AllParametersAreInformative)
1203 Result->AddInformativeChunk(Arg);
1204 else
1205 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001206 }
1207
Douglas Gregor2a17af02009-12-23 00:21:46 +00001208 if (Method->isVariadic()) {
1209 if (AllParametersAreInformative)
1210 Result->AddInformativeChunk(", ...");
1211 else
1212 Result->AddPlaceholderChunk(", ...");
1213 }
1214
Douglas Gregor9630eb62009-11-17 16:44:22 +00001215 return Result;
1216 }
1217
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001218 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00001219 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1220 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001221
1222 Result->AddTypedTextChunk(ND->getNameAsString());
1223 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001224}
1225
Douglas Gregor86d802e2009-09-23 00:34:09 +00001226CodeCompletionString *
1227CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1228 unsigned CurrentArg,
1229 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001230 typedef CodeCompletionString::Chunk Chunk;
1231
Douglas Gregor86d802e2009-09-23 00:34:09 +00001232 CodeCompletionString *Result = new CodeCompletionString;
1233 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001234 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001235 const FunctionProtoType *Proto
1236 = dyn_cast<FunctionProtoType>(getFunctionType());
1237 if (!FDecl && !Proto) {
1238 // Function without a prototype. Just give the return type and a
1239 // highlighted ellipsis.
1240 const FunctionType *FT = getFunctionType();
1241 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001242 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001243 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1244 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1245 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001246 return Result;
1247 }
1248
1249 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001250 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00001251 else
1252 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001253 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001254
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001255 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001256 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1257 for (unsigned I = 0; I != NumParams; ++I) {
1258 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001259 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001260
1261 std::string ArgString;
1262 QualType ArgType;
1263
1264 if (FDecl) {
1265 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1266 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1267 } else {
1268 ArgType = Proto->getArgType(I);
1269 }
1270
1271 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1272
1273 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001274 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00001275 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001276 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001277 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001278 }
1279
1280 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001281 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001282 if (CurrentArg < NumParams)
1283 Result->AddTextChunk("...");
1284 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001285 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001286 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001287 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001288
1289 return Result;
1290}
1291
Douglas Gregor86d9a522009-09-21 16:56:56 +00001292namespace {
1293 struct SortCodeCompleteResult {
1294 typedef CodeCompleteConsumer::Result Result;
1295
Douglas Gregor6a684032009-09-28 03:51:44 +00001296 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001297 Selector XSel = X.getObjCSelector();
1298 Selector YSel = Y.getObjCSelector();
1299 if (!XSel.isNull() && !YSel.isNull()) {
1300 // We are comparing two selectors.
1301 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1302 if (N == 0)
1303 ++N;
1304 for (unsigned I = 0; I != N; ++I) {
1305 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1306 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1307 if (!XId || !YId)
1308 return XId && !YId;
1309
1310 switch (XId->getName().compare_lower(YId->getName())) {
1311 case -1: return true;
1312 case 1: return false;
1313 default: break;
1314 }
1315 }
1316
1317 return XSel.getNumArgs() < YSel.getNumArgs();
1318 }
1319
1320 // For non-selectors, order by kind.
1321 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00001322 return X.getNameKind() < Y.getNameKind();
1323
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001324 // Order identifiers by comparison of their lowercased names.
1325 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1326 return XId->getName().compare_lower(
1327 Y.getAsIdentifierInfo()->getName()) < 0;
1328
1329 // Order overloaded operators by the order in which they appear
1330 // in our list of operators.
1331 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1332 return XOp < Y.getCXXOverloadedOperator();
1333
1334 // Order C++0x user-defined literal operators lexically by their
1335 // lowercased suffixes.
1336 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1337 return XLit->getName().compare_lower(
1338 Y.getCXXLiteralIdentifier()->getName()) < 0;
1339
1340 // The only stable ordering we have is to turn the name into a
1341 // string and then compare the lower-case strings. This is
1342 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00001343 return llvm::StringRef(X.getAsString()).compare_lower(
1344 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00001345 }
1346
Douglas Gregor86d9a522009-09-21 16:56:56 +00001347 bool operator()(const Result &X, const Result &Y) const {
1348 // Sort first by rank.
1349 if (X.Rank < Y.Rank)
1350 return true;
1351 else if (X.Rank > Y.Rank)
1352 return false;
1353
Douglas Gregor54f01612009-11-19 00:01:57 +00001354 // We use a special ordering for keywords and patterns, based on the
1355 // typed text.
1356 if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
1357 (Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
1358 const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword
1359 : X.Pattern->getTypedText();
1360 const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
1361 : Y.Pattern->getTypedText();
Benjamin Kramerf42d4882009-12-05 10:07:04 +00001362 return llvm::StringRef(XStr).compare_lower(YStr) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001363 }
1364
Douglas Gregor86d9a522009-09-21 16:56:56 +00001365 // Result kinds are ordered by decreasing importance.
1366 if (X.Kind < Y.Kind)
1367 return true;
1368 else if (X.Kind > Y.Kind)
1369 return false;
1370
1371 // Non-hidden names precede hidden names.
1372 if (X.Hidden != Y.Hidden)
1373 return !X.Hidden;
1374
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001375 // Non-nested-name-specifiers precede nested-name-specifiers.
1376 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1377 return !X.StartsNestedNameSpecifier;
1378
Douglas Gregor86d9a522009-09-21 16:56:56 +00001379 // Ordering depends on the kind of result.
1380 switch (X.Kind) {
1381 case Result::RK_Declaration:
1382 // Order based on the declaration names.
Douglas Gregor6a684032009-09-28 03:51:44 +00001383 return isEarlierDeclarationName(X.Declaration->getDeclName(),
1384 Y.Declaration->getDeclName());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001385
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001386 case Result::RK_Macro:
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001387 return X.Macro->getName().compare_lower(Y.Macro->getName()) < 0;
Douglas Gregor54f01612009-11-19 00:01:57 +00001388
1389 case Result::RK_Keyword:
1390 case Result::RK_Pattern:
Jeffrey Yasskin9f61aa92009-12-12 05:05:38 +00001391 llvm_unreachable("Result kinds handled above");
Douglas Gregor54f01612009-11-19 00:01:57 +00001392 break;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001393 }
1394
1395 // Silence GCC warning.
1396 return false;
1397 }
1398 };
1399}
1400
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001401static void AddMacroResults(Preprocessor &PP, unsigned Rank,
1402 ResultBuilder &Results) {
1403 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001404 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1405 MEnd = PP.macro_end();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001406 M != MEnd; ++M)
1407 Results.MaybeAddResult(CodeCompleteConsumer::Result(M->first, Rank));
1408 Results.ExitScope();
1409}
1410
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001411static void HandleCodeCompleteResults(Sema *S,
1412 CodeCompleteConsumer *CodeCompleter,
1413 CodeCompleteConsumer::Result *Results,
1414 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001415 // Sort the results by rank/kind/etc.
1416 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1417
1418 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001419 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00001420
1421 for (unsigned I = 0; I != NumResults; ++I)
1422 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001423}
1424
Douglas Gregor791215b2009-09-21 20:51:25 +00001425void Sema::CodeCompleteOrdinaryName(Scope *S) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001426 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor791215b2009-09-21 20:51:25 +00001427 ResultBuilder Results(*this, &ResultBuilder::IsOrdinaryName);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001428 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1429 0, CurContext, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001430
1431 Results.EnterNewScope();
1432 AddTypeSpecifierResults(getLangOptions(), NextRank, Results);
1433
1434 if (getLangOptions().ObjC1) {
1435 // Add the "super" keyword, if appropriate.
1436 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
1437 if (Method->getClassInterface()->getSuperClass())
1438 Results.MaybeAddResult(Result("super", NextRank));
1439 }
1440
1441 Results.ExitScope();
1442
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001443 if (CodeCompleter->includeMacros())
1444 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001445 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00001446}
1447
Douglas Gregor95ac6552009-11-18 01:29:26 +00001448static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00001449 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00001450 DeclContext *CurContext,
1451 ResultBuilder &Results) {
1452 typedef CodeCompleteConsumer::Result Result;
1453
1454 // Add properties in this container.
1455 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1456 PEnd = Container->prop_end();
1457 P != PEnd;
1458 ++P)
1459 Results.MaybeAddResult(Result(*P, 0), CurContext);
1460
1461 // Add properties in referenced protocols.
1462 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1463 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1464 PEnd = Protocol->protocol_end();
1465 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001466 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001467 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00001468 if (AllowCategories) {
1469 // Look through categories.
1470 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1471 Category; Category = Category->getNextClassCategory())
1472 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1473 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001474
1475 // Look through protocols.
1476 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1477 E = IFace->protocol_end();
1478 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001479 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001480
1481 // Look in the superclass.
1482 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00001483 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
1484 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001485 } else if (const ObjCCategoryDecl *Category
1486 = dyn_cast<ObjCCategoryDecl>(Container)) {
1487 // Look through protocols.
1488 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
1489 PEnd = Category->protocol_end();
1490 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001491 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001492 }
1493}
1494
Douglas Gregor81b747b2009-09-17 21:32:03 +00001495void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
1496 SourceLocation OpLoc,
1497 bool IsArrow) {
1498 if (!BaseE || !CodeCompleter)
1499 return;
1500
Douglas Gregor86d9a522009-09-21 16:56:56 +00001501 typedef CodeCompleteConsumer::Result Result;
1502
Douglas Gregor81b747b2009-09-17 21:32:03 +00001503 Expr *Base = static_cast<Expr *>(BaseE);
1504 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001505
1506 if (IsArrow) {
1507 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1508 BaseType = Ptr->getPointeeType();
1509 else if (BaseType->isObjCObjectPointerType())
1510 /*Do nothing*/ ;
1511 else
1512 return;
1513 }
1514
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001515 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001516 unsigned NextRank = 0;
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001517
Douglas Gregor95ac6552009-11-18 01:29:26 +00001518 Results.EnterNewScope();
1519 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
1520 // Access to a C/C++ class, struct, or union.
1521 NextRank = CollectMemberLookupResults(Record->getDecl(), NextRank,
1522 Record->getDecl(), Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001523
Douglas Gregor95ac6552009-11-18 01:29:26 +00001524 if (getLangOptions().CPlusPlus) {
1525 if (!Results.empty()) {
1526 // The "template" keyword can follow "->" or "." in the grammar.
1527 // However, we only want to suggest the template keyword if something
1528 // is dependent.
1529 bool IsDependent = BaseType->isDependentType();
1530 if (!IsDependent) {
1531 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
1532 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
1533 IsDependent = Ctx->isDependentContext();
1534 break;
1535 }
1536 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001537
Douglas Gregor95ac6552009-11-18 01:29:26 +00001538 if (IsDependent)
1539 Results.MaybeAddResult(Result("template", NextRank++));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001540 }
1541
Douglas Gregor95ac6552009-11-18 01:29:26 +00001542 // We could have the start of a nested-name-specifier. Add those
1543 // results as well.
Douglas Gregor76282942009-12-11 17:31:05 +00001544 // FIXME: We should really walk base classes to produce
1545 // nested-name-specifiers so that we produce more-precise results.
Douglas Gregor95ac6552009-11-18 01:29:26 +00001546 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
1547 CollectLookupResults(S, Context.getTranslationUnitDecl(), NextRank,
1548 CurContext, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001549 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001550 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
1551 // Objective-C property reference.
1552
1553 // Add property results based on our interface.
1554 const ObjCObjectPointerType *ObjCPtr
1555 = BaseType->getAsObjCInterfacePointerType();
1556 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00001557 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001558
1559 // Add properties from the protocols in a qualified interface.
1560 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
1561 E = ObjCPtr->qual_end();
1562 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001563 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001564
1565 // FIXME: We could (should?) also look for "implicit" properties, identified
1566 // only by the presence of nullary and unary selectors.
1567 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
1568 (!IsArrow && BaseType->isObjCInterfaceType())) {
1569 // Objective-C instance variable access.
1570 ObjCInterfaceDecl *Class = 0;
1571 if (const ObjCObjectPointerType *ObjCPtr
1572 = BaseType->getAs<ObjCObjectPointerType>())
1573 Class = ObjCPtr->getInterfaceDecl();
1574 else
1575 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
1576
1577 // Add all ivars from this class and its superclasses.
1578 for (; Class; Class = Class->getSuperClass()) {
1579 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
1580 IVarEnd = Class->ivar_end();
1581 IVar != IVarEnd; ++IVar)
1582 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
1583 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001584 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001585
1586 // FIXME: How do we cope with isa?
1587
1588 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001589
1590 // Add macros
1591 if (CodeCompleter->includeMacros())
1592 AddMacroResults(PP, NextRank, Results);
1593
1594 // Hand off the results found for code completion.
1595 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00001596}
1597
Douglas Gregor374929f2009-09-18 15:37:17 +00001598void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
1599 if (!CodeCompleter)
1600 return;
1601
Douglas Gregor86d9a522009-09-21 16:56:56 +00001602 typedef CodeCompleteConsumer::Result Result;
1603 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00001604 switch ((DeclSpec::TST)TagSpec) {
1605 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001606 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00001607 break;
1608
1609 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001610 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00001611 break;
1612
1613 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00001614 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00001615 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00001616 break;
1617
1618 default:
1619 assert(false && "Unknown type specifier kind in CodeCompleteTag");
1620 return;
1621 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001622
1623 ResultBuilder Results(*this, Filter);
1624 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00001625 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001626
1627 if (getLangOptions().CPlusPlus) {
1628 // We could have the start of a nested-name-specifier. Add those
1629 // results as well.
1630 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001631 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1632 NextRank, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001633 }
1634
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001635 if (CodeCompleter->includeMacros())
1636 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001637 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00001638}
1639
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001640void Sema::CodeCompleteCase(Scope *S) {
1641 if (getSwitchStack().empty() || !CodeCompleter)
1642 return;
1643
1644 SwitchStmt *Switch = getSwitchStack().back();
1645 if (!Switch->getCond()->getType()->isEnumeralType())
1646 return;
1647
1648 // Code-complete the cases of a switch statement over an enumeration type
1649 // by providing the list of
1650 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
1651
1652 // Determine which enumerators we have already seen in the switch statement.
1653 // FIXME: Ideally, we would also be able to look *past* the code-completion
1654 // token, in case we are code-completing in the middle of the switch and not
1655 // at the end. However, we aren't able to do so at the moment.
1656 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001657 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001658 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
1659 SC = SC->getNextSwitchCase()) {
1660 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
1661 if (!Case)
1662 continue;
1663
1664 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
1665 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
1666 if (EnumConstantDecl *Enumerator
1667 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
1668 // We look into the AST of the case statement to determine which
1669 // enumerator was named. Alternatively, we could compute the value of
1670 // the integral constant expression, then compare it against the
1671 // values of each enumerator. However, value-based approach would not
1672 // work as well with C++ templates where enumerators declared within a
1673 // template are type- and value-dependent.
1674 EnumeratorsSeen.insert(Enumerator);
1675
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001676 // If this is a qualified-id, keep track of the nested-name-specifier
1677 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001678 //
1679 // switch (TagD.getKind()) {
1680 // case TagDecl::TK_enum:
1681 // break;
1682 // case XXX
1683 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001684 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001685 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
1686 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00001687 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001688 }
1689 }
1690
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001691 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
1692 // If there are no prior enumerators in C++, check whether we have to
1693 // qualify the names of the enumerators that we suggest, because they
1694 // may not be visible in this scope.
1695 Qualifier = getRequiredQualification(Context, CurContext,
1696 Enum->getDeclContext());
1697
1698 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
1699 }
1700
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001701 // Add any enumerators that have not yet been mentioned.
1702 ResultBuilder Results(*this);
1703 Results.EnterNewScope();
1704 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
1705 EEnd = Enum->enumerator_end();
1706 E != EEnd; ++E) {
1707 if (EnumeratorsSeen.count(*E))
1708 continue;
1709
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001710 Results.MaybeAddResult(CodeCompleteConsumer::Result(*E, 0, Qualifier));
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001711 }
1712 Results.ExitScope();
1713
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001714 if (CodeCompleter->includeMacros())
1715 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001716 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00001717}
1718
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001719namespace {
1720 struct IsBetterOverloadCandidate {
1721 Sema &S;
1722
1723 public:
1724 explicit IsBetterOverloadCandidate(Sema &S) : S(S) { }
1725
1726 bool
1727 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
1728 return S.isBetterOverloadCandidate(X, Y);
1729 }
1730 };
1731}
1732
1733void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
1734 ExprTy **ArgsIn, unsigned NumArgs) {
1735 if (!CodeCompleter)
1736 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00001737
1738 // When we're code-completing for a call, we fall back to ordinary
1739 // name code-completion whenever we can't produce specific
1740 // results. We may want to revisit this strategy in the future,
1741 // e.g., by merging the two kinds of results.
1742
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001743 Expr *Fn = (Expr *)FnIn;
1744 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00001745
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001746 // Ignore type-dependent call expressions entirely.
1747 if (Fn->isTypeDependent() ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00001748 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
1749 CodeCompleteOrdinaryName(S);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001750 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00001751 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001752
John McCall3b4294e2009-12-16 12:17:52 +00001753 // Build an overload candidate set based on the functions we find.
1754 OverloadCandidateSet CandidateSet;
1755
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001756 // FIXME: What if we're calling something that isn't a function declaration?
1757 // FIXME: What if we're calling a pseudo-destructor?
1758 // FIXME: What if we're calling a member function?
1759
John McCall3b4294e2009-12-16 12:17:52 +00001760 Expr *NakedFn = Fn->IgnoreParenCasts();
1761 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
1762 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
1763 /*PartialOverloading=*/ true);
1764 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
1765 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
1766 if (FDecl)
1767 AddOverloadCandidate(FDecl, Args, NumArgs, CandidateSet,
1768 false, false, /*PartialOverloading*/ true);
1769 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001770
1771 // Sort the overload candidate set by placing the best overloads first.
1772 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
1773 IsBetterOverloadCandidate(*this));
1774
1775 // Add the remaining viable overload candidates as code-completion reslults.
Douglas Gregor05944382009-09-23 00:16:58 +00001776 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
1777 llvm::SmallVector<ResultCandidate, 8> Results;
Anders Carlsson90756302009-09-22 17:29:51 +00001778
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001779 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
1780 CandEnd = CandidateSet.end();
1781 Cand != CandEnd; ++Cand) {
1782 if (Cand->Viable)
Douglas Gregor05944382009-09-23 00:16:58 +00001783 Results.push_back(ResultCandidate(Cand->Function));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001784 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00001785
1786 if (Results.empty())
1787 CodeCompleteOrdinaryName(S);
1788 else
1789 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
1790 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00001791}
1792
Douglas Gregor81b747b2009-09-17 21:32:03 +00001793void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
1794 bool EnteringContext) {
1795 if (!SS.getScopeRep() || !CodeCompleter)
1796 return;
1797
Douglas Gregor86d9a522009-09-21 16:56:56 +00001798 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
1799 if (!Ctx)
1800 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00001801
1802 // Try to instantiate any non-dependent declaration contexts before
1803 // we look in them.
1804 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
1805 return;
1806
Douglas Gregor86d9a522009-09-21 16:56:56 +00001807 ResultBuilder Results(*this);
Douglas Gregor456c4a12009-09-21 20:12:40 +00001808 unsigned NextRank = CollectMemberLookupResults(Ctx, 0, Ctx, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001809
1810 // The "template" keyword can follow "::" in the grammar, but only
1811 // put it into the grammar if the nested-name-specifier is dependent.
1812 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
1813 if (!Results.empty() && NNS->isDependent())
1814 Results.MaybeAddResult(CodeCompleteConsumer::Result("template", NextRank));
1815
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001816 if (CodeCompleter->includeMacros())
1817 AddMacroResults(PP, NextRank + 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001818 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00001819}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001820
1821void Sema::CodeCompleteUsing(Scope *S) {
1822 if (!CodeCompleter)
1823 return;
1824
Douglas Gregor86d9a522009-09-21 16:56:56 +00001825 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001826 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001827
1828 // If we aren't in class scope, we could see the "namespace" keyword.
1829 if (!S->isClassScope())
1830 Results.MaybeAddResult(CodeCompleteConsumer::Result("namespace", 0));
1831
1832 // After "using", we can see anything that would start a
1833 // nested-name-specifier.
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001834 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1835 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001836 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001837
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001838 if (CodeCompleter->includeMacros())
1839 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001840 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001841}
1842
1843void Sema::CodeCompleteUsingDirective(Scope *S) {
1844 if (!CodeCompleter)
1845 return;
1846
Douglas Gregor86d9a522009-09-21 16:56:56 +00001847 // After "using namespace", we expect to see a namespace name or namespace
1848 // alias.
1849 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001850 Results.EnterNewScope();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001851 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1852 0, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001853 Results.ExitScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001854 if (CodeCompleter->includeMacros())
1855 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001856 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001857}
1858
1859void Sema::CodeCompleteNamespaceDecl(Scope *S) {
1860 if (!CodeCompleter)
1861 return;
1862
Douglas Gregor86d9a522009-09-21 16:56:56 +00001863 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
1864 DeclContext *Ctx = (DeclContext *)S->getEntity();
1865 if (!S->getParent())
1866 Ctx = Context.getTranslationUnitDecl();
1867
1868 if (Ctx && Ctx->isFileContext()) {
1869 // We only want to see those namespaces that have already been defined
1870 // within this scope, because its likely that the user is creating an
1871 // extended namespace declaration. Keep track of the most recent
1872 // definition of each namespace.
1873 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
1874 for (DeclContext::specific_decl_iterator<NamespaceDecl>
1875 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
1876 NS != NSEnd; ++NS)
1877 OrigToLatest[NS->getOriginalNamespace()] = *NS;
1878
1879 // Add the most recent definition (or extended definition) of each
1880 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001881 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001882 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
1883 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
1884 NS != NSEnd; ++NS)
Douglas Gregor456c4a12009-09-21 20:12:40 +00001885 Results.MaybeAddResult(CodeCompleteConsumer::Result(NS->second, 0),
1886 CurContext);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001887 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001888 }
1889
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001890 if (CodeCompleter->includeMacros())
1891 AddMacroResults(PP, 1, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001892 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001893}
1894
1895void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
1896 if (!CodeCompleter)
1897 return;
1898
Douglas Gregor86d9a522009-09-21 16:56:56 +00001899 // After "namespace", we expect to see a namespace or alias.
1900 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001901 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1902 0, CurContext, Results);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001903 if (CodeCompleter->includeMacros())
1904 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001905 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001906}
1907
Douglas Gregored8d3222009-09-18 20:05:18 +00001908void Sema::CodeCompleteOperatorName(Scope *S) {
1909 if (!CodeCompleter)
1910 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001911
1912 typedef CodeCompleteConsumer::Result Result;
1913 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001914 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00001915
Douglas Gregor86d9a522009-09-21 16:56:56 +00001916 // Add the names of overloadable operators.
1917#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1918 if (std::strcmp(Spelling, "?")) \
1919 Results.MaybeAddResult(Result(Spelling, 0));
1920#include "clang/Basic/OperatorKinds.def"
1921
1922 // Add any type names visible from the current scope
1923 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor456c4a12009-09-21 20:12:40 +00001924 0, CurContext, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001925
1926 // Add any type specifiers
1927 AddTypeSpecifierResults(getLangOptions(), 0, Results);
1928
1929 // Add any nested-name-specifiers
1930 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001931 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1932 NextRank + 1, CurContext, Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00001933 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001934
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001935 if (CodeCompleter->includeMacros())
1936 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001937 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00001938}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00001939
Douglas Gregorc464ae82009-12-07 09:27:33 +00001940void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
1941 bool InInterface) {
1942 typedef CodeCompleteConsumer::Result Result;
1943 ResultBuilder Results(*this);
1944 Results.EnterNewScope();
1945 if (ObjCImpDecl) {
1946 // Since we have an implementation, we can end it.
1947 Results.MaybeAddResult(Result("end", 0));
1948
1949 CodeCompletionString *Pattern = 0;
1950 Decl *ImpDecl = ObjCImpDecl.getAs<Decl>();
1951 if (isa<ObjCImplementationDecl>(ImpDecl) ||
1952 isa<ObjCCategoryImplDecl>(ImpDecl)) {
1953 // @dynamic
1954 Pattern = new CodeCompletionString;
1955 Pattern->AddTypedTextChunk("dynamic");
1956 Pattern->AddTextChunk(" ");
1957 Pattern->AddPlaceholderChunk("property");
1958 Results.MaybeAddResult(Result(Pattern, 0));
1959
1960 // @synthesize
1961 Pattern = new CodeCompletionString;
1962 Pattern->AddTypedTextChunk("synthesize");
1963 Pattern->AddTextChunk(" ");
1964 Pattern->AddPlaceholderChunk("property");
1965 Results.MaybeAddResult(Result(Pattern, 0));
1966 }
1967 } else if (InInterface) {
1968 // Since we have an interface or protocol, we can end it.
1969 Results.MaybeAddResult(Result("end", 0));
1970
1971 if (LangOpts.ObjC2) {
1972 // @property
1973 Results.MaybeAddResult(Result("property", 0));
1974 }
1975
1976 // @required
1977 Results.MaybeAddResult(Result("required", 0));
1978
1979 // @optional
1980 Results.MaybeAddResult(Result("optional", 0));
1981 } else {
1982 CodeCompletionString *Pattern = 0;
1983
1984 // @class name ;
1985 Pattern = new CodeCompletionString;
1986 Pattern->AddTypedTextChunk("class");
1987 Pattern->AddTextChunk(" ");
1988 Pattern->AddPlaceholderChunk("identifier");
1989 Pattern->AddTextChunk(";"); // add ';' chunk
1990 Results.MaybeAddResult(Result(Pattern, 0));
1991
1992 // @interface name
1993 // FIXME: Could introduce the whole pattern, including superclasses and
1994 // such.
1995 Pattern = new CodeCompletionString;
1996 Pattern->AddTypedTextChunk("interface");
1997 Pattern->AddTextChunk(" ");
1998 Pattern->AddPlaceholderChunk("class");
1999 Results.MaybeAddResult(Result(Pattern, 0));
2000
2001 // @protocol name
2002 Pattern = new CodeCompletionString;
2003 Pattern->AddTypedTextChunk("protocol");
2004 Pattern->AddTextChunk(" ");
2005 Pattern->AddPlaceholderChunk("protocol");
2006 Results.MaybeAddResult(Result(Pattern, 0));
2007
2008 // @implementation name
2009 Pattern = new CodeCompletionString;
2010 Pattern->AddTypedTextChunk("implementation");
2011 Pattern->AddTextChunk(" ");
2012 Pattern->AddPlaceholderChunk("class");
2013 Results.MaybeAddResult(Result(Pattern, 0));
2014
2015 // @compatibility_alias name
2016 Pattern = new CodeCompletionString;
2017 Pattern->AddTypedTextChunk("compatibility_alias");
2018 Pattern->AddTextChunk(" ");
2019 Pattern->AddPlaceholderChunk("alias");
2020 Pattern->AddTextChunk(" ");
2021 Pattern->AddPlaceholderChunk("class");
2022 Results.MaybeAddResult(Result(Pattern, 0));
2023 }
2024 Results.ExitScope();
2025 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2026}
2027
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002028static void AddObjCExpressionResults(unsigned Rank, ResultBuilder &Results) {
2029 typedef CodeCompleteConsumer::Result Result;
2030 CodeCompletionString *Pattern = 0;
2031
2032 // @encode ( type-name )
2033 Pattern = new CodeCompletionString;
2034 Pattern->AddTypedTextChunk("encode");
2035 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2036 Pattern->AddPlaceholderChunk("type-name");
2037 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2038 Results.MaybeAddResult(Result(Pattern, Rank));
2039
2040 // @protocol ( protocol-name )
2041 Pattern = new CodeCompletionString;
2042 Pattern->AddTypedTextChunk("protocol");
2043 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2044 Pattern->AddPlaceholderChunk("protocol-name");
2045 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2046 Results.MaybeAddResult(Result(Pattern, Rank));
2047
2048 // @selector ( selector )
2049 Pattern = new CodeCompletionString;
2050 Pattern->AddTypedTextChunk("selector");
2051 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2052 Pattern->AddPlaceholderChunk("selector");
2053 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2054 Results.MaybeAddResult(Result(Pattern, Rank));
2055}
2056
2057void Sema::CodeCompleteObjCAtStatement(Scope *S) {
2058 typedef CodeCompleteConsumer::Result Result;
2059 ResultBuilder Results(*this);
2060 Results.EnterNewScope();
2061
2062 CodeCompletionString *Pattern = 0;
2063
2064 // @try { statements } @catch ( declaration ) { statements } @finally
2065 // { statements }
2066 Pattern = new CodeCompletionString;
2067 Pattern->AddTypedTextChunk("try");
2068 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2069 Pattern->AddPlaceholderChunk("statements");
2070 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2071 Pattern->AddTextChunk("@catch");
2072 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2073 Pattern->AddPlaceholderChunk("parameter");
2074 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2075 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2076 Pattern->AddPlaceholderChunk("statements");
2077 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2078 Pattern->AddTextChunk("@finally");
2079 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2080 Pattern->AddPlaceholderChunk("statements");
2081 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2082 Results.MaybeAddResult(Result(Pattern, 0));
2083
2084 // @throw
2085 Pattern = new CodeCompletionString;
2086 Pattern->AddTypedTextChunk("throw");
2087 Pattern->AddTextChunk(" ");
2088 Pattern->AddPlaceholderChunk("expression");
2089 Pattern->AddTextChunk(";");
2090 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2091
2092 // @synchronized ( expression ) { statements }
2093 Pattern = new CodeCompletionString;
2094 Pattern->AddTypedTextChunk("synchronized");
2095 Pattern->AddTextChunk(" ");
2096 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2097 Pattern->AddPlaceholderChunk("expression");
2098 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2099 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2100 Pattern->AddPlaceholderChunk("statements");
2101 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2102 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2103
2104 AddObjCExpressionResults(0, Results);
2105 Results.ExitScope();
2106 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2107}
2108
2109void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2110 ResultBuilder Results(*this);
2111 Results.EnterNewScope();
2112 AddObjCExpressionResults(0, Results);
2113 Results.ExitScope();
2114 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2115}
2116
Douglas Gregor988358f2009-11-19 00:14:45 +00002117/// \brief Determine whether the addition of the given flag to an Objective-C
2118/// property's attributes will cause a conflict.
2119static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2120 // Check if we've already added this flag.
2121 if (Attributes & NewFlag)
2122 return true;
2123
2124 Attributes |= NewFlag;
2125
2126 // Check for collisions with "readonly".
2127 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2128 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2129 ObjCDeclSpec::DQ_PR_assign |
2130 ObjCDeclSpec::DQ_PR_copy |
2131 ObjCDeclSpec::DQ_PR_retain)))
2132 return true;
2133
2134 // Check for more than one of { assign, copy, retain }.
2135 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2136 ObjCDeclSpec::DQ_PR_copy |
2137 ObjCDeclSpec::DQ_PR_retain);
2138 if (AssignCopyRetMask &&
2139 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2140 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2141 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2142 return true;
2143
2144 return false;
2145}
2146
Douglas Gregora93b1082009-11-18 23:08:07 +00002147void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00002148 if (!CodeCompleter)
2149 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00002150
Steve Naroffece8e712009-10-08 21:55:05 +00002151 unsigned Attributes = ODS.getPropertyAttributes();
2152
2153 typedef CodeCompleteConsumer::Result Result;
2154 ResultBuilder Results(*this);
2155 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00002156 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Steve Naroffece8e712009-10-08 21:55:05 +00002157 Results.MaybeAddResult(CodeCompleteConsumer::Result("readonly", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002158 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Steve Naroffece8e712009-10-08 21:55:05 +00002159 Results.MaybeAddResult(CodeCompleteConsumer::Result("assign", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002160 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Steve Naroffece8e712009-10-08 21:55:05 +00002161 Results.MaybeAddResult(CodeCompleteConsumer::Result("readwrite", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002162 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Steve Naroffece8e712009-10-08 21:55:05 +00002163 Results.MaybeAddResult(CodeCompleteConsumer::Result("retain", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002164 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Steve Naroffece8e712009-10-08 21:55:05 +00002165 Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002166 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Steve Naroffece8e712009-10-08 21:55:05 +00002167 Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
Douglas Gregor988358f2009-11-19 00:14:45 +00002168 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002169 CodeCompletionString *Setter = new CodeCompletionString;
2170 Setter->AddTypedTextChunk("setter");
2171 Setter->AddTextChunk(" = ");
2172 Setter->AddPlaceholderChunk("method");
2173 Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
2174 }
Douglas Gregor988358f2009-11-19 00:14:45 +00002175 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002176 CodeCompletionString *Getter = new CodeCompletionString;
2177 Getter->AddTypedTextChunk("getter");
2178 Getter->AddTextChunk(" = ");
2179 Getter->AddPlaceholderChunk("method");
2180 Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
2181 }
Steve Naroffece8e712009-10-08 21:55:05 +00002182 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002183 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00002184}
Steve Naroffc4df6d22009-11-07 02:08:14 +00002185
Douglas Gregor4ad96852009-11-19 07:41:15 +00002186/// \brief Descripts the kind of Objective-C method that we want to find
2187/// via code completion.
2188enum ObjCMethodKind {
2189 MK_Any, //< Any kind of method, provided it means other specified criteria.
2190 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2191 MK_OneArgSelector //< One-argument selector.
2192};
2193
2194static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2195 ObjCMethodKind WantKind,
2196 IdentifierInfo **SelIdents,
2197 unsigned NumSelIdents) {
2198 Selector Sel = Method->getSelector();
2199 if (NumSelIdents > Sel.getNumArgs())
2200 return false;
2201
2202 switch (WantKind) {
2203 case MK_Any: break;
2204 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2205 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2206 }
2207
2208 for (unsigned I = 0; I != NumSelIdents; ++I)
2209 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2210 return false;
2211
2212 return true;
2213}
2214
Douglas Gregor36ecb042009-11-17 23:22:23 +00002215/// \brief Add all of the Objective-C methods in the given Objective-C
2216/// container to the set of results.
2217///
2218/// The container will be a class, protocol, category, or implementation of
2219/// any of the above. This mether will recurse to include methods from
2220/// the superclasses of classes along with their categories, protocols, and
2221/// implementations.
2222///
2223/// \param Container the container in which we'll look to find methods.
2224///
2225/// \param WantInstance whether to add instance methods (only); if false, this
2226/// routine will add factory methods (only).
2227///
2228/// \param CurContext the context in which we're performing the lookup that
2229/// finds methods.
2230///
2231/// \param Results the structure into which we'll add results.
2232static void AddObjCMethods(ObjCContainerDecl *Container,
2233 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00002234 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00002235 IdentifierInfo **SelIdents,
2236 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00002237 DeclContext *CurContext,
2238 ResultBuilder &Results) {
2239 typedef CodeCompleteConsumer::Result Result;
2240 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2241 MEnd = Container->meth_end();
2242 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002243 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2244 // Check whether the selector identifiers we've been given are a
2245 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002246 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00002247 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002248
Douglas Gregord3c68542009-11-19 01:08:35 +00002249 Result R = Result(*M, 0);
2250 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002251 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00002252 Results.MaybeAddResult(R, CurContext);
2253 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00002254 }
2255
2256 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2257 if (!IFace)
2258 return;
2259
2260 // Add methods in protocols.
2261 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2262 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2263 E = Protocols.end();
2264 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002265 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00002266 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002267
2268 // Add methods in categories.
2269 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2270 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00002271 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2272 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002273
2274 // Add a categories protocol methods.
2275 const ObjCList<ObjCProtocolDecl> &Protocols
2276 = CatDecl->getReferencedProtocols();
2277 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2278 E = Protocols.end();
2279 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002280 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2281 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002282
2283 // Add methods in category implementations.
2284 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002285 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2286 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002287 }
2288
2289 // Add methods in superclass.
2290 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002291 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2292 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002293
2294 // Add methods in our implementation, if any.
2295 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002296 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2297 NumSelIdents, CurContext, Results);
2298}
2299
2300
2301void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2302 DeclPtrTy *Methods,
2303 unsigned NumMethods) {
2304 typedef CodeCompleteConsumer::Result Result;
2305
2306 // Try to find the interface where getters might live.
2307 ObjCInterfaceDecl *Class
2308 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2309 if (!Class) {
2310 if (ObjCCategoryDecl *Category
2311 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2312 Class = Category->getClassInterface();
2313
2314 if (!Class)
2315 return;
2316 }
2317
2318 // Find all of the potential getters.
2319 ResultBuilder Results(*this);
2320 Results.EnterNewScope();
2321
2322 // FIXME: We need to do this because Objective-C methods don't get
2323 // pushed into DeclContexts early enough. Argh!
2324 for (unsigned I = 0; I != NumMethods; ++I) {
2325 if (ObjCMethodDecl *Method
2326 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2327 if (Method->isInstanceMethod() &&
2328 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2329 Result R = Result(Method, 0);
2330 R.AllParametersAreInformative = true;
2331 Results.MaybeAddResult(R, CurContext);
2332 }
2333 }
2334
2335 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2336 Results.ExitScope();
2337 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2338}
2339
2340void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2341 DeclPtrTy *Methods,
2342 unsigned NumMethods) {
2343 typedef CodeCompleteConsumer::Result Result;
2344
2345 // Try to find the interface where setters might live.
2346 ObjCInterfaceDecl *Class
2347 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2348 if (!Class) {
2349 if (ObjCCategoryDecl *Category
2350 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2351 Class = Category->getClassInterface();
2352
2353 if (!Class)
2354 return;
2355 }
2356
2357 // Find all of the potential getters.
2358 ResultBuilder Results(*this);
2359 Results.EnterNewScope();
2360
2361 // FIXME: We need to do this because Objective-C methods don't get
2362 // pushed into DeclContexts early enough. Argh!
2363 for (unsigned I = 0; I != NumMethods; ++I) {
2364 if (ObjCMethodDecl *Method
2365 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2366 if (Method->isInstanceMethod() &&
2367 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2368 Result R = Result(Method, 0);
2369 R.AllParametersAreInformative = true;
2370 Results.MaybeAddResult(R, CurContext);
2371 }
2372 }
2373
2374 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2375
2376 Results.ExitScope();
2377 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00002378}
2379
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002380void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregord3c68542009-11-19 01:08:35 +00002381 SourceLocation FNameLoc,
2382 IdentifierInfo **SelIdents,
2383 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002384 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00002385 ObjCInterfaceDecl *CDecl = 0;
2386
Douglas Gregor24a069f2009-11-17 17:59:40 +00002387 if (FName->isStr("super")) {
2388 // We're sending a message to "super".
2389 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2390 // Figure out which interface we're in.
2391 CDecl = CurMethod->getClassInterface();
2392 if (!CDecl)
2393 return;
2394
2395 // Find the superclass of this class.
2396 CDecl = CDecl->getSuperClass();
2397 if (!CDecl)
2398 return;
2399
2400 if (CurMethod->isInstanceMethod()) {
2401 // We are inside an instance method, which means that the message
2402 // send [super ...] is actually calling an instance method on the
2403 // current object. Build the super expression and handle this like
2404 // an instance method.
2405 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2406 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2407 OwningExprResult Super
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002408 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregord3c68542009-11-19 01:08:35 +00002409 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2410 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002411 }
2412
2413 // Okay, we're calling a factory method in our superclass.
2414 }
2415 }
2416
2417 // If the given name refers to an interface type, retrieve the
2418 // corresponding declaration.
2419 if (!CDecl)
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002420 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor24a069f2009-11-17 17:59:40 +00002421 QualType T = GetTypeFromParser(Ty, 0);
2422 if (!T.isNull())
2423 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
2424 CDecl = Interface->getDecl();
2425 }
2426
2427 if (!CDecl && FName->isStr("super")) {
2428 // "super" may be the name of a variable, in which case we are
2429 // probably calling an instance method.
John McCallf7a1a742009-11-24 19:00:30 +00002430 CXXScopeSpec SS;
2431 UnqualifiedId id;
2432 id.setIdentifier(FName, FNameLoc);
2433 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregord3c68542009-11-19 01:08:35 +00002434 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2435 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002436 }
2437
Douglas Gregor36ecb042009-11-17 23:22:23 +00002438 // Add all of the factory methods in this Objective-C class, its protocols,
2439 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00002440 ResultBuilder Results(*this);
2441 Results.EnterNewScope();
Douglas Gregor4ad96852009-11-19 07:41:15 +00002442 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
2443 Results);
Steve Naroffc4df6d22009-11-07 02:08:14 +00002444 Results.ExitScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00002445
Steve Naroffc4df6d22009-11-07 02:08:14 +00002446 // This also suppresses remaining diagnostics.
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002447 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00002448}
2449
Douglas Gregord3c68542009-11-19 01:08:35 +00002450void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
2451 IdentifierInfo **SelIdents,
2452 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002453 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00002454
2455 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00002456
Douglas Gregor36ecb042009-11-17 23:22:23 +00002457 // If necessary, apply function/array conversion to the receiver.
2458 // C99 6.7.5.3p[7,8].
2459 DefaultFunctionArrayConversion(RecExpr);
2460 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00002461
Douglas Gregor36ecb042009-11-17 23:22:23 +00002462 if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType()) {
2463 // FIXME: We're messaging 'id'. Do we actually want to look up every method
2464 // in the universe?
2465 return;
2466 }
2467
Douglas Gregor36ecb042009-11-17 23:22:23 +00002468 // Build the set of methods we can see.
2469 ResultBuilder Results(*this);
2470 Results.EnterNewScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00002471
Douglas Gregorf74a4192009-11-18 00:06:18 +00002472 // Handle messages to Class. This really isn't a message to an instance
2473 // method, so we treat it the same way we would treat a message send to a
2474 // class method.
2475 if (ReceiverType->isObjCClassType() ||
2476 ReceiverType->isObjCQualifiedClassType()) {
2477 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2478 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002479 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
2480 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002481 }
2482 }
2483 // Handle messages to a qualified ID ("id<foo>").
2484 else if (const ObjCObjectPointerType *QualID
2485 = ReceiverType->getAsObjCQualifiedIdType()) {
2486 // Search protocols for instance methods.
2487 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
2488 E = QualID->qual_end();
2489 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002490 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2491 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002492 }
2493 // Handle messages to a pointer to interface type.
2494 else if (const ObjCObjectPointerType *IFacePtr
2495 = ReceiverType->getAsObjCInterfacePointerType()) {
2496 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002497 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
2498 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002499
2500 // Search protocols for instance methods.
2501 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
2502 E = IFacePtr->qual_end();
2503 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002504 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2505 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00002506 }
2507
Steve Naroffc4df6d22009-11-07 02:08:14 +00002508 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002509 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00002510}
Douglas Gregor55385fe2009-11-18 04:19:12 +00002511
2512/// \brief Add all of the protocol declarations that we find in the given
2513/// (translation unit) context.
2514static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00002515 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00002516 ResultBuilder &Results) {
2517 typedef CodeCompleteConsumer::Result Result;
2518
2519 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2520 DEnd = Ctx->decls_end();
2521 D != DEnd; ++D) {
2522 // Record any protocols we find.
2523 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00002524 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
2525 Results.MaybeAddResult(Result(Proto, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002526
2527 // Record any forward-declared protocols we find.
2528 if (ObjCForwardProtocolDecl *Forward
2529 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
2530 for (ObjCForwardProtocolDecl::protocol_iterator
2531 P = Forward->protocol_begin(),
2532 PEnd = Forward->protocol_end();
2533 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00002534 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
2535 Results.MaybeAddResult(Result(*P, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002536 }
2537 }
2538}
2539
2540void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
2541 unsigned NumProtocols) {
2542 ResultBuilder Results(*this);
2543 Results.EnterNewScope();
2544
2545 // Tell the result set to ignore all of the protocols we have
2546 // already seen.
2547 for (unsigned I = 0; I != NumProtocols; ++I)
2548 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
2549 Results.Ignore(Protocol);
2550
2551 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00002552 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
2553 Results);
2554
2555 Results.ExitScope();
2556 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2557}
2558
2559void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
2560 ResultBuilder Results(*this);
2561 Results.EnterNewScope();
2562
2563 // Add all protocols.
2564 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
2565 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00002566
2567 Results.ExitScope();
2568 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2569}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00002570
2571/// \brief Add all of the Objective-C interface declarations that we find in
2572/// the given (translation unit) context.
2573static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
2574 bool OnlyForwardDeclarations,
2575 bool OnlyUnimplemented,
2576 ResultBuilder &Results) {
2577 typedef CodeCompleteConsumer::Result Result;
2578
2579 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2580 DEnd = Ctx->decls_end();
2581 D != DEnd; ++D) {
2582 // Record any interfaces we find.
2583 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
2584 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
2585 (!OnlyUnimplemented || !Class->getImplementation()))
2586 Results.MaybeAddResult(Result(Class, 0), CurContext);
2587
2588 // Record any forward-declared interfaces we find.
2589 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
2590 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
2591 C != CEnd; ++C)
2592 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
2593 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
2594 Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
2595 }
2596 }
2597}
2598
2599void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
2600 ResultBuilder Results(*this);
2601 Results.EnterNewScope();
2602
2603 // Add all classes.
2604 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
2605 false, Results);
2606
2607 Results.ExitScope();
2608 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2609}
2610
2611void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
2612 ResultBuilder Results(*this);
2613 Results.EnterNewScope();
2614
2615 // Make sure that we ignore the class we're currently defining.
2616 NamedDecl *CurClass
2617 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00002618 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00002619 Results.Ignore(CurClass);
2620
2621 // Add all classes.
2622 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2623 false, Results);
2624
2625 Results.ExitScope();
2626 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2627}
2628
2629void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
2630 ResultBuilder Results(*this);
2631 Results.EnterNewScope();
2632
2633 // Add all unimplemented classes.
2634 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2635 true, Results);
2636
2637 Results.ExitScope();
2638 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2639}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00002640
2641void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
2642 IdentifierInfo *ClassName) {
2643 typedef CodeCompleteConsumer::Result Result;
2644
2645 ResultBuilder Results(*this);
2646
2647 // Ignore any categories we find that have already been implemented by this
2648 // interface.
2649 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2650 NamedDecl *CurClass
2651 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2652 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
2653 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2654 Category = Category->getNextClassCategory())
2655 CategoryNames.insert(Category->getIdentifier());
2656
2657 // Add all of the categories we know about.
2658 Results.EnterNewScope();
2659 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
2660 for (DeclContext::decl_iterator D = TU->decls_begin(),
2661 DEnd = TU->decls_end();
2662 D != DEnd; ++D)
2663 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
2664 if (CategoryNames.insert(Category->getIdentifier()))
2665 Results.MaybeAddResult(Result(Category, 0), CurContext);
2666 Results.ExitScope();
2667
2668 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2669}
2670
2671void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
2672 IdentifierInfo *ClassName) {
2673 typedef CodeCompleteConsumer::Result Result;
2674
2675 // Find the corresponding interface. If we couldn't find the interface, the
2676 // program itself is ill-formed. However, we'll try to be helpful still by
2677 // providing the list of all of the categories we know about.
2678 NamedDecl *CurClass
2679 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2680 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
2681 if (!Class)
2682 return CodeCompleteObjCInterfaceCategory(S, ClassName);
2683
2684 ResultBuilder Results(*this);
2685
2686 // Add all of the categories that have have corresponding interface
2687 // declarations in this class and any of its superclasses, except for
2688 // already-implemented categories in the class itself.
2689 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2690 Results.EnterNewScope();
2691 bool IgnoreImplemented = true;
2692 while (Class) {
2693 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2694 Category = Category->getNextClassCategory())
2695 if ((!IgnoreImplemented || !Category->getImplementation()) &&
2696 CategoryNames.insert(Category->getIdentifier()))
2697 Results.MaybeAddResult(Result(Category, 0), CurContext);
2698
2699 Class = Class->getSuperClass();
2700 IgnoreImplemented = false;
2701 }
2702 Results.ExitScope();
2703
2704 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2705}
Douglas Gregor322328b2009-11-18 22:32:06 +00002706
Douglas Gregor424b2a52009-11-18 22:56:13 +00002707void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00002708 typedef CodeCompleteConsumer::Result Result;
2709 ResultBuilder Results(*this);
2710
2711 // Figure out where this @synthesize lives.
2712 ObjCContainerDecl *Container
2713 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2714 if (!Container ||
2715 (!isa<ObjCImplementationDecl>(Container) &&
2716 !isa<ObjCCategoryImplDecl>(Container)))
2717 return;
2718
2719 // Ignore any properties that have already been implemented.
2720 for (DeclContext::decl_iterator D = Container->decls_begin(),
2721 DEnd = Container->decls_end();
2722 D != DEnd; ++D)
2723 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
2724 Results.Ignore(PropertyImpl->getPropertyDecl());
2725
2726 // Add any properties that we find.
2727 Results.EnterNewScope();
2728 if (ObjCImplementationDecl *ClassImpl
2729 = dyn_cast<ObjCImplementationDecl>(Container))
2730 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
2731 Results);
2732 else
2733 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
2734 false, CurContext, Results);
2735 Results.ExitScope();
2736
2737 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2738}
2739
2740void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
2741 IdentifierInfo *PropertyName,
2742 DeclPtrTy ObjCImpDecl) {
2743 typedef CodeCompleteConsumer::Result Result;
2744 ResultBuilder Results(*this);
2745
2746 // Figure out where this @synthesize lives.
2747 ObjCContainerDecl *Container
2748 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2749 if (!Container ||
2750 (!isa<ObjCImplementationDecl>(Container) &&
2751 !isa<ObjCCategoryImplDecl>(Container)))
2752 return;
2753
2754 // Figure out which interface we're looking into.
2755 ObjCInterfaceDecl *Class = 0;
2756 if (ObjCImplementationDecl *ClassImpl
2757 = dyn_cast<ObjCImplementationDecl>(Container))
2758 Class = ClassImpl->getClassInterface();
2759 else
2760 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
2761 ->getClassInterface();
2762
2763 // Add all of the instance variables in this class and its superclasses.
2764 Results.EnterNewScope();
2765 for(; Class; Class = Class->getSuperClass()) {
2766 // FIXME: We could screen the type of each ivar for compatibility with
2767 // the property, but is that being too paternal?
2768 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
2769 IVarEnd = Class->ivar_end();
2770 IVar != IVarEnd; ++IVar)
2771 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
2772 }
2773 Results.ExitScope();
2774
2775 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2776}