blob: 1391adfd48df8707286127459d73e804c5d740d6 [file] [log] [blame]
Douglas Gregor2436e712009-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 Gregorf2510672009-09-21 19:57:38 +000015#include "clang/AST/ExprCXX.h"
Douglas Gregor8ce33212009-11-17 17:59:40 +000016#include "clang/AST/ExprObjC.h"
Douglas Gregorf329c7c2009-10-30 16:50:04 +000017#include "clang/Lex/MacroInfo.h"
18#include "clang/Lex/Preprocessor.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000019#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregore6688e62009-09-28 03:51:44 +000020#include "llvm/ADT/StringExtras.h"
Douglas Gregor3545ff42009-09-21 16:56:56 +000021#include <list>
22#include <map>
23#include <vector>
Douglas Gregor2436e712009-09-17 21:32:03 +000024
25using namespace clang;
26
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-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 Gregor3545ff42009-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 Gregor05e7ca32009-12-06 20:23:50 +0000105 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor3545ff42009-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 Gregor2af2f672009-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 Gregor3545ff42009-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 Gregorbaf69612009-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 Gregor3545ff42009-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 Gregor9d64c5e2009-09-21 20:51:25 +0000160 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor3545ff42009-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 Gregore412a5a2009-09-23 22:26:46 +0000168 bool IsMember(NamedDecl *ND) const;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000169 //@}
170 };
171}
172
Douglas Gregor05e7ca32009-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 Gregor94bb5e82009-12-06 21:27:58 +0000225 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregor05e7ca32009-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 Gregor94bb5e82009-12-06 21:27:58 +0000233 return X.DeclOrIterator.getOpaqueValue()
234 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000235 X.SingleDeclIndex == Y.SingleDeclIndex;
236 }
237
238 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregor94bb5e82009-12-06 21:27:58 +0000239 return !(X == Y);
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000240 }
241};
242
Douglas Gregor05e7ca32009-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 Gregor3545ff42009-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 Gregor3545ff42009-09-21 16:56:56 +0000284 return HiddenCtx != Visible->getDeclContext()->getLookupContext();
285}
286
Douglas Gregor2af2f672009-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 Gregor9eb77012009-11-07 00:00:49 +0000329 }
Douglas Gregor2af2f672009-09-21 20:12:40 +0000330 return Result;
331}
332
333void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
Douglas Gregor64b12b52009-09-22 23:31:26 +0000334 assert(!ShadowMaps.empty() && "Must enter into a results scope");
335
Douglas Gregor3545ff42009-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 Gregor58acf322009-10-09 22:16:47 +0000341
342 // Skip unnamed entities.
343 if (!R.Declaration->getDeclName())
344 return;
345
Douglas Gregor3545ff42009-09-21 16:56:56 +0000346 // Look through using declarations.
John McCall3f746822009-11-17 05:59:44 +0000347 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration))
Douglas Gregor5bf52692009-09-22 23:15:58 +0000348 MaybeAddResult(Result(Using->getTargetDecl(), R.Rank, R.Qualifier),
349 CurContext);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000350
Douglas Gregor3545ff42009-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 Gregor83c49b52009-12-11 16:18:54 +0000359
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000360 // Class template (partial) specializations are never added as results.
Douglas Gregor83c49b52009-12-11 16:18:54 +0000361 if (isa<ClassTemplateSpecializationDecl>(CanonDecl) ||
362 isa<ClassTemplatePartialSpecializationDecl>(CanonDecl))
363 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000364
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000365 // Using declarations themselves are never added as results.
366 if (isa<UsingDecl>(CanonDecl))
367 return;
368
Douglas Gregor3545ff42009-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 Gregor58acf322009-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 Dunbar2c422dc92009-10-18 20:26:12 +0000376 //
377 // FIXME: Add predicate for this.
Douglas Gregor58acf322009-10-09 22:16:47 +0000378 if (Id->getLength() >= 2) {
Daniel Dunbar2c422dc92009-10-18 20:26:12 +0000379 const char *Name = Id->getNameStart();
Douglas Gregor58acf322009-10-09 22:16:47 +0000380 if (Name[0] == '_' &&
381 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
382 return;
383 }
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-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 Gregor3545ff42009-09-21 16:56:56 +0000405 if (ND->getCanonicalDecl() == CanonDecl) {
406 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-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 Gregor3545ff42009-09-21 16:56:56 +0000430 // A tag declaration does not hide a non-tag declaration.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000431 if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-12-06 20:23:50 +0000437 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor3545ff42009-09-21 16:56:56 +0000438 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000439 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-12-06 20:23:50 +0000444 I->first)) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000445 // Note that this result was hidden.
446 R.Hidden = true;
Douglas Gregor5bf52692009-09-22 23:15:58 +0000447 R.QualifierIsInformative = false;
Douglas Gregor2af2f672009-09-21 20:12:40 +0000448
449 if (!R.Qualifier)
450 R.Qualifier = getRequiredQualification(SemaRef.Context,
451 CurContext,
452 R.Declaration->getDeclContext());
Douglas Gregor3545ff42009-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 Gregore412a5a2009-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 Gregor5bf52692009-09-22 23:15:58 +0000475 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregore412a5a2009-09-23 22:26:46 +0000476 if (R.QualifierIsInformative && !R.Qualifier &&
477 !R.StartsNestedNameSpecifier) {
Douglas Gregor5bf52692009-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 Gregore412a5a2009-09-23 22:26:46 +0000487
Douglas Gregor3545ff42009-09-21 16:56:56 +0000488 // Insert this result into the set of results and into the current shadow
489 // map.
Douglas Gregor05e7ca32009-12-06 20:23:50 +0000490 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor3545ff42009-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 Gregor05e7ca32009-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 Gregor3545ff42009-09-21 16:56:56 +0000507 ShadowMaps.pop_back();
508}
509
Douglas Gregor9d64c5e2009-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 Gregor3545ff42009-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 Gregor99fe2ad2009-12-11 17:31:05 +0000571/// \brief Determines whether the given declaration is a type.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000572bool ResultBuilder::IsType(NamedDecl *ND) const {
573 return isa<TypeDecl>(ND);
574}
575
Douglas Gregor99fe2ad2009-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 Gregore412a5a2009-09-23 22:26:46 +0000579bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor99fe2ad2009-12-11 17:31:05 +0000580 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
581 ND = Using->getTargetDecl();
582
Douglas Gregor70788392009-12-11 18:14:22 +0000583 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
584 isa<ObjCPropertyDecl>(ND);
Douglas Gregore412a5a2009-09-23 22:26:46 +0000585}
586
Douglas Gregor3545ff42009-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 Gregor5bf52692009-09-22 23:15:58 +0000601/// \param Rank the rank given to results in this declaration context.
Douglas Gregor3545ff42009-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 Gregor5bf52692009-09-22 23:15:58 +0000609/// \param InBaseClass whether we are in a base class.
610///
Douglas Gregor3545ff42009-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 Gregor5bf52692009-09-22 23:15:58 +0000614 unsigned Rank,
Douglas Gregor2af2f672009-09-21 20:12:40 +0000615 DeclContext *CurContext,
616 llvm::SmallPtrSet<DeclContext *, 16> &Visited,
Douglas Gregor5bf52692009-09-22 23:15:58 +0000617 ResultBuilder &Results,
618 bool InBaseClass = false) {
Douglas Gregor3545ff42009-09-21 16:56:56 +0000619 // Make sure we don't visit the same context twice.
620 if (!Visited.insert(Ctx->getPrimaryContext()))
Douglas Gregor5bf52692009-09-22 23:15:58 +0000621 return Rank;
Douglas Gregor3545ff42009-09-21 16:56:56 +0000622
623 // Enumerate all of the results in this context.
Douglas Gregor5bf52692009-09-22 23:15:58 +0000624 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor3545ff42009-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 Gregor8caea942009-11-09 21:35:27 +0000629 DEnd = CurCtx->decls_end();
Douglas Gregor3545ff42009-09-21 16:56:56 +0000630 D != DEnd; ++D) {
631 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
Douglas Gregor5bf52692009-09-22 23:15:58 +0000632 Results.MaybeAddResult(Result(ND, Rank, 0, InBaseClass), CurContext);
Douglas Gregor8caea942009-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 Gregor3545ff42009-09-21 16:56:56 +0000640 }
641 }
642
643 // Traverse the contexts of inherited classes.
Douglas Gregor3545ff42009-09-21 16:56:56 +0000644 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
645 for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
Douglas Gregor8caea942009-11-09 21:35:27 +0000646 BEnd = Record->bases_end();
Douglas Gregor3545ff42009-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 Gregor5bf52692009-09-22 23:15:58 +0000678 CollectMemberLookupResults(Record->getDecl(), Rank, CurContext, Visited,
679 Results, /*InBaseClass=*/true);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000680 }
681 }
682
683 // FIXME: Look into base classes in Objective-C!
684
685 Results.ExitScope();
Douglas Gregor5bf52692009-09-22 23:15:58 +0000686 return Rank + 1;
Douglas Gregor3545ff42009-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 Gregor2af2f672009-09-21 20:12:40 +0000705 DeclContext *CurContext,
Douglas Gregor3545ff42009-09-21 16:56:56 +0000706 ResultBuilder &Results) {
707 llvm::SmallPtrSet<DeclContext *, 16> Visited;
Douglas Gregor2af2f672009-09-21 20:12:40 +0000708 return CollectMemberLookupResults(Ctx, InitialRank, CurContext, Visited,
709 Results);
Douglas Gregor3545ff42009-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 Gregor2af2f672009-09-21 20:12:40 +0000720/// \param CurContext the context from which lookup results will be found.
721///
Douglas Gregor3545ff42009-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 Gregor2af2f672009-09-21 20:12:40 +0000726 DeclContext *CurContext,
Douglas Gregor3545ff42009-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 Gregor2af2f672009-09-21 20:12:40 +0000748 NextRank = CollectMemberLookupResults(Ctx, NextRank + 1, CurContext,
749 Results);
Douglas Gregor3545ff42009-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 Gregor2af2f672009-09-21 20:12:40 +0000763 CurContext, Results);
Douglas Gregor3545ff42009-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 Gregor2af2f672009-09-21 20:12:40 +0000769 Results.MaybeAddResult(CodeCompleteConsumer::Result(ND, NextRank),
770 CurContext);
Douglas Gregor3545ff42009-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 Gregor2af2f672009-09-21 20:12:40 +0000778 CurContext, Results);
Douglas Gregor3545ff42009-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 Gregorbc7c5e42009-12-07 09:51:25 +0000785static void AddTypeSpecifierResults(const LangOptions &LangOpts, unsigned Rank,
Douglas Gregor3545ff42009-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 Gregorb3fa9192009-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 Gregor3545ff42009-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 Gregor9eb77012009-11-07 00:00:49 +0000869 typedef CodeCompletionString::Chunk Chunk;
870
Douglas Gregor3545ff42009-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 Gregor9eb77012009-11-07 00:00:49 +0000885 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-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 Kramerb33a97c2009-11-29 20:18:50 +0000896 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000897 }
Douglas Gregorba449032009-09-22 21:42:17 +0000898
899 if (const FunctionProtoType *Proto
900 = Function->getType()->getAs<FunctionProtoType>())
901 if (Proto->isVariadic())
902 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor3545ff42009-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 Gregor9eb77012009-11-07 00:00:49 +0000910 typedef CodeCompletionString::Chunk Chunk;
911
Douglas Gregor3545ff42009-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 Gregor9eb77012009-11-07 00:00:49 +0000967 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3545ff42009-09-21 16:56:56 +0000968
969 // Add the placeholder string.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +0000970 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor3545ff42009-09-21 16:56:56 +0000971 }
972}
973
Douglas Gregorf2510672009-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 Gregor0f622362009-12-11 18:44:16 +0000976static void
977AddQualifierToCompletionString(CodeCompletionString *Result,
978 NestedNameSpecifier *Qualifier,
979 bool QualifierIsInformative,
980 ASTContext &Context) {
Douglas Gregorf2510672009-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 Gregor5bf52692009-09-22 23:15:58 +0000989 if (QualifierIsInformative)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +0000990 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor5bf52692009-09-22 23:15:58 +0000991 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +0000992 Result->AddTextChunk(PrintedNNS);
Douglas Gregorf2510672009-09-21 19:57:38 +0000993}
994
Douglas Gregor0f622362009-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 Gregor3545ff42009-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 Gregor9eb77012009-11-07 00:00:49 +00001020 typedef CodeCompletionString::Chunk Chunk;
1021
Douglas Gregorf09935f2009-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 Gregor3545ff42009-09-21 16:56:56 +00001031
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001032 if (Kind == RK_Macro) {
1033 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregorf09935f2009-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 Gregorf329c7c2009-10-30 16:50:04 +00001040
1041 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor9eb77012009-11-07 00:00:49 +00001042 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf329c7c2009-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 Gregor9eb77012009-11-07 00:00:49 +00001046 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001047
1048 if (!MI->isVariadic() || A != AEnd - 1) {
1049 // Non-variadic argument.
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001050 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregorf329c7c2009-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 Kramerb33a97c2009-11-29 20:18:50 +00001062 Result->AddPlaceholderChunk(Arg);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001063 }
1064 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001065 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001066 return Result;
1067 }
1068
1069 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor3545ff42009-09-21 16:56:56 +00001070 NamedDecl *ND = Declaration;
1071
Douglas Gregor9eb77012009-11-07 00:00:49 +00001072 if (StartsNestedNameSpecifier) {
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001073 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001074 Result->AddTextChunk("::");
1075 return Result;
1076 }
1077
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001078 AddResultTypeChunk(S.Context, ND, Result);
1079
Douglas Gregor3545ff42009-09-21 16:56:56 +00001080 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001081 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1082 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001083 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001084 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001085 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001086 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001087 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001088 return Result;
1089 }
1090
1091 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001092 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1093 S.Context);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001094 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001095 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor3545ff42009-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 Gregor9eb77012009-11-07 00:00:49 +00001119 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor3545ff42009-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 Gregor9eb77012009-11-07 00:00:49 +00001131 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001132 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1133 LastDeducibleArgument);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001134 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001135 }
1136
1137 // Add the function parameters
Douglas Gregor9eb77012009-11-07 00:00:49 +00001138 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001139 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001140 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor0f622362009-12-11 18:44:16 +00001141 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001142 return Result;
1143 }
1144
1145 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor5bf52692009-09-22 23:15:58 +00001146 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1147 S.Context);
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001148 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor9eb77012009-11-07 00:00:49 +00001149 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001150 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001151 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor3545ff42009-09-21 16:56:56 +00001152 return Result;
1153 }
1154
Douglas Gregord3c5d792009-11-17 16:44:22 +00001155 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregord3c5d792009-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 Gregor1b605f72009-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 Gregord3c5d792009-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 Gregor1b605f72009-11-19 01:08:35 +00001179 std::string Keyword;
1180 if (Idx > StartParameter)
1181 Keyword = " ";
Douglas Gregord3c5d792009-11-17 16:44:22 +00001182 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1183 Keyword += II->getName().str();
1184 Keyword += ":";
Douglas Gregorc8537c52009-11-19 07:41:15 +00001185 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregor1b605f72009-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 Gregord3c5d792009-11-17 16:44:22 +00001191 }
Douglas Gregor1b605f72009-11-19 01:08:35 +00001192
1193 // If we're before the starting parameter, skip the placeholder.
1194 if (Idx < StartParameter)
1195 continue;
Douglas Gregord3c5d792009-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 Gregorc8537c52009-11-19 07:41:15 +00001202 if (AllParametersAreInformative)
1203 Result->AddInformativeChunk(Arg);
1204 else
1205 Result->AddPlaceholderChunk(Arg);
Douglas Gregord3c5d792009-11-17 16:44:22 +00001206 }
1207
1208 return Result;
1209 }
1210
Douglas Gregorf09935f2009-12-01 05:55:20 +00001211 if (Qualifier)
Douglas Gregor5bf52692009-09-22 23:15:58 +00001212 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1213 S.Context);
Douglas Gregorf09935f2009-12-01 05:55:20 +00001214
1215 Result->AddTypedTextChunk(ND->getNameAsString());
1216 return Result;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001217}
1218
Douglas Gregorf0f51982009-09-23 00:34:09 +00001219CodeCompletionString *
1220CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1221 unsigned CurrentArg,
1222 Sema &S) const {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001223 typedef CodeCompletionString::Chunk Chunk;
1224
Douglas Gregorf0f51982009-09-23 00:34:09 +00001225 CodeCompletionString *Result = new CodeCompletionString;
1226 FunctionDecl *FDecl = getFunction();
Douglas Gregorb3fa9192009-12-18 18:53:37 +00001227 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001228 const FunctionProtoType *Proto
1229 = dyn_cast<FunctionProtoType>(getFunctionType());
1230 if (!FDecl && !Proto) {
1231 // Function without a prototype. Just give the return type and a
1232 // highlighted ellipsis.
1233 const FunctionType *FT = getFunctionType();
1234 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001235 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor9eb77012009-11-07 00:00:49 +00001236 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1237 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1238 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001239 return Result;
1240 }
1241
1242 if (FDecl)
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001243 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregorf0f51982009-09-23 00:34:09 +00001244 else
1245 Result->AddTextChunk(
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001246 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001247
Douglas Gregor9eb77012009-11-07 00:00:49 +00001248 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001249 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1250 for (unsigned I = 0; I != NumParams; ++I) {
1251 if (I)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001252 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001253
1254 std::string ArgString;
1255 QualType ArgType;
1256
1257 if (FDecl) {
1258 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1259 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1260 } else {
1261 ArgType = Proto->getArgType(I);
1262 }
1263
1264 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1265
1266 if (I == CurrentArg)
Douglas Gregor9eb77012009-11-07 00:00:49 +00001267 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001268 ArgString));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001269 else
Benjamin Kramerb33a97c2009-11-29 20:18:50 +00001270 Result->AddTextChunk(ArgString);
Douglas Gregorf0f51982009-09-23 00:34:09 +00001271 }
1272
1273 if (Proto && Proto->isVariadic()) {
Douglas Gregor9eb77012009-11-07 00:00:49 +00001274 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001275 if (CurrentArg < NumParams)
1276 Result->AddTextChunk("...");
1277 else
Douglas Gregor9eb77012009-11-07 00:00:49 +00001278 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001279 }
Douglas Gregor9eb77012009-11-07 00:00:49 +00001280 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregorf0f51982009-09-23 00:34:09 +00001281
1282 return Result;
1283}
1284
Douglas Gregor3545ff42009-09-21 16:56:56 +00001285namespace {
1286 struct SortCodeCompleteResult {
1287 typedef CodeCompleteConsumer::Result Result;
1288
Douglas Gregore6688e62009-09-28 03:51:44 +00001289 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor249d6822009-12-05 09:08:56 +00001290 Selector XSel = X.getObjCSelector();
1291 Selector YSel = Y.getObjCSelector();
1292 if (!XSel.isNull() && !YSel.isNull()) {
1293 // We are comparing two selectors.
1294 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1295 if (N == 0)
1296 ++N;
1297 for (unsigned I = 0; I != N; ++I) {
1298 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1299 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1300 if (!XId || !YId)
1301 return XId && !YId;
1302
1303 switch (XId->getName().compare_lower(YId->getName())) {
1304 case -1: return true;
1305 case 1: return false;
1306 default: break;
1307 }
1308 }
1309
1310 return XSel.getNumArgs() < YSel.getNumArgs();
1311 }
1312
1313 // For non-selectors, order by kind.
1314 if (X.getNameKind() != Y.getNameKind())
Douglas Gregore6688e62009-09-28 03:51:44 +00001315 return X.getNameKind() < Y.getNameKind();
1316
Douglas Gregor249d6822009-12-05 09:08:56 +00001317 // Order identifiers by comparison of their lowercased names.
1318 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1319 return XId->getName().compare_lower(
1320 Y.getAsIdentifierInfo()->getName()) < 0;
1321
1322 // Order overloaded operators by the order in which they appear
1323 // in our list of operators.
1324 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1325 return XOp < Y.getCXXOverloadedOperator();
1326
1327 // Order C++0x user-defined literal operators lexically by their
1328 // lowercased suffixes.
1329 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1330 return XLit->getName().compare_lower(
1331 Y.getCXXLiteralIdentifier()->getName()) < 0;
1332
1333 // The only stable ordering we have is to turn the name into a
1334 // string and then compare the lower-case strings. This is
1335 // inefficient, but thankfully does not happen too often.
Benjamin Kramer4053e5d2009-12-05 10:22:15 +00001336 return llvm::StringRef(X.getAsString()).compare_lower(
1337 Y.getAsString()) < 0;
Douglas Gregore6688e62009-09-28 03:51:44 +00001338 }
1339
Douglas Gregor3545ff42009-09-21 16:56:56 +00001340 bool operator()(const Result &X, const Result &Y) const {
1341 // Sort first by rank.
1342 if (X.Rank < Y.Rank)
1343 return true;
1344 else if (X.Rank > Y.Rank)
1345 return false;
1346
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001347 // We use a special ordering for keywords and patterns, based on the
1348 // typed text.
1349 if ((X.Kind == Result::RK_Keyword || X.Kind == Result::RK_Pattern) &&
1350 (Y.Kind == Result::RK_Keyword || Y.Kind == Result::RK_Pattern)) {
1351 const char *XStr = (X.Kind == Result::RK_Keyword)? X.Keyword
1352 : X.Pattern->getTypedText();
1353 const char *YStr = (Y.Kind == Result::RK_Keyword)? Y.Keyword
1354 : Y.Pattern->getTypedText();
Benjamin Kramered606352009-12-05 10:07:04 +00001355 return llvm::StringRef(XStr).compare_lower(YStr) < 0;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001356 }
1357
Douglas Gregor3545ff42009-09-21 16:56:56 +00001358 // Result kinds are ordered by decreasing importance.
1359 if (X.Kind < Y.Kind)
1360 return true;
1361 else if (X.Kind > Y.Kind)
1362 return false;
1363
1364 // Non-hidden names precede hidden names.
1365 if (X.Hidden != Y.Hidden)
1366 return !X.Hidden;
1367
Douglas Gregore412a5a2009-09-23 22:26:46 +00001368 // Non-nested-name-specifiers precede nested-name-specifiers.
1369 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1370 return !X.StartsNestedNameSpecifier;
1371
Douglas Gregor3545ff42009-09-21 16:56:56 +00001372 // Ordering depends on the kind of result.
1373 switch (X.Kind) {
1374 case Result::RK_Declaration:
1375 // Order based on the declaration names.
Douglas Gregore6688e62009-09-28 03:51:44 +00001376 return isEarlierDeclarationName(X.Declaration->getDeclName(),
1377 Y.Declaration->getDeclName());
Douglas Gregor3545ff42009-09-21 16:56:56 +00001378
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001379 case Result::RK_Macro:
Douglas Gregor249d6822009-12-05 09:08:56 +00001380 return X.Macro->getName().compare_lower(Y.Macro->getName()) < 0;
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001381
1382 case Result::RK_Keyword:
1383 case Result::RK_Pattern:
Jeffrey Yasskin1615d452009-12-12 05:05:38 +00001384 llvm_unreachable("Result kinds handled above");
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001385 break;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001386 }
1387
1388 // Silence GCC warning.
1389 return false;
1390 }
1391 };
1392}
1393
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001394static void AddMacroResults(Preprocessor &PP, unsigned Rank,
1395 ResultBuilder &Results) {
1396 Results.EnterNewScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00001397 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1398 MEnd = PP.macro_end();
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001399 M != MEnd; ++M)
1400 Results.MaybeAddResult(CodeCompleteConsumer::Result(M->first, Rank));
1401 Results.ExitScope();
1402}
1403
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001404static void HandleCodeCompleteResults(Sema *S,
1405 CodeCompleteConsumer *CodeCompleter,
1406 CodeCompleteConsumer::Result *Results,
1407 unsigned NumResults) {
Douglas Gregor3545ff42009-09-21 16:56:56 +00001408 // Sort the results by rank/kind/etc.
1409 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1410
1411 if (CodeCompleter)
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001412 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor45f83ee2009-11-19 00:01:57 +00001413
1414 for (unsigned I = 0; I != NumResults; ++I)
1415 Results[I].Destroy();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001416}
1417
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00001418void Sema::CodeCompleteOrdinaryName(Scope *S) {
Douglas Gregor92253692009-12-07 09:54:55 +00001419 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00001420 ResultBuilder Results(*this, &ResultBuilder::IsOrdinaryName);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001421 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1422 0, CurContext, Results);
Douglas Gregor92253692009-12-07 09:54:55 +00001423
1424 Results.EnterNewScope();
1425 AddTypeSpecifierResults(getLangOptions(), NextRank, Results);
1426
1427 if (getLangOptions().ObjC1) {
1428 // Add the "super" keyword, if appropriate.
1429 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(CurContext))
1430 if (Method->getClassInterface()->getSuperClass())
1431 Results.MaybeAddResult(Result("super", NextRank));
1432 }
1433
1434 Results.ExitScope();
1435
Douglas Gregor9eb77012009-11-07 00:00:49 +00001436 if (CodeCompleter->includeMacros())
1437 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001438 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor9d64c5e2009-09-21 20:51:25 +00001439}
1440
Douglas Gregor9291bad2009-11-18 01:29:26 +00001441static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor5d649882009-11-18 22:32:06 +00001442 bool AllowCategories,
Douglas Gregor9291bad2009-11-18 01:29:26 +00001443 DeclContext *CurContext,
1444 ResultBuilder &Results) {
1445 typedef CodeCompleteConsumer::Result Result;
1446
1447 // Add properties in this container.
1448 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1449 PEnd = Container->prop_end();
1450 P != PEnd;
1451 ++P)
1452 Results.MaybeAddResult(Result(*P, 0), CurContext);
1453
1454 // Add properties in referenced protocols.
1455 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1456 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1457 PEnd = Protocol->protocol_end();
1458 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00001459 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001460 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor5d649882009-11-18 22:32:06 +00001461 if (AllowCategories) {
1462 // Look through categories.
1463 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1464 Category; Category = Category->getNextClassCategory())
1465 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1466 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00001467
1468 // Look through protocols.
1469 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1470 E = IFace->protocol_end();
1471 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00001472 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001473
1474 // Look in the superclass.
1475 if (IFace->getSuperClass())
Douglas Gregor5d649882009-11-18 22:32:06 +00001476 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
1477 Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001478 } else if (const ObjCCategoryDecl *Category
1479 = dyn_cast<ObjCCategoryDecl>(Container)) {
1480 // Look through protocols.
1481 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
1482 PEnd = Category->protocol_end();
1483 P != PEnd; ++P)
Douglas Gregor5d649882009-11-18 22:32:06 +00001484 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001485 }
1486}
1487
Douglas Gregor2436e712009-09-17 21:32:03 +00001488void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
1489 SourceLocation OpLoc,
1490 bool IsArrow) {
1491 if (!BaseE || !CodeCompleter)
1492 return;
1493
Douglas Gregor3545ff42009-09-21 16:56:56 +00001494 typedef CodeCompleteConsumer::Result Result;
1495
Douglas Gregor2436e712009-09-17 21:32:03 +00001496 Expr *Base = static_cast<Expr *>(BaseE);
1497 QualType BaseType = Base->getType();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001498
1499 if (IsArrow) {
1500 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
1501 BaseType = Ptr->getPointeeType();
1502 else if (BaseType->isObjCObjectPointerType())
1503 /*Do nothing*/ ;
1504 else
1505 return;
1506 }
1507
Douglas Gregore412a5a2009-09-23 22:26:46 +00001508 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001509 unsigned NextRank = 0;
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001510
Douglas Gregor9291bad2009-11-18 01:29:26 +00001511 Results.EnterNewScope();
1512 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
1513 // Access to a C/C++ class, struct, or union.
1514 NextRank = CollectMemberLookupResults(Record->getDecl(), NextRank,
1515 Record->getDecl(), Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001516
Douglas Gregor9291bad2009-11-18 01:29:26 +00001517 if (getLangOptions().CPlusPlus) {
1518 if (!Results.empty()) {
1519 // The "template" keyword can follow "->" or "." in the grammar.
1520 // However, we only want to suggest the template keyword if something
1521 // is dependent.
1522 bool IsDependent = BaseType->isDependentType();
1523 if (!IsDependent) {
1524 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
1525 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
1526 IsDependent = Ctx->isDependentContext();
1527 break;
1528 }
1529 }
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001530
Douglas Gregor9291bad2009-11-18 01:29:26 +00001531 if (IsDependent)
1532 Results.MaybeAddResult(Result("template", NextRank++));
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001533 }
1534
Douglas Gregor9291bad2009-11-18 01:29:26 +00001535 // We could have the start of a nested-name-specifier. Add those
1536 // results as well.
Douglas Gregor99fe2ad2009-12-11 17:31:05 +00001537 // FIXME: We should really walk base classes to produce
1538 // nested-name-specifiers so that we produce more-precise results.
Douglas Gregor9291bad2009-11-18 01:29:26 +00001539 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
1540 CollectLookupResults(S, Context.getTranslationUnitDecl(), NextRank,
1541 CurContext, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001542 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00001543 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
1544 // Objective-C property reference.
1545
1546 // Add property results based on our interface.
1547 const ObjCObjectPointerType *ObjCPtr
1548 = BaseType->getAsObjCInterfacePointerType();
1549 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor5d649882009-11-18 22:32:06 +00001550 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001551
1552 // Add properties from the protocols in a qualified interface.
1553 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
1554 E = ObjCPtr->qual_end();
1555 I != E; ++I)
Douglas Gregor5d649882009-11-18 22:32:06 +00001556 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor9291bad2009-11-18 01:29:26 +00001557
1558 // FIXME: We could (should?) also look for "implicit" properties, identified
1559 // only by the presence of nullary and unary selectors.
1560 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
1561 (!IsArrow && BaseType->isObjCInterfaceType())) {
1562 // Objective-C instance variable access.
1563 ObjCInterfaceDecl *Class = 0;
1564 if (const ObjCObjectPointerType *ObjCPtr
1565 = BaseType->getAs<ObjCObjectPointerType>())
1566 Class = ObjCPtr->getInterfaceDecl();
1567 else
1568 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
1569
1570 // Add all ivars from this class and its superclasses.
1571 for (; Class; Class = Class->getSuperClass()) {
1572 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
1573 IVarEnd = Class->ivar_end();
1574 IVar != IVarEnd; ++IVar)
1575 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
1576 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001577 }
Douglas Gregor9291bad2009-11-18 01:29:26 +00001578
1579 // FIXME: How do we cope with isa?
1580
1581 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001582
1583 // Add macros
1584 if (CodeCompleter->includeMacros())
1585 AddMacroResults(PP, NextRank, Results);
1586
1587 // Hand off the results found for code completion.
1588 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00001589}
1590
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00001591void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
1592 if (!CodeCompleter)
1593 return;
1594
Douglas Gregor3545ff42009-09-21 16:56:56 +00001595 typedef CodeCompleteConsumer::Result Result;
1596 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00001597 switch ((DeclSpec::TST)TagSpec) {
1598 case DeclSpec::TST_enum:
Douglas Gregor3545ff42009-09-21 16:56:56 +00001599 Filter = &ResultBuilder::IsEnum;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00001600 break;
1601
1602 case DeclSpec::TST_union:
Douglas Gregor3545ff42009-09-21 16:56:56 +00001603 Filter = &ResultBuilder::IsUnion;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00001604 break;
1605
1606 case DeclSpec::TST_struct:
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00001607 case DeclSpec::TST_class:
Douglas Gregor3545ff42009-09-21 16:56:56 +00001608 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00001609 break;
1610
1611 default:
1612 assert(false && "Unknown type specifier kind in CodeCompleteTag");
1613 return;
1614 }
Douglas Gregor3545ff42009-09-21 16:56:56 +00001615
1616 ResultBuilder Results(*this, Filter);
1617 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor2af2f672009-09-21 20:12:40 +00001618 0, CurContext, Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001619
1620 if (getLangOptions().CPlusPlus) {
1621 // We could have the start of a nested-name-specifier. Add those
1622 // results as well.
1623 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001624 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1625 NextRank, CurContext, Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001626 }
1627
Douglas Gregor9eb77012009-11-07 00:00:49 +00001628 if (CodeCompleter->includeMacros())
1629 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001630 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorf45b0cf2009-09-18 15:37:17 +00001631}
1632
Douglas Gregord328d572009-09-21 18:10:23 +00001633void Sema::CodeCompleteCase(Scope *S) {
1634 if (getSwitchStack().empty() || !CodeCompleter)
1635 return;
1636
1637 SwitchStmt *Switch = getSwitchStack().back();
1638 if (!Switch->getCond()->getType()->isEnumeralType())
1639 return;
1640
1641 // Code-complete the cases of a switch statement over an enumeration type
1642 // by providing the list of
1643 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
1644
1645 // Determine which enumerators we have already seen in the switch statement.
1646 // FIXME: Ideally, we would also be able to look *past* the code-completion
1647 // token, in case we are code-completing in the middle of the switch and not
1648 // at the end. However, we aren't able to do so at the moment.
1649 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorf2510672009-09-21 19:57:38 +00001650 NestedNameSpecifier *Qualifier = 0;
Douglas Gregord328d572009-09-21 18:10:23 +00001651 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
1652 SC = SC->getNextSwitchCase()) {
1653 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
1654 if (!Case)
1655 continue;
1656
1657 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
1658 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
1659 if (EnumConstantDecl *Enumerator
1660 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
1661 // We look into the AST of the case statement to determine which
1662 // enumerator was named. Alternatively, we could compute the value of
1663 // the integral constant expression, then compare it against the
1664 // values of each enumerator. However, value-based approach would not
1665 // work as well with C++ templates where enumerators declared within a
1666 // template are type- and value-dependent.
1667 EnumeratorsSeen.insert(Enumerator);
1668
Douglas Gregorf2510672009-09-21 19:57:38 +00001669 // If this is a qualified-id, keep track of the nested-name-specifier
1670 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregord328d572009-09-21 18:10:23 +00001671 //
1672 // switch (TagD.getKind()) {
1673 // case TagDecl::TK_enum:
1674 // break;
1675 // case XXX
1676 //
Douglas Gregorf2510672009-09-21 19:57:38 +00001677 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregord328d572009-09-21 18:10:23 +00001678 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
1679 // TK_struct, and TK_class.
Douglas Gregor4bd90e52009-10-23 18:54:35 +00001680 Qualifier = DRE->getQualifier();
Douglas Gregord328d572009-09-21 18:10:23 +00001681 }
1682 }
1683
Douglas Gregorf2510672009-09-21 19:57:38 +00001684 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
1685 // If there are no prior enumerators in C++, check whether we have to
1686 // qualify the names of the enumerators that we suggest, because they
1687 // may not be visible in this scope.
1688 Qualifier = getRequiredQualification(Context, CurContext,
1689 Enum->getDeclContext());
1690
1691 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
1692 }
1693
Douglas Gregord328d572009-09-21 18:10:23 +00001694 // Add any enumerators that have not yet been mentioned.
1695 ResultBuilder Results(*this);
1696 Results.EnterNewScope();
1697 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
1698 EEnd = Enum->enumerator_end();
1699 E != EEnd; ++E) {
1700 if (EnumeratorsSeen.count(*E))
1701 continue;
1702
Douglas Gregorf2510672009-09-21 19:57:38 +00001703 Results.MaybeAddResult(CodeCompleteConsumer::Result(*E, 0, Qualifier));
Douglas Gregord328d572009-09-21 18:10:23 +00001704 }
1705 Results.ExitScope();
1706
Douglas Gregor9eb77012009-11-07 00:00:49 +00001707 if (CodeCompleter->includeMacros())
1708 AddMacroResults(PP, 1, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001709 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregord328d572009-09-21 18:10:23 +00001710}
1711
Douglas Gregorcabea402009-09-22 15:41:20 +00001712namespace {
1713 struct IsBetterOverloadCandidate {
1714 Sema &S;
1715
1716 public:
1717 explicit IsBetterOverloadCandidate(Sema &S) : S(S) { }
1718
1719 bool
1720 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
1721 return S.isBetterOverloadCandidate(X, Y);
1722 }
1723 };
1724}
1725
1726void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
1727 ExprTy **ArgsIn, unsigned NumArgs) {
1728 if (!CodeCompleter)
1729 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00001730
1731 // When we're code-completing for a call, we fall back to ordinary
1732 // name code-completion whenever we can't produce specific
1733 // results. We may want to revisit this strategy in the future,
1734 // e.g., by merging the two kinds of results.
1735
Douglas Gregorcabea402009-09-22 15:41:20 +00001736 Expr *Fn = (Expr *)FnIn;
1737 Expr **Args = (Expr **)ArgsIn;
Douglas Gregor3ef59522009-12-11 19:06:04 +00001738
Douglas Gregorcabea402009-09-22 15:41:20 +00001739 // Ignore type-dependent call expressions entirely.
1740 if (Fn->isTypeDependent() ||
Douglas Gregor3ef59522009-12-11 19:06:04 +00001741 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
1742 CodeCompleteOrdinaryName(S);
Douglas Gregorcabea402009-09-22 15:41:20 +00001743 return;
Douglas Gregor3ef59522009-12-11 19:06:04 +00001744 }
Douglas Gregorcabea402009-09-22 15:41:20 +00001745
John McCall57500772009-12-16 12:17:52 +00001746 // Build an overload candidate set based on the functions we find.
1747 OverloadCandidateSet CandidateSet;
1748
Douglas Gregorcabea402009-09-22 15:41:20 +00001749 // FIXME: What if we're calling something that isn't a function declaration?
1750 // FIXME: What if we're calling a pseudo-destructor?
1751 // FIXME: What if we're calling a member function?
1752
John McCall57500772009-12-16 12:17:52 +00001753 Expr *NakedFn = Fn->IgnoreParenCasts();
1754 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
1755 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
1756 /*PartialOverloading=*/ true);
1757 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
1758 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
1759 if (FDecl)
1760 AddOverloadCandidate(FDecl, Args, NumArgs, CandidateSet,
1761 false, false, /*PartialOverloading*/ true);
1762 }
Douglas Gregorcabea402009-09-22 15:41:20 +00001763
1764 // Sort the overload candidate set by placing the best overloads first.
1765 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
1766 IsBetterOverloadCandidate(*this));
1767
1768 // Add the remaining viable overload candidates as code-completion reslults.
Douglas Gregor05f477c2009-09-23 00:16:58 +00001769 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
1770 llvm::SmallVector<ResultCandidate, 8> Results;
Anders Carlssone7ceb852009-09-22 17:29:51 +00001771
Douglas Gregorcabea402009-09-22 15:41:20 +00001772 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
1773 CandEnd = CandidateSet.end();
1774 Cand != CandEnd; ++Cand) {
1775 if (Cand->Viable)
Douglas Gregor05f477c2009-09-23 00:16:58 +00001776 Results.push_back(ResultCandidate(Cand->Function));
Douglas Gregorcabea402009-09-22 15:41:20 +00001777 }
Douglas Gregor3ef59522009-12-11 19:06:04 +00001778
1779 if (Results.empty())
1780 CodeCompleteOrdinaryName(S);
1781 else
1782 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
1783 Results.size());
Douglas Gregorcabea402009-09-22 15:41:20 +00001784}
1785
Douglas Gregor2436e712009-09-17 21:32:03 +00001786void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
1787 bool EnteringContext) {
1788 if (!SS.getScopeRep() || !CodeCompleter)
1789 return;
1790
Douglas Gregor3545ff42009-09-21 16:56:56 +00001791 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
1792 if (!Ctx)
1793 return;
Douglas Gregor800f2f02009-12-11 18:28:39 +00001794
1795 // Try to instantiate any non-dependent declaration contexts before
1796 // we look in them.
1797 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
1798 return;
1799
Douglas Gregor3545ff42009-09-21 16:56:56 +00001800 ResultBuilder Results(*this);
Douglas Gregor2af2f672009-09-21 20:12:40 +00001801 unsigned NextRank = CollectMemberLookupResults(Ctx, 0, Ctx, Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001802
1803 // The "template" keyword can follow "::" in the grammar, but only
1804 // put it into the grammar if the nested-name-specifier is dependent.
1805 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
1806 if (!Results.empty() && NNS->isDependent())
1807 Results.MaybeAddResult(CodeCompleteConsumer::Result("template", NextRank));
1808
Douglas Gregor9eb77012009-11-07 00:00:49 +00001809 if (CodeCompleter->includeMacros())
1810 AddMacroResults(PP, NextRank + 1, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001811 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor2436e712009-09-17 21:32:03 +00001812}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00001813
1814void Sema::CodeCompleteUsing(Scope *S) {
1815 if (!CodeCompleter)
1816 return;
1817
Douglas Gregor3545ff42009-09-21 16:56:56 +00001818 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor64b12b52009-09-22 23:31:26 +00001819 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001820
1821 // If we aren't in class scope, we could see the "namespace" keyword.
1822 if (!S->isClassScope())
1823 Results.MaybeAddResult(CodeCompleteConsumer::Result("namespace", 0));
1824
1825 // After "using", we can see anything that would start a
1826 // nested-name-specifier.
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001827 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1828 0, CurContext, Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00001829 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001830
Douglas Gregor9eb77012009-11-07 00:00:49 +00001831 if (CodeCompleter->includeMacros())
1832 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001833 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00001834}
1835
1836void Sema::CodeCompleteUsingDirective(Scope *S) {
1837 if (!CodeCompleter)
1838 return;
1839
Douglas Gregor3545ff42009-09-21 16:56:56 +00001840 // After "using namespace", we expect to see a namespace name or namespace
1841 // alias.
1842 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor64b12b52009-09-22 23:31:26 +00001843 Results.EnterNewScope();
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001844 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1845 0, CurContext, Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00001846 Results.ExitScope();
Douglas Gregor9eb77012009-11-07 00:00:49 +00001847 if (CodeCompleter->includeMacros())
1848 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001849 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00001850}
1851
1852void Sema::CodeCompleteNamespaceDecl(Scope *S) {
1853 if (!CodeCompleter)
1854 return;
1855
Douglas Gregor3545ff42009-09-21 16:56:56 +00001856 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
1857 DeclContext *Ctx = (DeclContext *)S->getEntity();
1858 if (!S->getParent())
1859 Ctx = Context.getTranslationUnitDecl();
1860
1861 if (Ctx && Ctx->isFileContext()) {
1862 // We only want to see those namespaces that have already been defined
1863 // within this scope, because its likely that the user is creating an
1864 // extended namespace declaration. Keep track of the most recent
1865 // definition of each namespace.
1866 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
1867 for (DeclContext::specific_decl_iterator<NamespaceDecl>
1868 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
1869 NS != NSEnd; ++NS)
1870 OrigToLatest[NS->getOriginalNamespace()] = *NS;
1871
1872 // Add the most recent definition (or extended definition) of each
1873 // namespace to the list of results.
Douglas Gregor64b12b52009-09-22 23:31:26 +00001874 Results.EnterNewScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001875 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
1876 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
1877 NS != NSEnd; ++NS)
Douglas Gregor2af2f672009-09-21 20:12:40 +00001878 Results.MaybeAddResult(CodeCompleteConsumer::Result(NS->second, 0),
1879 CurContext);
Douglas Gregor64b12b52009-09-22 23:31:26 +00001880 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001881 }
1882
Douglas Gregor9eb77012009-11-07 00:00:49 +00001883 if (CodeCompleter->includeMacros())
1884 AddMacroResults(PP, 1, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001885 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00001886}
1887
1888void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
1889 if (!CodeCompleter)
1890 return;
1891
Douglas Gregor3545ff42009-09-21 16:56:56 +00001892 // After "namespace", we expect to see a namespace or alias.
1893 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001894 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1895 0, CurContext, Results);
Douglas Gregor9eb77012009-11-07 00:00:49 +00001896 if (CodeCompleter->includeMacros())
1897 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001898 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00001899}
1900
Douglas Gregorc811ede2009-09-18 20:05:18 +00001901void Sema::CodeCompleteOperatorName(Scope *S) {
1902 if (!CodeCompleter)
1903 return;
Douglas Gregor3545ff42009-09-21 16:56:56 +00001904
1905 typedef CodeCompleteConsumer::Result Result;
1906 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor64b12b52009-09-22 23:31:26 +00001907 Results.EnterNewScope();
Douglas Gregorc811ede2009-09-18 20:05:18 +00001908
Douglas Gregor3545ff42009-09-21 16:56:56 +00001909 // Add the names of overloadable operators.
1910#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
1911 if (std::strcmp(Spelling, "?")) \
1912 Results.MaybeAddResult(Result(Spelling, 0));
1913#include "clang/Basic/OperatorKinds.def"
1914
1915 // Add any type names visible from the current scope
1916 unsigned NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
Douglas Gregor2af2f672009-09-21 20:12:40 +00001917 0, CurContext, Results);
Douglas Gregor3545ff42009-09-21 16:56:56 +00001918
1919 // Add any type specifiers
1920 AddTypeSpecifierResults(getLangOptions(), 0, Results);
1921
1922 // Add any nested-name-specifiers
1923 Results.setFilter(&ResultBuilder::IsNestedNameSpecifier);
Douglas Gregorf329c7c2009-10-30 16:50:04 +00001924 NextRank = CollectLookupResults(S, Context.getTranslationUnitDecl(),
1925 NextRank + 1, CurContext, Results);
Douglas Gregor64b12b52009-09-22 23:31:26 +00001926 Results.ExitScope();
Douglas Gregor3545ff42009-09-21 16:56:56 +00001927
Douglas Gregor9eb77012009-11-07 00:00:49 +00001928 if (CodeCompleter->includeMacros())
1929 AddMacroResults(PP, NextRank, Results);
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00001930 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregorc811ede2009-09-18 20:05:18 +00001931}
Douglas Gregor7e90c6d2009-09-18 19:03:04 +00001932
Douglas Gregorf48706c2009-12-07 09:27:33 +00001933void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
1934 bool InInterface) {
1935 typedef CodeCompleteConsumer::Result Result;
1936 ResultBuilder Results(*this);
1937 Results.EnterNewScope();
1938 if (ObjCImpDecl) {
1939 // Since we have an implementation, we can end it.
1940 Results.MaybeAddResult(Result("end", 0));
1941
1942 CodeCompletionString *Pattern = 0;
1943 Decl *ImpDecl = ObjCImpDecl.getAs<Decl>();
1944 if (isa<ObjCImplementationDecl>(ImpDecl) ||
1945 isa<ObjCCategoryImplDecl>(ImpDecl)) {
1946 // @dynamic
1947 Pattern = new CodeCompletionString;
1948 Pattern->AddTypedTextChunk("dynamic");
1949 Pattern->AddTextChunk(" ");
1950 Pattern->AddPlaceholderChunk("property");
1951 Results.MaybeAddResult(Result(Pattern, 0));
1952
1953 // @synthesize
1954 Pattern = new CodeCompletionString;
1955 Pattern->AddTypedTextChunk("synthesize");
1956 Pattern->AddTextChunk(" ");
1957 Pattern->AddPlaceholderChunk("property");
1958 Results.MaybeAddResult(Result(Pattern, 0));
1959 }
1960 } else if (InInterface) {
1961 // Since we have an interface or protocol, we can end it.
1962 Results.MaybeAddResult(Result("end", 0));
1963
1964 if (LangOpts.ObjC2) {
1965 // @property
1966 Results.MaybeAddResult(Result("property", 0));
1967 }
1968
1969 // @required
1970 Results.MaybeAddResult(Result("required", 0));
1971
1972 // @optional
1973 Results.MaybeAddResult(Result("optional", 0));
1974 } else {
1975 CodeCompletionString *Pattern = 0;
1976
1977 // @class name ;
1978 Pattern = new CodeCompletionString;
1979 Pattern->AddTypedTextChunk("class");
1980 Pattern->AddTextChunk(" ");
1981 Pattern->AddPlaceholderChunk("identifier");
1982 Pattern->AddTextChunk(";"); // add ';' chunk
1983 Results.MaybeAddResult(Result(Pattern, 0));
1984
1985 // @interface name
1986 // FIXME: Could introduce the whole pattern, including superclasses and
1987 // such.
1988 Pattern = new CodeCompletionString;
1989 Pattern->AddTypedTextChunk("interface");
1990 Pattern->AddTextChunk(" ");
1991 Pattern->AddPlaceholderChunk("class");
1992 Results.MaybeAddResult(Result(Pattern, 0));
1993
1994 // @protocol name
1995 Pattern = new CodeCompletionString;
1996 Pattern->AddTypedTextChunk("protocol");
1997 Pattern->AddTextChunk(" ");
1998 Pattern->AddPlaceholderChunk("protocol");
1999 Results.MaybeAddResult(Result(Pattern, 0));
2000
2001 // @implementation name
2002 Pattern = new CodeCompletionString;
2003 Pattern->AddTypedTextChunk("implementation");
2004 Pattern->AddTextChunk(" ");
2005 Pattern->AddPlaceholderChunk("class");
2006 Results.MaybeAddResult(Result(Pattern, 0));
2007
2008 // @compatibility_alias name
2009 Pattern = new CodeCompletionString;
2010 Pattern->AddTypedTextChunk("compatibility_alias");
2011 Pattern->AddTextChunk(" ");
2012 Pattern->AddPlaceholderChunk("alias");
2013 Pattern->AddTextChunk(" ");
2014 Pattern->AddPlaceholderChunk("class");
2015 Results.MaybeAddResult(Result(Pattern, 0));
2016 }
2017 Results.ExitScope();
2018 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2019}
2020
Douglas Gregorbc7c5e42009-12-07 09:51:25 +00002021static void AddObjCExpressionResults(unsigned Rank, ResultBuilder &Results) {
2022 typedef CodeCompleteConsumer::Result Result;
2023 CodeCompletionString *Pattern = 0;
2024
2025 // @encode ( type-name )
2026 Pattern = new CodeCompletionString;
2027 Pattern->AddTypedTextChunk("encode");
2028 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2029 Pattern->AddPlaceholderChunk("type-name");
2030 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2031 Results.MaybeAddResult(Result(Pattern, Rank));
2032
2033 // @protocol ( protocol-name )
2034 Pattern = new CodeCompletionString;
2035 Pattern->AddTypedTextChunk("protocol");
2036 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2037 Pattern->AddPlaceholderChunk("protocol-name");
2038 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2039 Results.MaybeAddResult(Result(Pattern, Rank));
2040
2041 // @selector ( selector )
2042 Pattern = new CodeCompletionString;
2043 Pattern->AddTypedTextChunk("selector");
2044 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2045 Pattern->AddPlaceholderChunk("selector");
2046 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2047 Results.MaybeAddResult(Result(Pattern, Rank));
2048}
2049
2050void Sema::CodeCompleteObjCAtStatement(Scope *S) {
2051 typedef CodeCompleteConsumer::Result Result;
2052 ResultBuilder Results(*this);
2053 Results.EnterNewScope();
2054
2055 CodeCompletionString *Pattern = 0;
2056
2057 // @try { statements } @catch ( declaration ) { statements } @finally
2058 // { statements }
2059 Pattern = new CodeCompletionString;
2060 Pattern->AddTypedTextChunk("try");
2061 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2062 Pattern->AddPlaceholderChunk("statements");
2063 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2064 Pattern->AddTextChunk("@catch");
2065 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2066 Pattern->AddPlaceholderChunk("parameter");
2067 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2068 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2069 Pattern->AddPlaceholderChunk("statements");
2070 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2071 Pattern->AddTextChunk("@finally");
2072 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2073 Pattern->AddPlaceholderChunk("statements");
2074 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2075 Results.MaybeAddResult(Result(Pattern, 0));
2076
2077 // @throw
2078 Pattern = new CodeCompletionString;
2079 Pattern->AddTypedTextChunk("throw");
2080 Pattern->AddTextChunk(" ");
2081 Pattern->AddPlaceholderChunk("expression");
2082 Pattern->AddTextChunk(";");
2083 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2084
2085 // @synchronized ( expression ) { statements }
2086 Pattern = new CodeCompletionString;
2087 Pattern->AddTypedTextChunk("synchronized");
2088 Pattern->AddTextChunk(" ");
2089 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2090 Pattern->AddPlaceholderChunk("expression");
2091 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2092 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2093 Pattern->AddPlaceholderChunk("statements");
2094 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2095 Results.MaybeAddResult(Result(Pattern, 0)); // FIXME: add ';' chunk
2096
2097 AddObjCExpressionResults(0, Results);
2098 Results.ExitScope();
2099 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2100}
2101
2102void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2103 ResultBuilder Results(*this);
2104 Results.EnterNewScope();
2105 AddObjCExpressionResults(0, Results);
2106 Results.ExitScope();
2107 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2108}
2109
Douglas Gregore6078da2009-11-19 00:14:45 +00002110/// \brief Determine whether the addition of the given flag to an Objective-C
2111/// property's attributes will cause a conflict.
2112static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2113 // Check if we've already added this flag.
2114 if (Attributes & NewFlag)
2115 return true;
2116
2117 Attributes |= NewFlag;
2118
2119 // Check for collisions with "readonly".
2120 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2121 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2122 ObjCDeclSpec::DQ_PR_assign |
2123 ObjCDeclSpec::DQ_PR_copy |
2124 ObjCDeclSpec::DQ_PR_retain)))
2125 return true;
2126
2127 // Check for more than one of { assign, copy, retain }.
2128 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2129 ObjCDeclSpec::DQ_PR_copy |
2130 ObjCDeclSpec::DQ_PR_retain);
2131 if (AssignCopyRetMask &&
2132 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2133 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2134 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2135 return true;
2136
2137 return false;
2138}
2139
Douglas Gregor36029f42009-11-18 23:08:07 +00002140void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroff936354c2009-10-08 21:55:05 +00002141 if (!CodeCompleter)
2142 return;
Douglas Gregor1b605f72009-11-19 01:08:35 +00002143
Steve Naroff936354c2009-10-08 21:55:05 +00002144 unsigned Attributes = ODS.getPropertyAttributes();
2145
2146 typedef CodeCompleteConsumer::Result Result;
2147 ResultBuilder Results(*this);
2148 Results.EnterNewScope();
Douglas Gregore6078da2009-11-19 00:14:45 +00002149 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Steve Naroff936354c2009-10-08 21:55:05 +00002150 Results.MaybeAddResult(CodeCompleteConsumer::Result("readonly", 0));
Douglas Gregore6078da2009-11-19 00:14:45 +00002151 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Steve Naroff936354c2009-10-08 21:55:05 +00002152 Results.MaybeAddResult(CodeCompleteConsumer::Result("assign", 0));
Douglas Gregore6078da2009-11-19 00:14:45 +00002153 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Steve Naroff936354c2009-10-08 21:55:05 +00002154 Results.MaybeAddResult(CodeCompleteConsumer::Result("readwrite", 0));
Douglas Gregore6078da2009-11-19 00:14:45 +00002155 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Steve Naroff936354c2009-10-08 21:55:05 +00002156 Results.MaybeAddResult(CodeCompleteConsumer::Result("retain", 0));
Douglas Gregore6078da2009-11-19 00:14:45 +00002157 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Steve Naroff936354c2009-10-08 21:55:05 +00002158 Results.MaybeAddResult(CodeCompleteConsumer::Result("copy", 0));
Douglas Gregore6078da2009-11-19 00:14:45 +00002159 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Steve Naroff936354c2009-10-08 21:55:05 +00002160 Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic", 0));
Douglas Gregore6078da2009-11-19 00:14:45 +00002161 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002162 CodeCompletionString *Setter = new CodeCompletionString;
2163 Setter->AddTypedTextChunk("setter");
2164 Setter->AddTextChunk(" = ");
2165 Setter->AddPlaceholderChunk("method");
2166 Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter, 0));
2167 }
Douglas Gregore6078da2009-11-19 00:14:45 +00002168 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor45f83ee2009-11-19 00:01:57 +00002169 CodeCompletionString *Getter = new CodeCompletionString;
2170 Getter->AddTypedTextChunk("getter");
2171 Getter->AddTextChunk(" = ");
2172 Getter->AddPlaceholderChunk("method");
2173 Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter, 0));
2174 }
Steve Naroff936354c2009-10-08 21:55:05 +00002175 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002176 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroff936354c2009-10-08 21:55:05 +00002177}
Steve Naroffeae65032009-11-07 02:08:14 +00002178
Douglas Gregorc8537c52009-11-19 07:41:15 +00002179/// \brief Descripts the kind of Objective-C method that we want to find
2180/// via code completion.
2181enum ObjCMethodKind {
2182 MK_Any, //< Any kind of method, provided it means other specified criteria.
2183 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2184 MK_OneArgSelector //< One-argument selector.
2185};
2186
2187static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2188 ObjCMethodKind WantKind,
2189 IdentifierInfo **SelIdents,
2190 unsigned NumSelIdents) {
2191 Selector Sel = Method->getSelector();
2192 if (NumSelIdents > Sel.getNumArgs())
2193 return false;
2194
2195 switch (WantKind) {
2196 case MK_Any: break;
2197 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2198 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2199 }
2200
2201 for (unsigned I = 0; I != NumSelIdents; ++I)
2202 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2203 return false;
2204
2205 return true;
2206}
2207
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002208/// \brief Add all of the Objective-C methods in the given Objective-C
2209/// container to the set of results.
2210///
2211/// The container will be a class, protocol, category, or implementation of
2212/// any of the above. This mether will recurse to include methods from
2213/// the superclasses of classes along with their categories, protocols, and
2214/// implementations.
2215///
2216/// \param Container the container in which we'll look to find methods.
2217///
2218/// \param WantInstance whether to add instance methods (only); if false, this
2219/// routine will add factory methods (only).
2220///
2221/// \param CurContext the context in which we're performing the lookup that
2222/// finds methods.
2223///
2224/// \param Results the structure into which we'll add results.
2225static void AddObjCMethods(ObjCContainerDecl *Container,
2226 bool WantInstanceMethods,
Douglas Gregorc8537c52009-11-19 07:41:15 +00002227 ObjCMethodKind WantKind,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002228 IdentifierInfo **SelIdents,
2229 unsigned NumSelIdents,
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002230 DeclContext *CurContext,
2231 ResultBuilder &Results) {
2232 typedef CodeCompleteConsumer::Result Result;
2233 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2234 MEnd = Container->meth_end();
2235 M != MEnd; ++M) {
Douglas Gregor1b605f72009-11-19 01:08:35 +00002236 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2237 // Check whether the selector identifiers we've been given are a
2238 // subset of the identifiers for this particular method.
Douglas Gregorc8537c52009-11-19 07:41:15 +00002239 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregor1b605f72009-11-19 01:08:35 +00002240 continue;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002241
Douglas Gregor1b605f72009-11-19 01:08:35 +00002242 Result R = Result(*M, 0);
2243 R.StartParameter = NumSelIdents;
Douglas Gregorc8537c52009-11-19 07:41:15 +00002244 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregor1b605f72009-11-19 01:08:35 +00002245 Results.MaybeAddResult(R, CurContext);
2246 }
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002247 }
2248
2249 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2250 if (!IFace)
2251 return;
2252
2253 // Add methods in protocols.
2254 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2255 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2256 E = Protocols.end();
2257 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002258 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002259 CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002260
2261 // Add methods in categories.
2262 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2263 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregorc8537c52009-11-19 07:41:15 +00002264 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2265 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002266
2267 // Add a categories protocol methods.
2268 const ObjCList<ObjCProtocolDecl> &Protocols
2269 = CatDecl->getReferencedProtocols();
2270 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2271 E = Protocols.end();
2272 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002273 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2274 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002275
2276 // Add methods in category implementations.
2277 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002278 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2279 NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002280 }
2281
2282 // Add methods in superclass.
2283 if (IFace->getSuperClass())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002284 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2285 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002286
2287 // Add methods in our implementation, if any.
2288 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002289 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2290 NumSelIdents, CurContext, Results);
2291}
2292
2293
2294void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2295 DeclPtrTy *Methods,
2296 unsigned NumMethods) {
2297 typedef CodeCompleteConsumer::Result Result;
2298
2299 // Try to find the interface where getters might live.
2300 ObjCInterfaceDecl *Class
2301 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2302 if (!Class) {
2303 if (ObjCCategoryDecl *Category
2304 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2305 Class = Category->getClassInterface();
2306
2307 if (!Class)
2308 return;
2309 }
2310
2311 // Find all of the potential getters.
2312 ResultBuilder Results(*this);
2313 Results.EnterNewScope();
2314
2315 // FIXME: We need to do this because Objective-C methods don't get
2316 // pushed into DeclContexts early enough. Argh!
2317 for (unsigned I = 0; I != NumMethods; ++I) {
2318 if (ObjCMethodDecl *Method
2319 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2320 if (Method->isInstanceMethod() &&
2321 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2322 Result R = Result(Method, 0);
2323 R.AllParametersAreInformative = true;
2324 Results.MaybeAddResult(R, CurContext);
2325 }
2326 }
2327
2328 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2329 Results.ExitScope();
2330 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2331}
2332
2333void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2334 DeclPtrTy *Methods,
2335 unsigned NumMethods) {
2336 typedef CodeCompleteConsumer::Result Result;
2337
2338 // Try to find the interface where setters might live.
2339 ObjCInterfaceDecl *Class
2340 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2341 if (!Class) {
2342 if (ObjCCategoryDecl *Category
2343 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2344 Class = Category->getClassInterface();
2345
2346 if (!Class)
2347 return;
2348 }
2349
2350 // Find all of the potential getters.
2351 ResultBuilder Results(*this);
2352 Results.EnterNewScope();
2353
2354 // FIXME: We need to do this because Objective-C methods don't get
2355 // pushed into DeclContexts early enough. Argh!
2356 for (unsigned I = 0; I != NumMethods; ++I) {
2357 if (ObjCMethodDecl *Method
2358 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2359 if (Method->isInstanceMethod() &&
2360 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2361 Result R = Result(Method, 0);
2362 R.AllParametersAreInformative = true;
2363 Results.MaybeAddResult(R, CurContext);
2364 }
2365 }
2366
2367 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2368
2369 Results.ExitScope();
2370 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002371}
2372
Douglas Gregor090dd182009-11-17 23:31:36 +00002373void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregor1b605f72009-11-19 01:08:35 +00002374 SourceLocation FNameLoc,
2375 IdentifierInfo **SelIdents,
2376 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00002377 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor8ce33212009-11-17 17:59:40 +00002378 ObjCInterfaceDecl *CDecl = 0;
2379
Douglas Gregor8ce33212009-11-17 17:59:40 +00002380 if (FName->isStr("super")) {
2381 // We're sending a message to "super".
2382 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2383 // Figure out which interface we're in.
2384 CDecl = CurMethod->getClassInterface();
2385 if (!CDecl)
2386 return;
2387
2388 // Find the superclass of this class.
2389 CDecl = CDecl->getSuperClass();
2390 if (!CDecl)
2391 return;
2392
2393 if (CurMethod->isInstanceMethod()) {
2394 // We are inside an instance method, which means that the message
2395 // send [super ...] is actually calling an instance method on the
2396 // current object. Build the super expression and handle this like
2397 // an instance method.
2398 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2399 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2400 OwningExprResult Super
Douglas Gregor090dd182009-11-17 23:31:36 +00002401 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregor1b605f72009-11-19 01:08:35 +00002402 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2403 SelIdents, NumSelIdents);
Douglas Gregor8ce33212009-11-17 17:59:40 +00002404 }
2405
2406 // Okay, we're calling a factory method in our superclass.
2407 }
2408 }
2409
2410 // If the given name refers to an interface type, retrieve the
2411 // corresponding declaration.
2412 if (!CDecl)
Douglas Gregor090dd182009-11-17 23:31:36 +00002413 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor8ce33212009-11-17 17:59:40 +00002414 QualType T = GetTypeFromParser(Ty, 0);
2415 if (!T.isNull())
2416 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
2417 CDecl = Interface->getDecl();
2418 }
2419
2420 if (!CDecl && FName->isStr("super")) {
2421 // "super" may be the name of a variable, in which case we are
2422 // probably calling an instance method.
John McCalle66edc12009-11-24 19:00:30 +00002423 CXXScopeSpec SS;
2424 UnqualifiedId id;
2425 id.setIdentifier(FName, FNameLoc);
2426 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregor1b605f72009-11-19 01:08:35 +00002427 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2428 SelIdents, NumSelIdents);
Douglas Gregor8ce33212009-11-17 17:59:40 +00002429 }
2430
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002431 // Add all of the factory methods in this Objective-C class, its protocols,
2432 // superclasses, categories, implementation, etc.
Steve Naroffeae65032009-11-07 02:08:14 +00002433 ResultBuilder Results(*this);
2434 Results.EnterNewScope();
Douglas Gregorc8537c52009-11-19 07:41:15 +00002435 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
2436 Results);
Steve Naroffeae65032009-11-07 02:08:14 +00002437 Results.ExitScope();
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002438
Steve Naroffeae65032009-11-07 02:08:14 +00002439 // This also suppresses remaining diagnostics.
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002440 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00002441}
2442
Douglas Gregor1b605f72009-11-19 01:08:35 +00002443void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
2444 IdentifierInfo **SelIdents,
2445 unsigned NumSelIdents) {
Steve Naroffeae65032009-11-07 02:08:14 +00002446 typedef CodeCompleteConsumer::Result Result;
Steve Naroffeae65032009-11-07 02:08:14 +00002447
2448 Expr *RecExpr = static_cast<Expr *>(Receiver);
2449 QualType RecType = RecExpr->getType();
2450
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002451 // If necessary, apply function/array conversion to the receiver.
2452 // C99 6.7.5.3p[7,8].
2453 DefaultFunctionArrayConversion(RecExpr);
2454 QualType ReceiverType = RecExpr->getType();
Steve Naroffeae65032009-11-07 02:08:14 +00002455
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002456 if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType()) {
2457 // FIXME: We're messaging 'id'. Do we actually want to look up every method
2458 // in the universe?
2459 return;
2460 }
2461
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002462 // Build the set of methods we can see.
2463 ResultBuilder Results(*this);
2464 Results.EnterNewScope();
Douglas Gregorbab2b3c2009-11-17 23:22:23 +00002465
Douglas Gregora3329fa2009-11-18 00:06:18 +00002466 // Handle messages to Class. This really isn't a message to an instance
2467 // method, so we treat it the same way we would treat a message send to a
2468 // class method.
2469 if (ReceiverType->isObjCClassType() ||
2470 ReceiverType->isObjCQualifiedClassType()) {
2471 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2472 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregorc8537c52009-11-19 07:41:15 +00002473 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
2474 CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00002475 }
2476 }
2477 // Handle messages to a qualified ID ("id<foo>").
2478 else if (const ObjCObjectPointerType *QualID
2479 = ReceiverType->getAsObjCQualifiedIdType()) {
2480 // Search protocols for instance methods.
2481 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
2482 E = QualID->qual_end();
2483 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002484 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2485 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00002486 }
2487 // Handle messages to a pointer to interface type.
2488 else if (const ObjCObjectPointerType *IFacePtr
2489 = ReceiverType->getAsObjCInterfacePointerType()) {
2490 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregorc8537c52009-11-19 07:41:15 +00002491 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
2492 NumSelIdents, CurContext, Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00002493
2494 // Search protocols for instance methods.
2495 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
2496 E = IFacePtr->qual_end();
2497 I != E; ++I)
Douglas Gregorc8537c52009-11-19 07:41:15 +00002498 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
2499 Results);
Douglas Gregora3329fa2009-11-18 00:06:18 +00002500 }
2501
Steve Naroffeae65032009-11-07 02:08:14 +00002502 Results.ExitScope();
Daniel Dunbar242ea9a2009-11-13 08:58:20 +00002503 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffeae65032009-11-07 02:08:14 +00002504}
Douglas Gregorbaf69612009-11-18 04:19:12 +00002505
2506/// \brief Add all of the protocol declarations that we find in the given
2507/// (translation unit) context.
2508static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor5b4671c2009-11-18 04:49:41 +00002509 bool OnlyForwardDeclarations,
Douglas Gregorbaf69612009-11-18 04:19:12 +00002510 ResultBuilder &Results) {
2511 typedef CodeCompleteConsumer::Result Result;
2512
2513 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2514 DEnd = Ctx->decls_end();
2515 D != DEnd; ++D) {
2516 // Record any protocols we find.
2517 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor5b4671c2009-11-18 04:49:41 +00002518 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
2519 Results.MaybeAddResult(Result(Proto, 0), CurContext);
Douglas Gregorbaf69612009-11-18 04:19:12 +00002520
2521 // Record any forward-declared protocols we find.
2522 if (ObjCForwardProtocolDecl *Forward
2523 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
2524 for (ObjCForwardProtocolDecl::protocol_iterator
2525 P = Forward->protocol_begin(),
2526 PEnd = Forward->protocol_end();
2527 P != PEnd; ++P)
Douglas Gregor5b4671c2009-11-18 04:49:41 +00002528 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
2529 Results.MaybeAddResult(Result(*P, 0), CurContext);
Douglas Gregorbaf69612009-11-18 04:19:12 +00002530 }
2531 }
2532}
2533
2534void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
2535 unsigned NumProtocols) {
2536 ResultBuilder Results(*this);
2537 Results.EnterNewScope();
2538
2539 // Tell the result set to ignore all of the protocols we have
2540 // already seen.
2541 for (unsigned I = 0; I != NumProtocols; ++I)
2542 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
2543 Results.Ignore(Protocol);
2544
2545 // Add all protocols.
Douglas Gregor5b4671c2009-11-18 04:49:41 +00002546 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
2547 Results);
2548
2549 Results.ExitScope();
2550 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2551}
2552
2553void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
2554 ResultBuilder Results(*this);
2555 Results.EnterNewScope();
2556
2557 // Add all protocols.
2558 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
2559 Results);
Douglas Gregorbaf69612009-11-18 04:19:12 +00002560
2561 Results.ExitScope();
2562 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2563}
Douglas Gregor49c22a72009-11-18 16:26:39 +00002564
2565/// \brief Add all of the Objective-C interface declarations that we find in
2566/// the given (translation unit) context.
2567static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
2568 bool OnlyForwardDeclarations,
2569 bool OnlyUnimplemented,
2570 ResultBuilder &Results) {
2571 typedef CodeCompleteConsumer::Result Result;
2572
2573 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
2574 DEnd = Ctx->decls_end();
2575 D != DEnd; ++D) {
2576 // Record any interfaces we find.
2577 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
2578 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
2579 (!OnlyUnimplemented || !Class->getImplementation()))
2580 Results.MaybeAddResult(Result(Class, 0), CurContext);
2581
2582 // Record any forward-declared interfaces we find.
2583 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
2584 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
2585 C != CEnd; ++C)
2586 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
2587 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
2588 Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
2589 }
2590 }
2591}
2592
2593void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
2594 ResultBuilder Results(*this);
2595 Results.EnterNewScope();
2596
2597 // Add all classes.
2598 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
2599 false, Results);
2600
2601 Results.ExitScope();
2602 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2603}
2604
2605void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
2606 ResultBuilder Results(*this);
2607 Results.EnterNewScope();
2608
2609 // Make sure that we ignore the class we're currently defining.
2610 NamedDecl *CurClass
2611 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor5d34fd32009-11-18 19:08:43 +00002612 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor49c22a72009-11-18 16:26:39 +00002613 Results.Ignore(CurClass);
2614
2615 // Add all classes.
2616 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2617 false, Results);
2618
2619 Results.ExitScope();
2620 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2621}
2622
2623void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
2624 ResultBuilder Results(*this);
2625 Results.EnterNewScope();
2626
2627 // Add all unimplemented classes.
2628 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
2629 true, Results);
2630
2631 Results.ExitScope();
2632 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2633}
Douglas Gregor5d34fd32009-11-18 19:08:43 +00002634
2635void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
2636 IdentifierInfo *ClassName) {
2637 typedef CodeCompleteConsumer::Result Result;
2638
2639 ResultBuilder Results(*this);
2640
2641 // Ignore any categories we find that have already been implemented by this
2642 // interface.
2643 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2644 NamedDecl *CurClass
2645 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2646 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
2647 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2648 Category = Category->getNextClassCategory())
2649 CategoryNames.insert(Category->getIdentifier());
2650
2651 // Add all of the categories we know about.
2652 Results.EnterNewScope();
2653 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
2654 for (DeclContext::decl_iterator D = TU->decls_begin(),
2655 DEnd = TU->decls_end();
2656 D != DEnd; ++D)
2657 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
2658 if (CategoryNames.insert(Category->getIdentifier()))
2659 Results.MaybeAddResult(Result(Category, 0), CurContext);
2660 Results.ExitScope();
2661
2662 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2663}
2664
2665void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
2666 IdentifierInfo *ClassName) {
2667 typedef CodeCompleteConsumer::Result Result;
2668
2669 // Find the corresponding interface. If we couldn't find the interface, the
2670 // program itself is ill-formed. However, we'll try to be helpful still by
2671 // providing the list of all of the categories we know about.
2672 NamedDecl *CurClass
2673 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
2674 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
2675 if (!Class)
2676 return CodeCompleteObjCInterfaceCategory(S, ClassName);
2677
2678 ResultBuilder Results(*this);
2679
2680 // Add all of the categories that have have corresponding interface
2681 // declarations in this class and any of its superclasses, except for
2682 // already-implemented categories in the class itself.
2683 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
2684 Results.EnterNewScope();
2685 bool IgnoreImplemented = true;
2686 while (Class) {
2687 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
2688 Category = Category->getNextClassCategory())
2689 if ((!IgnoreImplemented || !Category->getImplementation()) &&
2690 CategoryNames.insert(Category->getIdentifier()))
2691 Results.MaybeAddResult(Result(Category, 0), CurContext);
2692
2693 Class = Class->getSuperClass();
2694 IgnoreImplemented = false;
2695 }
2696 Results.ExitScope();
2697
2698 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2699}
Douglas Gregor5d649882009-11-18 22:32:06 +00002700
Douglas Gregor52e78bd2009-11-18 22:56:13 +00002701void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor5d649882009-11-18 22:32:06 +00002702 typedef CodeCompleteConsumer::Result Result;
2703 ResultBuilder Results(*this);
2704
2705 // Figure out where this @synthesize lives.
2706 ObjCContainerDecl *Container
2707 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2708 if (!Container ||
2709 (!isa<ObjCImplementationDecl>(Container) &&
2710 !isa<ObjCCategoryImplDecl>(Container)))
2711 return;
2712
2713 // Ignore any properties that have already been implemented.
2714 for (DeclContext::decl_iterator D = Container->decls_begin(),
2715 DEnd = Container->decls_end();
2716 D != DEnd; ++D)
2717 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
2718 Results.Ignore(PropertyImpl->getPropertyDecl());
2719
2720 // Add any properties that we find.
2721 Results.EnterNewScope();
2722 if (ObjCImplementationDecl *ClassImpl
2723 = dyn_cast<ObjCImplementationDecl>(Container))
2724 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
2725 Results);
2726 else
2727 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
2728 false, CurContext, Results);
2729 Results.ExitScope();
2730
2731 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2732}
2733
2734void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
2735 IdentifierInfo *PropertyName,
2736 DeclPtrTy ObjCImpDecl) {
2737 typedef CodeCompleteConsumer::Result Result;
2738 ResultBuilder Results(*this);
2739
2740 // Figure out where this @synthesize lives.
2741 ObjCContainerDecl *Container
2742 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
2743 if (!Container ||
2744 (!isa<ObjCImplementationDecl>(Container) &&
2745 !isa<ObjCCategoryImplDecl>(Container)))
2746 return;
2747
2748 // Figure out which interface we're looking into.
2749 ObjCInterfaceDecl *Class = 0;
2750 if (ObjCImplementationDecl *ClassImpl
2751 = dyn_cast<ObjCImplementationDecl>(Container))
2752 Class = ClassImpl->getClassInterface();
2753 else
2754 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
2755 ->getClassInterface();
2756
2757 // Add all of the instance variables in this class and its superclasses.
2758 Results.EnterNewScope();
2759 for(; Class; Class = Class->getSuperClass()) {
2760 // FIXME: We could screen the type of each ivar for compatibility with
2761 // the property, but is that being too paternal?
2762 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
2763 IVarEnd = Class->ivar_end();
2764 IVar != IVarEnd; ++IVar)
2765 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
2766 }
2767 Results.ExitScope();
2768
2769 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2770}