blob: f7f5fe3b4dde27d36b439f79607abd8a2fe82c0d [file] [log] [blame]
Douglas Gregor81b747b2009-09-17 21:32:03 +00001//===---------------- SemaCodeComplete.cpp - Code Completion ----*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines the code-completion semantic actions.
11//
12//===----------------------------------------------------------------------===//
13#include "Sema.h"
Douglas Gregor1ca6ae82010-01-14 01:09:38 +000014#include "Lookup.h"
Douglas Gregor81b747b2009-09-17 21:32:03 +000015#include "clang/Sema/CodeCompleteConsumer.h"
Douglas Gregorb9d0ef72009-09-21 19:57:38 +000016#include "clang/AST/ExprCXX.h"
Douglas Gregor24a069f2009-11-17 17:59:40 +000017#include "clang/AST/ExprObjC.h"
Douglas Gregor3f7c7f42009-10-30 16:50:04 +000018#include "clang/Lex/MacroInfo.h"
19#include "clang/Lex/Preprocessor.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000020#include "llvm/ADT/SmallPtrSet.h"
Douglas Gregor6a684032009-09-28 03:51:44 +000021#include "llvm/ADT/StringExtras.h"
Douglas Gregor86d9a522009-09-21 16:56:56 +000022#include <list>
23#include <map>
24#include <vector>
Douglas Gregor81b747b2009-09-17 21:32:03 +000025
26using namespace clang;
27
Douglas Gregor86d9a522009-09-21 16:56:56 +000028namespace {
29 /// \brief A container of code-completion results.
30 class ResultBuilder {
31 public:
32 /// \brief The type of a name-lookup filter, which can be provided to the
33 /// name-lookup routines to specify which declarations should be included in
34 /// the result set (when it returns true) and which declarations should be
35 /// filtered out (returns false).
36 typedef bool (ResultBuilder::*LookupFilter)(NamedDecl *) const;
37
38 typedef CodeCompleteConsumer::Result Result;
39
40 private:
41 /// \brief The actual results we have found.
42 std::vector<Result> Results;
43
44 /// \brief A record of all of the declarations we have found and placed
45 /// into the result set, used to ensure that no declaration ever gets into
46 /// the result set twice.
47 llvm::SmallPtrSet<Decl*, 16> AllDeclsFound;
48
Douglas Gregorfbcb5d62009-12-06 20:23:50 +000049 typedef std::pair<NamedDecl *, unsigned> DeclIndexPair;
50
51 /// \brief An entry in the shadow map, which is optimized to store
52 /// a single (declaration, index) mapping (the common case) but
53 /// can also store a list of (declaration, index) mappings.
54 class ShadowMapEntry {
55 typedef llvm::SmallVector<DeclIndexPair, 4> DeclIndexPairVector;
56
57 /// \brief Contains either the solitary NamedDecl * or a vector
58 /// of (declaration, index) pairs.
59 llvm::PointerUnion<NamedDecl *, DeclIndexPairVector*> DeclOrVector;
60
61 /// \brief When the entry contains a single declaration, this is
62 /// the index associated with that entry.
63 unsigned SingleDeclIndex;
64
65 public:
66 ShadowMapEntry() : DeclOrVector(), SingleDeclIndex(0) { }
67
68 void Add(NamedDecl *ND, unsigned Index) {
69 if (DeclOrVector.isNull()) {
70 // 0 - > 1 elements: just set the single element information.
71 DeclOrVector = ND;
72 SingleDeclIndex = Index;
73 return;
74 }
75
76 if (NamedDecl *PrevND = DeclOrVector.dyn_cast<NamedDecl *>()) {
77 // 1 -> 2 elements: create the vector of results and push in the
78 // existing declaration.
79 DeclIndexPairVector *Vec = new DeclIndexPairVector;
80 Vec->push_back(DeclIndexPair(PrevND, SingleDeclIndex));
81 DeclOrVector = Vec;
82 }
83
84 // Add the new element to the end of the vector.
85 DeclOrVector.get<DeclIndexPairVector*>()->push_back(
86 DeclIndexPair(ND, Index));
87 }
88
89 void Destroy() {
90 if (DeclIndexPairVector *Vec
91 = DeclOrVector.dyn_cast<DeclIndexPairVector *>()) {
92 delete Vec;
93 DeclOrVector = ((NamedDecl *)0);
94 }
95 }
96
97 // Iteration.
98 class iterator;
99 iterator begin() const;
100 iterator end() const;
101 };
102
Douglas Gregor86d9a522009-09-21 16:56:56 +0000103 /// \brief A mapping from declaration names to the declarations that have
104 /// this name within a particular scope and their index within the list of
105 /// results.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000106 typedef llvm::DenseMap<DeclarationName, ShadowMapEntry> ShadowMap;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000107
108 /// \brief The semantic analysis object for which results are being
109 /// produced.
110 Sema &SemaRef;
111
112 /// \brief If non-NULL, a filter function used to remove any code-completion
113 /// results that are not desirable.
114 LookupFilter Filter;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000115
116 /// \brief Whether we should allow declarations as
117 /// nested-name-specifiers that would otherwise be filtered out.
118 bool AllowNestedNameSpecifiers;
119
Douglas Gregor86d9a522009-09-21 16:56:56 +0000120 /// \brief A list of shadow maps, which is used to model name hiding at
121 /// different levels of, e.g., the inheritance hierarchy.
122 std::list<ShadowMap> ShadowMaps;
123
124 public:
125 explicit ResultBuilder(Sema &SemaRef, LookupFilter Filter = 0)
Douglas Gregor45bcd432010-01-14 03:21:49 +0000126 : SemaRef(SemaRef), Filter(Filter), AllowNestedNameSpecifiers(false) { }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000127
128 /// \brief Set the filter used for code-completion results.
129 void setFilter(LookupFilter Filter) {
130 this->Filter = Filter;
131 }
132
133 typedef std::vector<Result>::iterator iterator;
134 iterator begin() { return Results.begin(); }
135 iterator end() { return Results.end(); }
136
137 Result *data() { return Results.empty()? 0 : &Results.front(); }
138 unsigned size() const { return Results.size(); }
139 bool empty() const { return Results.empty(); }
140
Douglas Gregor45bcd432010-01-14 03:21:49 +0000141 /// \brief Specify whether nested-name-specifiers are allowed.
142 void allowNestedNameSpecifiers(bool Allow = true) {
143 AllowNestedNameSpecifiers = Allow;
144 }
145
Douglas Gregore495b7f2010-01-14 00:20:49 +0000146 /// \brief Determine whether the given declaration is at all interesting
147 /// as a code-completion result.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000148 ///
149 /// \param ND the declaration that we are inspecting.
150 ///
151 /// \param AsNestedNameSpecifier will be set true if this declaration is
152 /// only interesting when it is a nested-name-specifier.
153 bool isInterestingDecl(NamedDecl *ND, bool &AsNestedNameSpecifier) const;
Douglas Gregor6660d842010-01-14 00:41:07 +0000154
155 /// \brief Check whether the result is hidden by the Hiding declaration.
156 ///
157 /// \returns true if the result is hidden and cannot be found, false if
158 /// the hidden result could still be found. When false, \p R may be
159 /// modified to describe how the result can be found (e.g., via extra
160 /// qualification).
161 bool CheckHiddenResult(Result &R, DeclContext *CurContext,
162 NamedDecl *Hiding);
163
Douglas Gregor86d9a522009-09-21 16:56:56 +0000164 /// \brief Add a new result to this result set (if it isn't already in one
165 /// of the shadow maps), or replace an existing result (for, e.g., a
166 /// redeclaration).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000167 ///
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000168 /// \param CurContext the result to add (if it is unique).
Douglas Gregor456c4a12009-09-21 20:12:40 +0000169 ///
170 /// \param R the context in which this result will be named.
171 void MaybeAddResult(Result R, DeclContext *CurContext = 0);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000172
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000173 /// \brief Add a new result to this result set, where we already know
174 /// the hiding declation (if any).
175 ///
176 /// \param R the result to add (if it is unique).
177 ///
178 /// \param CurContext the context in which this result will be named.
179 ///
180 /// \param Hiding the declaration that hides the result.
181 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding);
182
Douglas Gregor86d9a522009-09-21 16:56:56 +0000183 /// \brief Enter into a new scope.
184 void EnterNewScope();
185
186 /// \brief Exit from the current scope.
187 void ExitScope();
188
Douglas Gregor55385fe2009-11-18 04:19:12 +0000189 /// \brief Ignore this declaration, if it is seen again.
190 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
191
Douglas Gregor86d9a522009-09-21 16:56:56 +0000192 /// \name Name lookup predicates
193 ///
194 /// These predicates can be passed to the name lookup functions to filter the
195 /// results of name lookup. All of the predicates have the same type, so that
196 ///
197 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000198 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000199 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000200 bool IsNestedNameSpecifier(NamedDecl *ND) const;
201 bool IsEnum(NamedDecl *ND) const;
202 bool IsClassOrStruct(NamedDecl *ND) const;
203 bool IsUnion(NamedDecl *ND) const;
204 bool IsNamespace(NamedDecl *ND) const;
205 bool IsNamespaceOrAlias(NamedDecl *ND) const;
206 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000207 bool IsMember(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000208 //@}
209 };
210}
211
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000212class ResultBuilder::ShadowMapEntry::iterator {
213 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
214 unsigned SingleDeclIndex;
215
216public:
217 typedef DeclIndexPair value_type;
218 typedef value_type reference;
219 typedef std::ptrdiff_t difference_type;
220 typedef std::input_iterator_tag iterator_category;
221
222 class pointer {
223 DeclIndexPair Value;
224
225 public:
226 pointer(const DeclIndexPair &Value) : Value(Value) { }
227
228 const DeclIndexPair *operator->() const {
229 return &Value;
230 }
231 };
232
233 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
234
235 iterator(NamedDecl *SingleDecl, unsigned Index)
236 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
237
238 iterator(const DeclIndexPair *Iterator)
239 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
240
241 iterator &operator++() {
242 if (DeclOrIterator.is<NamedDecl *>()) {
243 DeclOrIterator = (NamedDecl *)0;
244 SingleDeclIndex = 0;
245 return *this;
246 }
247
248 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
249 ++I;
250 DeclOrIterator = I;
251 return *this;
252 }
253
254 iterator operator++(int) {
255 iterator tmp(*this);
256 ++(*this);
257 return tmp;
258 }
259
260 reference operator*() const {
261 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
262 return reference(ND, SingleDeclIndex);
263
Douglas Gregord490f952009-12-06 21:27:58 +0000264 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000265 }
266
267 pointer operator->() const {
268 return pointer(**this);
269 }
270
271 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000272 return X.DeclOrIterator.getOpaqueValue()
273 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000274 X.SingleDeclIndex == Y.SingleDeclIndex;
275 }
276
277 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000278 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000279 }
280};
281
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000282ResultBuilder::ShadowMapEntry::iterator
283ResultBuilder::ShadowMapEntry::begin() const {
284 if (DeclOrVector.isNull())
285 return iterator();
286
287 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
288 return iterator(ND, SingleDeclIndex);
289
290 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
291}
292
293ResultBuilder::ShadowMapEntry::iterator
294ResultBuilder::ShadowMapEntry::end() const {
295 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
296 return iterator();
297
298 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
299}
300
Douglas Gregor456c4a12009-09-21 20:12:40 +0000301/// \brief Compute the qualification required to get from the current context
302/// (\p CurContext) to the target context (\p TargetContext).
303///
304/// \param Context the AST context in which the qualification will be used.
305///
306/// \param CurContext the context where an entity is being named, which is
307/// typically based on the current scope.
308///
309/// \param TargetContext the context in which the named entity actually
310/// resides.
311///
312/// \returns a nested name specifier that refers into the target context, or
313/// NULL if no qualification is needed.
314static NestedNameSpecifier *
315getRequiredQualification(ASTContext &Context,
316 DeclContext *CurContext,
317 DeclContext *TargetContext) {
318 llvm::SmallVector<DeclContext *, 4> TargetParents;
319
320 for (DeclContext *CommonAncestor = TargetContext;
321 CommonAncestor && !CommonAncestor->Encloses(CurContext);
322 CommonAncestor = CommonAncestor->getLookupParent()) {
323 if (CommonAncestor->isTransparentContext() ||
324 CommonAncestor->isFunctionOrMethod())
325 continue;
326
327 TargetParents.push_back(CommonAncestor);
328 }
329
330 NestedNameSpecifier *Result = 0;
331 while (!TargetParents.empty()) {
332 DeclContext *Parent = TargetParents.back();
333 TargetParents.pop_back();
334
335 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
336 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
337 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
338 Result = NestedNameSpecifier::Create(Context, Result,
339 false,
340 Context.getTypeDeclType(TD).getTypePtr());
341 else
342 assert(Parent->isTranslationUnit());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000343 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000344 return Result;
345}
346
Douglas Gregor45bcd432010-01-14 03:21:49 +0000347bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
348 bool &AsNestedNameSpecifier) const {
349 AsNestedNameSpecifier = false;
350
Douglas Gregore495b7f2010-01-14 00:20:49 +0000351 ND = ND->getUnderlyingDecl();
352 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000353
354 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000355 if (!ND->getDeclName())
356 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000357
358 // Friend declarations and declarations introduced due to friends are never
359 // added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000360 if (isa<FriendDecl>(ND) ||
Douglas Gregor86d9a522009-09-21 16:56:56 +0000361 (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend)))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000362 return false;
363
Douglas Gregor76282942009-12-11 17:31:05 +0000364 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000365 if (isa<ClassTemplateSpecializationDecl>(ND) ||
366 isa<ClassTemplatePartialSpecializationDecl>(ND))
367 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000368
Douglas Gregor76282942009-12-11 17:31:05 +0000369 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000370 if (isa<UsingDecl>(ND))
371 return false;
372
373 // Some declarations have reserved names that we don't want to ever show.
374 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000375 // __va_list_tag is a freak of nature. Find it and skip it.
376 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000377 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000378
Douglas Gregorf52cede2009-10-09 22:16:47 +0000379 // Filter out names reserved for the implementation (C99 7.1.3,
380 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbare013d682009-10-18 20:26:12 +0000381 //
382 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000383 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000384 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000385 if (Name[0] == '_' &&
386 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000387 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000388 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000389 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000390
Douglas Gregor86d9a522009-09-21 16:56:56 +0000391 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000392 if (isa<CXXConstructorDecl>(ND))
393 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000394
395 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000396 if (Filter && !(this->*Filter)(ND)) {
397 // Check whether it is interesting as a nested-name-specifier.
398 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
399 IsNestedNameSpecifier(ND) &&
400 (Filter != &ResultBuilder::IsMember ||
401 (isa<CXXRecordDecl>(ND) &&
402 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
403 AsNestedNameSpecifier = true;
404 return true;
405 }
406
Douglas Gregore495b7f2010-01-14 00:20:49 +0000407 return false;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000408 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000409
Douglas Gregore495b7f2010-01-14 00:20:49 +0000410 // ... then it must be interesting!
411 return true;
412}
413
Douglas Gregor6660d842010-01-14 00:41:07 +0000414bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
415 NamedDecl *Hiding) {
416 // In C, there is no way to refer to a hidden name.
417 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
418 // name if we introduce the tag type.
419 if (!SemaRef.getLangOptions().CPlusPlus)
420 return true;
421
422 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
423
424 // There is no way to qualify a name declared in a function or method.
425 if (HiddenCtx->isFunctionOrMethod())
426 return true;
427
428 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
429 return true;
430
431 // We can refer to the result with the appropriate qualification. Do it.
432 R.Hidden = true;
433 R.QualifierIsInformative = false;
434
435 if (!R.Qualifier)
436 R.Qualifier = getRequiredQualification(SemaRef.Context,
437 CurContext,
438 R.Declaration->getDeclContext());
439 return false;
440}
441
Douglas Gregore495b7f2010-01-14 00:20:49 +0000442void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
443 assert(!ShadowMaps.empty() && "Must enter into a results scope");
444
445 if (R.Kind != Result::RK_Declaration) {
446 // For non-declaration results, just add the result.
447 Results.push_back(R);
448 return;
449 }
450
451 // Look through using declarations.
452 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
453 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
454 return;
455 }
456
457 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
458 unsigned IDNS = CanonDecl->getIdentifierNamespace();
459
Douglas Gregor45bcd432010-01-14 03:21:49 +0000460 bool AsNestedNameSpecifier = false;
461 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000462 return;
463
Douglas Gregor86d9a522009-09-21 16:56:56 +0000464 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000465 ShadowMapEntry::iterator I, IEnd;
466 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
467 if (NamePos != SMap.end()) {
468 I = NamePos->second.begin();
469 IEnd = NamePos->second.end();
470 }
471
472 for (; I != IEnd; ++I) {
473 NamedDecl *ND = I->first;
474 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000475 if (ND->getCanonicalDecl() == CanonDecl) {
476 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000477 Results[Index].Declaration = R.Declaration;
478
Douglas Gregor86d9a522009-09-21 16:56:56 +0000479 // We're done.
480 return;
481 }
482 }
483
484 // This is a new declaration in this scope. However, check whether this
485 // declaration name is hidden by a similarly-named declaration in an outer
486 // scope.
487 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
488 --SMEnd;
489 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000490 ShadowMapEntry::iterator I, IEnd;
491 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
492 if (NamePos != SM->end()) {
493 I = NamePos->second.begin();
494 IEnd = NamePos->second.end();
495 }
496 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000497 // A tag declaration does not hide a non-tag declaration.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000498 if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000499 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
500 Decl::IDNS_ObjCProtocol)))
501 continue;
502
503 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000504 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000505 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000506 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000507 continue;
508
509 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000510 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000511 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000512
513 break;
514 }
515 }
516
517 // Make sure that any given declaration only shows up in the result set once.
518 if (!AllDeclsFound.insert(CanonDecl))
519 return;
520
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000521 // If the filter is for nested-name-specifiers, then this result starts a
522 // nested-name-specifier.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000523 if (AsNestedNameSpecifier)
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000524 R.StartsNestedNameSpecifier = true;
525
Douglas Gregor0563c262009-09-22 23:15:58 +0000526 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000527 if (R.QualifierIsInformative && !R.Qualifier &&
528 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000529 DeclContext *Ctx = R.Declaration->getDeclContext();
530 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
531 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
532 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
533 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
534 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
535 else
536 R.QualifierIsInformative = false;
537 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000538
Douglas Gregor86d9a522009-09-21 16:56:56 +0000539 // Insert this result into the set of results and into the current shadow
540 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000541 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000542 Results.push_back(R);
543}
544
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000545void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
546 NamedDecl *Hiding) {
547 assert(R.Kind == Result::RK_Declaration &&
548 "Only declaration results are supported");
549
550 // Look through using declarations.
551 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
552 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
553 return;
554 }
555
Douglas Gregor45bcd432010-01-14 03:21:49 +0000556 bool AsNestedNameSpecifier = false;
557 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000558 return;
559
560 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
561 return;
562
563 // Make sure that any given declaration only shows up in the result set once.
564 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
565 return;
566
567 // If the filter is for nested-name-specifiers, then this result starts a
568 // nested-name-specifier.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000569 if (AsNestedNameSpecifier)
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000570 R.StartsNestedNameSpecifier = true;
571
572 // If this result is supposed to have an informative qualifier, add one.
573 if (R.QualifierIsInformative && !R.Qualifier &&
574 !R.StartsNestedNameSpecifier) {
575 DeclContext *Ctx = R.Declaration->getDeclContext();
576 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
577 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
578 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
579 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000580 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000581 else
582 R.QualifierIsInformative = false;
583 }
584
585 // Insert this result into the set of results.
586 Results.push_back(R);
587}
588
Douglas Gregor86d9a522009-09-21 16:56:56 +0000589/// \brief Enter into a new scope.
590void ResultBuilder::EnterNewScope() {
591 ShadowMaps.push_back(ShadowMap());
592}
593
594/// \brief Exit from the current scope.
595void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000596 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
597 EEnd = ShadowMaps.back().end();
598 E != EEnd;
599 ++E)
600 E->second.Destroy();
601
Douglas Gregor86d9a522009-09-21 16:56:56 +0000602 ShadowMaps.pop_back();
603}
604
Douglas Gregor791215b2009-09-21 20:51:25 +0000605/// \brief Determines whether this given declaration will be found by
606/// ordinary name lookup.
607bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
608 unsigned IDNS = Decl::IDNS_Ordinary;
609 if (SemaRef.getLangOptions().CPlusPlus)
610 IDNS |= Decl::IDNS_Tag;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000611 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
612 return true;
613
Douglas Gregor791215b2009-09-21 20:51:25 +0000614 return ND->getIdentifierNamespace() & IDNS;
615}
616
Douglas Gregor01dfea02010-01-10 23:08:15 +0000617/// \brief Determines whether this given declaration will be found by
618/// ordinary name lookup.
619bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
620 unsigned IDNS = Decl::IDNS_Ordinary;
621 if (SemaRef.getLangOptions().CPlusPlus)
622 IDNS |= Decl::IDNS_Tag;
623
624 return (ND->getIdentifierNamespace() & IDNS) &&
625 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
626}
627
Douglas Gregor86d9a522009-09-21 16:56:56 +0000628/// \brief Determines whether the given declaration is suitable as the
629/// start of a C++ nested-name-specifier, e.g., a class or namespace.
630bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
631 // Allow us to find class templates, too.
632 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
633 ND = ClassTemplate->getTemplatedDecl();
634
635 return SemaRef.isAcceptableNestedNameSpecifier(ND);
636}
637
638/// \brief Determines whether the given declaration is an enumeration.
639bool ResultBuilder::IsEnum(NamedDecl *ND) const {
640 return isa<EnumDecl>(ND);
641}
642
643/// \brief Determines whether the given declaration is a class or struct.
644bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
645 // Allow us to find class templates, too.
646 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
647 ND = ClassTemplate->getTemplatedDecl();
648
649 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
650 return RD->getTagKind() == TagDecl::TK_class ||
651 RD->getTagKind() == TagDecl::TK_struct;
652
653 return false;
654}
655
656/// \brief Determines whether the given declaration is a union.
657bool ResultBuilder::IsUnion(NamedDecl *ND) const {
658 // Allow us to find class templates, too.
659 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
660 ND = ClassTemplate->getTemplatedDecl();
661
662 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
663 return RD->getTagKind() == TagDecl::TK_union;
664
665 return false;
666}
667
668/// \brief Determines whether the given declaration is a namespace.
669bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
670 return isa<NamespaceDecl>(ND);
671}
672
673/// \brief Determines whether the given declaration is a namespace or
674/// namespace alias.
675bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
676 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
677}
678
Douglas Gregor76282942009-12-11 17:31:05 +0000679/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000680bool ResultBuilder::IsType(NamedDecl *ND) const {
681 return isa<TypeDecl>(ND);
682}
683
Douglas Gregor76282942009-12-11 17:31:05 +0000684/// \brief Determines which members of a class should be visible via
685/// "." or "->". Only value declarations, nested name specifiers, and
686/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000687bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000688 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
689 ND = Using->getTargetDecl();
690
Douglas Gregorce821962009-12-11 18:14:22 +0000691 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
692 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000693}
694
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000695namespace {
696 /// \brief Visible declaration consumer that adds a code-completion result
697 /// for each visible declaration.
698 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
699 ResultBuilder &Results;
700 DeclContext *CurContext;
701
702 public:
703 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
704 : Results(Results), CurContext(CurContext) { }
705
706 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding) {
707 Results.AddResult(ND, CurContext, Hiding);
708 }
709 };
710}
711
Douglas Gregor86d9a522009-09-21 16:56:56 +0000712/// \brief Collect the results of searching for members within the given
713/// declaration context.
714///
715/// \param Ctx the declaration context from which we will gather results.
716///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000717/// \param Visited the set of declaration contexts that have already been
718/// visited. Declaration contexts will only be visited once.
719///
720/// \param Results the result set that will be extended with any results
721/// found within this declaration context (and, for a C++ class, its bases).
722///
Douglas Gregor0563c262009-09-22 23:15:58 +0000723/// \param InBaseClass whether we are in a base class.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000724static void CollectMemberLookupResults(DeclContext *Ctx,
725 DeclContext *CurContext,
Douglas Gregor456c4a12009-09-21 20:12:40 +0000726 llvm::SmallPtrSet<DeclContext *, 16> &Visited,
Douglas Gregorbca403c2010-01-13 23:51:12 +0000727 ResultBuilder &Results,
728 bool InBaseClass = false) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000729 // Make sure we don't visit the same context twice.
730 if (!Visited.insert(Ctx->getPrimaryContext()))
Douglas Gregorbca403c2010-01-13 23:51:12 +0000731 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000732
733 // Enumerate all of the results in this context.
Douglas Gregor0563c262009-09-22 23:15:58 +0000734 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000735 Results.EnterNewScope();
736 for (DeclContext *CurCtx = Ctx->getPrimaryContext(); CurCtx;
737 CurCtx = CurCtx->getNextContext()) {
738 for (DeclContext::decl_iterator D = CurCtx->decls_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000739 DEnd = CurCtx->decls_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000740 D != DEnd; ++D) {
741 if (NamedDecl *ND = dyn_cast<NamedDecl>(*D))
Douglas Gregorbca403c2010-01-13 23:51:12 +0000742 Results.MaybeAddResult(Result(ND, 0, InBaseClass), CurContext);
Douglas Gregorff4393c2009-11-09 21:35:27 +0000743
744 // Visit transparent contexts inside this context.
745 if (DeclContext *InnerCtx = dyn_cast<DeclContext>(*D)) {
746 if (InnerCtx->isTransparentContext())
Douglas Gregorbca403c2010-01-13 23:51:12 +0000747 CollectMemberLookupResults(InnerCtx, CurContext, Visited,
Douglas Gregorff4393c2009-11-09 21:35:27 +0000748 Results, InBaseClass);
749 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000750 }
751 }
752
753 // Traverse the contexts of inherited classes.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000754 if (CXXRecordDecl *Record = dyn_cast<CXXRecordDecl>(Ctx)) {
755 for (CXXRecordDecl::base_class_iterator B = Record->bases_begin(),
Douglas Gregorff4393c2009-11-09 21:35:27 +0000756 BEnd = Record->bases_end();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000757 B != BEnd; ++B) {
758 QualType BaseType = B->getType();
759
760 // Don't look into dependent bases, because name lookup can't look
761 // there anyway.
762 if (BaseType->isDependentType())
763 continue;
764
765 const RecordType *Record = BaseType->getAs<RecordType>();
766 if (!Record)
767 continue;
768
769 // FIXME: It would be nice to be able to determine whether referencing
770 // a particular member would be ambiguous. For example, given
771 //
772 // struct A { int member; };
773 // struct B { int member; };
774 // struct C : A, B { };
775 //
776 // void f(C *c) { c->### }
777 // accessing 'member' would result in an ambiguity. However, code
778 // completion could be smart enough to qualify the member with the
779 // base class, e.g.,
780 //
781 // c->B::member
782 //
783 // or
784 //
785 // c->A::member
786
787 // Collect results from this base class (and its bases).
Douglas Gregorbca403c2010-01-13 23:51:12 +0000788 CollectMemberLookupResults(Record->getDecl(), CurContext, Visited,
Douglas Gregor0563c262009-09-22 23:15:58 +0000789 Results, /*InBaseClass=*/true);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000790 }
791 }
792
793 // FIXME: Look into base classes in Objective-C!
794
795 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +0000796}
797
798/// \brief Collect the results of searching for members within the given
799/// declaration context.
800///
801/// \param Ctx the declaration context from which we will gather results.
802///
Douglas Gregor86d9a522009-09-21 16:56:56 +0000803/// \param Results the result set that will be extended with any results
804/// found within this declaration context (and, for a C++ class, its bases).
Douglas Gregorbca403c2010-01-13 23:51:12 +0000805static void CollectMemberLookupResults(DeclContext *Ctx,
806 DeclContext *CurContext,
807 ResultBuilder &Results) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000808 llvm::SmallPtrSet<DeclContext *, 16> Visited;
Douglas Gregorbca403c2010-01-13 23:51:12 +0000809 CollectMemberLookupResults(Ctx, CurContext, Visited, Results);
Douglas Gregor86d9a522009-09-21 16:56:56 +0000810}
811
Douglas Gregor86d9a522009-09-21 16:56:56 +0000812/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000813static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000814 ResultBuilder &Results) {
815 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbca403c2010-01-13 23:51:12 +0000816 Results.MaybeAddResult(Result("short"));
817 Results.MaybeAddResult(Result("long"));
818 Results.MaybeAddResult(Result("signed"));
819 Results.MaybeAddResult(Result("unsigned"));
820 Results.MaybeAddResult(Result("void"));
821 Results.MaybeAddResult(Result("char"));
822 Results.MaybeAddResult(Result("int"));
823 Results.MaybeAddResult(Result("float"));
824 Results.MaybeAddResult(Result("double"));
825 Results.MaybeAddResult(Result("enum"));
826 Results.MaybeAddResult(Result("struct"));
827 Results.MaybeAddResult(Result("union"));
828 Results.MaybeAddResult(Result("const"));
829 Results.MaybeAddResult(Result("volatile"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000830
Douglas Gregor86d9a522009-09-21 16:56:56 +0000831 if (LangOpts.C99) {
832 // C99-specific
Douglas Gregorbca403c2010-01-13 23:51:12 +0000833 Results.MaybeAddResult(Result("_Complex"));
834 Results.MaybeAddResult(Result("_Imaginary"));
835 Results.MaybeAddResult(Result("_Bool"));
836 Results.MaybeAddResult(Result("restrict"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000837 }
838
839 if (LangOpts.CPlusPlus) {
840 // C++-specific
Douglas Gregorbca403c2010-01-13 23:51:12 +0000841 Results.MaybeAddResult(Result("bool"));
842 Results.MaybeAddResult(Result("class"));
843 Results.MaybeAddResult(Result("wchar_t"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000844
Douglas Gregor01dfea02010-01-10 23:08:15 +0000845 // typename qualified-id
846 CodeCompletionString *Pattern = new CodeCompletionString;
847 Pattern->AddTypedTextChunk("typename");
848 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
849 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregorbca403c2010-01-13 23:51:12 +0000850 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000851
Douglas Gregor86d9a522009-09-21 16:56:56 +0000852 if (LangOpts.CPlusPlus0x) {
Douglas Gregorbca403c2010-01-13 23:51:12 +0000853 Results.MaybeAddResult(Result("auto"));
854 Results.MaybeAddResult(Result("char16_t"));
855 Results.MaybeAddResult(Result("char32_t"));
856 Results.MaybeAddResult(Result("decltype"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000857 }
858 }
859
860 // GNU extensions
861 if (LangOpts.GNUMode) {
862 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000863 // Results.MaybeAddResult(Result("_Decimal32"));
864 // Results.MaybeAddResult(Result("_Decimal64"));
865 // Results.MaybeAddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000866
867 CodeCompletionString *Pattern = new CodeCompletionString;
868 Pattern->AddTypedTextChunk("typeof");
869 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
870 Pattern->AddPlaceholderChunk("expression-or-type");
871 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000872 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000873 }
874}
875
Douglas Gregor01dfea02010-01-10 23:08:15 +0000876static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
877 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000878 ResultBuilder &Results) {
879 typedef CodeCompleteConsumer::Result Result;
880 // Note: we don't suggest either "auto" or "register", because both
881 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
882 // in C++0x as a type specifier.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000883 Results.MaybeAddResult(Result("extern"));
884 Results.MaybeAddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000885}
886
887static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
888 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000889 ResultBuilder &Results) {
890 typedef CodeCompleteConsumer::Result Result;
891 switch (CCC) {
892 case Action::CCC_Class:
893 case Action::CCC_MemberTemplate:
894 if (LangOpts.CPlusPlus) {
Douglas Gregorbca403c2010-01-13 23:51:12 +0000895 Results.MaybeAddResult(Result("explicit"));
896 Results.MaybeAddResult(Result("friend"));
897 Results.MaybeAddResult(Result("mutable"));
898 Results.MaybeAddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000899 }
900 // Fall through
901
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000902 case Action::CCC_ObjCInterface:
903 case Action::CCC_ObjCImplementation:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000904 case Action::CCC_Namespace:
905 case Action::CCC_Template:
906 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregorbca403c2010-01-13 23:51:12 +0000907 Results.MaybeAddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000908 break;
909
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000910 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000911 case Action::CCC_Expression:
912 case Action::CCC_Statement:
913 case Action::CCC_ForInit:
914 case Action::CCC_Condition:
915 break;
916 }
917}
918
Douglas Gregorbca403c2010-01-13 23:51:12 +0000919static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
920static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
921static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000922 ResultBuilder &Results,
923 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000924static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000925 ResultBuilder &Results,
926 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000927static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000928 ResultBuilder &Results,
929 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000930static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000931
Douglas Gregor01dfea02010-01-10 23:08:15 +0000932/// \brief Add language constructs that show up for "ordinary" names.
933static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
934 Scope *S,
935 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000936 ResultBuilder &Results) {
937 typedef CodeCompleteConsumer::Result Result;
938 switch (CCC) {
939 case Action::CCC_Namespace:
940 if (SemaRef.getLangOptions().CPlusPlus) {
941 // namespace <identifier> { }
942 CodeCompletionString *Pattern = new CodeCompletionString;
943 Pattern->AddTypedTextChunk("namespace");
944 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
945 Pattern->AddPlaceholderChunk("identifier");
946 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
947 Pattern->AddPlaceholderChunk("declarations");
948 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
949 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000950 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000951
952 // namespace identifier = identifier ;
953 Pattern = new CodeCompletionString;
954 Pattern->AddTypedTextChunk("namespace");
955 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
956 Pattern->AddPlaceholderChunk("identifier");
957 Pattern->AddChunk(CodeCompletionString::CK_Equal);
958 Pattern->AddPlaceholderChunk("identifier");
959 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000960 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000961
962 // Using directives
963 Pattern = new CodeCompletionString;
964 Pattern->AddTypedTextChunk("using");
965 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
966 Pattern->AddTextChunk("namespace");
967 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
968 Pattern->AddPlaceholderChunk("identifier");
969 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000970 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000971
972 // asm(string-literal)
973 Pattern = new CodeCompletionString;
974 Pattern->AddTypedTextChunk("asm");
975 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
976 Pattern->AddPlaceholderChunk("string-literal");
977 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
978 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000979 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000980
981 // Explicit template instantiation
982 Pattern = new CodeCompletionString;
983 Pattern->AddTypedTextChunk("template");
984 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
985 Pattern->AddPlaceholderChunk("declaration");
986 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000987 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000988 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000989
990 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +0000991 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000992
Douglas Gregor01dfea02010-01-10 23:08:15 +0000993 // Fall through
994
995 case Action::CCC_Class:
Douglas Gregorbca403c2010-01-13 23:51:12 +0000996 Results.MaybeAddResult(Result("typedef"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000997 if (SemaRef.getLangOptions().CPlusPlus) {
998 // Using declaration
999 CodeCompletionString *Pattern = new CodeCompletionString;
1000 Pattern->AddTypedTextChunk("using");
1001 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1002 Pattern->AddPlaceholderChunk("qualified-id");
1003 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001004 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001005
1006 // using typename qualified-id; (only in a dependent context)
1007 if (SemaRef.CurContext->isDependentContext()) {
1008 Pattern = new CodeCompletionString;
1009 Pattern->AddTypedTextChunk("using");
1010 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1011 Pattern->AddTextChunk("typename");
1012 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1013 Pattern->AddPlaceholderChunk("qualified-id");
1014 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001015 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001016 }
1017
1018 if (CCC == Action::CCC_Class) {
1019 // public:
1020 Pattern = new CodeCompletionString;
1021 Pattern->AddTypedTextChunk("public");
1022 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001023 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001024
1025 // protected:
1026 Pattern = new CodeCompletionString;
1027 Pattern->AddTypedTextChunk("protected");
1028 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001029 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001030
1031 // private:
1032 Pattern = new CodeCompletionString;
1033 Pattern->AddTypedTextChunk("private");
1034 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001035 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001036 }
1037 }
1038 // Fall through
1039
1040 case Action::CCC_Template:
1041 case Action::CCC_MemberTemplate:
1042 if (SemaRef.getLangOptions().CPlusPlus) {
1043 // template < parameters >
1044 CodeCompletionString *Pattern = new CodeCompletionString;
1045 Pattern->AddTypedTextChunk("template");
1046 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1047 Pattern->AddPlaceholderChunk("parameters");
1048 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001049 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001050 }
1051
Douglas Gregorbca403c2010-01-13 23:51:12 +00001052 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1053 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001054 break;
1055
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001056 case Action::CCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001057 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
1058 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1059 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001060 break;
1061
1062 case Action::CCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001063 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
1064 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
1065 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001066 break;
1067
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001068 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001069 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001070 break;
1071
Douglas Gregor01dfea02010-01-10 23:08:15 +00001072 case Action::CCC_Statement: {
Douglas Gregorbca403c2010-01-13 23:51:12 +00001073 Results.MaybeAddResult(Result("typedef"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001074
1075 CodeCompletionString *Pattern = 0;
1076 if (SemaRef.getLangOptions().CPlusPlus) {
1077 Pattern = new CodeCompletionString;
1078 Pattern->AddTypedTextChunk("try");
1079 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1080 Pattern->AddPlaceholderChunk("statements");
1081 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1082 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1083 Pattern->AddTextChunk("catch");
1084 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1085 Pattern->AddPlaceholderChunk("declaration");
1086 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1087 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1088 Pattern->AddPlaceholderChunk("statements");
1089 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1090 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001091 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001092 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001093 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001094 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001095
Douglas Gregor01dfea02010-01-10 23:08:15 +00001096 // if (condition) { statements }
1097 Pattern = new CodeCompletionString;
1098 Pattern->AddTypedTextChunk("if");
1099 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1100 if (SemaRef.getLangOptions().CPlusPlus)
1101 Pattern->AddPlaceholderChunk("condition");
1102 else
1103 Pattern->AddPlaceholderChunk("expression");
1104 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1105 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1106 Pattern->AddPlaceholderChunk("statements");
1107 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1108 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001109 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001110
1111 // switch (condition) { }
1112 Pattern = new CodeCompletionString;
1113 Pattern->AddTypedTextChunk("switch");
1114 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1115 if (SemaRef.getLangOptions().CPlusPlus)
1116 Pattern->AddPlaceholderChunk("condition");
1117 else
1118 Pattern->AddPlaceholderChunk("expression");
1119 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1120 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1121 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1122 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001123 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001124
1125 // Switch-specific statements.
1126 if (!SemaRef.getSwitchStack().empty()) {
1127 // case expression:
1128 Pattern = new CodeCompletionString;
1129 Pattern->AddTypedTextChunk("case");
1130 Pattern->AddPlaceholderChunk("expression");
1131 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001132 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001133
1134 // default:
1135 Pattern = new CodeCompletionString;
1136 Pattern->AddTypedTextChunk("default");
1137 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001138 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001139 }
1140
1141 /// while (condition) { statements }
1142 Pattern = new CodeCompletionString;
1143 Pattern->AddTypedTextChunk("while");
1144 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1145 if (SemaRef.getLangOptions().CPlusPlus)
1146 Pattern->AddPlaceholderChunk("condition");
1147 else
1148 Pattern->AddPlaceholderChunk("expression");
1149 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1150 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1151 Pattern->AddPlaceholderChunk("statements");
1152 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1153 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001154 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001155
1156 // do { statements } while ( expression );
1157 Pattern = new CodeCompletionString;
1158 Pattern->AddTypedTextChunk("do");
1159 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1160 Pattern->AddPlaceholderChunk("statements");
1161 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1162 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1163 Pattern->AddTextChunk("while");
1164 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1165 Pattern->AddPlaceholderChunk("expression");
1166 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1167 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001168 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001169
1170 // for ( for-init-statement ; condition ; expression ) { statements }
1171 Pattern = new CodeCompletionString;
1172 Pattern->AddTypedTextChunk("for");
1173 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1174 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1175 Pattern->AddPlaceholderChunk("init-statement");
1176 else
1177 Pattern->AddPlaceholderChunk("init-expression");
1178 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1179 Pattern->AddPlaceholderChunk("condition");
1180 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1181 Pattern->AddPlaceholderChunk("inc-expression");
1182 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1183 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1184 Pattern->AddPlaceholderChunk("statements");
1185 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1186 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001187 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001188
1189 if (S->getContinueParent()) {
1190 // continue ;
1191 Pattern = new CodeCompletionString;
1192 Pattern->AddTypedTextChunk("continue");
1193 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001194 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001195 }
1196
1197 if (S->getBreakParent()) {
1198 // break ;
1199 Pattern = new CodeCompletionString;
1200 Pattern->AddTypedTextChunk("break");
1201 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001202 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001203 }
1204
1205 // "return expression ;" or "return ;", depending on whether we
1206 // know the function is void or not.
1207 bool isVoid = false;
1208 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1209 isVoid = Function->getResultType()->isVoidType();
1210 else if (ObjCMethodDecl *Method
1211 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1212 isVoid = Method->getResultType()->isVoidType();
1213 else if (SemaRef.CurBlock && !SemaRef.CurBlock->ReturnType.isNull())
1214 isVoid = SemaRef.CurBlock->ReturnType->isVoidType();
1215 Pattern = new CodeCompletionString;
1216 Pattern->AddTypedTextChunk("return");
1217 if (!isVoid)
1218 Pattern->AddPlaceholderChunk("expression");
1219 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001220 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001221
1222 // goto identifier ;
1223 Pattern = new CodeCompletionString;
1224 Pattern->AddTypedTextChunk("goto");
1225 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1226 Pattern->AddPlaceholderChunk("identifier");
1227 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001228 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001229
1230 // Using directives
1231 Pattern = new CodeCompletionString;
1232 Pattern->AddTypedTextChunk("using");
1233 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1234 Pattern->AddTextChunk("namespace");
1235 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1236 Pattern->AddPlaceholderChunk("identifier");
1237 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001238 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001239 }
1240
1241 // Fall through (for statement expressions).
1242 case Action::CCC_ForInit:
1243 case Action::CCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001244 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001245 // Fall through: conditions and statements can have expressions.
1246
1247 case Action::CCC_Expression: {
1248 CodeCompletionString *Pattern = 0;
1249 if (SemaRef.getLangOptions().CPlusPlus) {
1250 // 'this', if we're in a non-static member function.
1251 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1252 if (!Method->isStatic())
Douglas Gregorbca403c2010-01-13 23:51:12 +00001253 Results.MaybeAddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001254
1255 // true, false
Douglas Gregorbca403c2010-01-13 23:51:12 +00001256 Results.MaybeAddResult(Result("true"));
1257 Results.MaybeAddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001258
1259 // dynamic_cast < type-id > ( expression )
1260 Pattern = new CodeCompletionString;
1261 Pattern->AddTypedTextChunk("dynamic_cast");
1262 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1263 Pattern->AddPlaceholderChunk("type-id");
1264 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1265 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1266 Pattern->AddPlaceholderChunk("expression");
1267 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001268 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001269
1270 // static_cast < type-id > ( expression )
1271 Pattern = new CodeCompletionString;
1272 Pattern->AddTypedTextChunk("static_cast");
1273 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1274 Pattern->AddPlaceholderChunk("type-id");
1275 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1276 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1277 Pattern->AddPlaceholderChunk("expression");
1278 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001279 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001280
1281 // reinterpret_cast < type-id > ( expression )
1282 Pattern = new CodeCompletionString;
1283 Pattern->AddTypedTextChunk("reinterpret_cast");
1284 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1285 Pattern->AddPlaceholderChunk("type-id");
1286 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1287 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1288 Pattern->AddPlaceholderChunk("expression");
1289 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001290 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001291
1292 // const_cast < type-id > ( expression )
1293 Pattern = new CodeCompletionString;
1294 Pattern->AddTypedTextChunk("const_cast");
1295 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1296 Pattern->AddPlaceholderChunk("type-id");
1297 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1298 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1299 Pattern->AddPlaceholderChunk("expression");
1300 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001301 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001302
1303 // typeid ( expression-or-type )
1304 Pattern = new CodeCompletionString;
1305 Pattern->AddTypedTextChunk("typeid");
1306 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1307 Pattern->AddPlaceholderChunk("expression-or-type");
1308 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001309 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001310
1311 // new T ( ... )
1312 Pattern = new CodeCompletionString;
1313 Pattern->AddTypedTextChunk("new");
1314 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1315 Pattern->AddPlaceholderChunk("type-id");
1316 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1317 Pattern->AddPlaceholderChunk("expressions");
1318 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001319 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001320
1321 // new T [ ] ( ... )
1322 Pattern = new CodeCompletionString;
1323 Pattern->AddTypedTextChunk("new");
1324 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1325 Pattern->AddPlaceholderChunk("type-id");
1326 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1327 Pattern->AddPlaceholderChunk("size");
1328 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1329 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1330 Pattern->AddPlaceholderChunk("expressions");
1331 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001332 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001333
1334 // delete expression
1335 Pattern = new CodeCompletionString;
1336 Pattern->AddTypedTextChunk("delete");
1337 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1338 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorbca403c2010-01-13 23:51:12 +00001339 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001340
1341 // delete [] expression
1342 Pattern = new CodeCompletionString;
1343 Pattern->AddTypedTextChunk("delete");
1344 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1345 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1346 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1347 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorbca403c2010-01-13 23:51:12 +00001348 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001349
1350 // throw expression
1351 Pattern = new CodeCompletionString;
1352 Pattern->AddTypedTextChunk("throw");
1353 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1354 Pattern->AddPlaceholderChunk("expression");
Douglas Gregorbca403c2010-01-13 23:51:12 +00001355 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001356 }
1357
1358 if (SemaRef.getLangOptions().ObjC1) {
1359 // Add "super", if we're in an Objective-C class with a superclass.
1360 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1361 if (Method->getClassInterface()->getSuperClass())
Douglas Gregorbca403c2010-01-13 23:51:12 +00001362 Results.MaybeAddResult(Result("super"));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001363
Douglas Gregorbca403c2010-01-13 23:51:12 +00001364 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001365 }
1366
1367 // sizeof expression
1368 Pattern = new CodeCompletionString;
1369 Pattern->AddTypedTextChunk("sizeof");
1370 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1371 Pattern->AddPlaceholderChunk("expression-or-type");
1372 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +00001373 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001374 break;
1375 }
1376 }
1377
Douglas Gregorbca403c2010-01-13 23:51:12 +00001378 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001379
1380 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001381 Results.MaybeAddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001382}
1383
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001384/// \brief If the given declaration has an associated type, add it as a result
1385/// type chunk.
1386static void AddResultTypeChunk(ASTContext &Context,
1387 NamedDecl *ND,
1388 CodeCompletionString *Result) {
1389 if (!ND)
1390 return;
1391
1392 // Determine the type of the declaration (if it has a type).
1393 QualType T;
1394 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1395 T = Function->getResultType();
1396 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1397 T = Method->getResultType();
1398 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1399 T = FunTmpl->getTemplatedDecl()->getResultType();
1400 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1401 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1402 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1403 /* Do nothing: ignore unresolved using declarations*/
1404 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1405 T = Value->getType();
1406 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1407 T = Property->getType();
1408
1409 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1410 return;
1411
1412 std::string TypeStr;
1413 T.getAsStringInternal(TypeStr, Context.PrintingPolicy);
1414 Result->AddResultTypeChunk(TypeStr);
1415}
1416
Douglas Gregor86d9a522009-09-21 16:56:56 +00001417/// \brief Add function parameter chunks to the given code completion string.
1418static void AddFunctionParameterChunks(ASTContext &Context,
1419 FunctionDecl *Function,
1420 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001421 typedef CodeCompletionString::Chunk Chunk;
1422
Douglas Gregor86d9a522009-09-21 16:56:56 +00001423 CodeCompletionString *CCStr = Result;
1424
1425 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1426 ParmVarDecl *Param = Function->getParamDecl(P);
1427
1428 if (Param->hasDefaultArg()) {
1429 // When we see an optional default argument, put that argument and
1430 // the remaining default arguments into a new, optional string.
1431 CodeCompletionString *Opt = new CodeCompletionString;
1432 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1433 CCStr = Opt;
1434 }
1435
1436 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001437 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001438
1439 // Format the placeholder string.
1440 std::string PlaceholderStr;
1441 if (Param->getIdentifier())
1442 PlaceholderStr = Param->getIdentifier()->getName();
1443
1444 Param->getType().getAsStringInternal(PlaceholderStr,
1445 Context.PrintingPolicy);
1446
1447 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001448 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001449 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001450
1451 if (const FunctionProtoType *Proto
1452 = Function->getType()->getAs<FunctionProtoType>())
1453 if (Proto->isVariadic())
1454 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001455}
1456
1457/// \brief Add template parameter chunks to the given code completion string.
1458static void AddTemplateParameterChunks(ASTContext &Context,
1459 TemplateDecl *Template,
1460 CodeCompletionString *Result,
1461 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001462 typedef CodeCompletionString::Chunk Chunk;
1463
Douglas Gregor86d9a522009-09-21 16:56:56 +00001464 CodeCompletionString *CCStr = Result;
1465 bool FirstParameter = true;
1466
1467 TemplateParameterList *Params = Template->getTemplateParameters();
1468 TemplateParameterList::iterator PEnd = Params->end();
1469 if (MaxParameters)
1470 PEnd = Params->begin() + MaxParameters;
1471 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1472 bool HasDefaultArg = false;
1473 std::string PlaceholderStr;
1474 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1475 if (TTP->wasDeclaredWithTypename())
1476 PlaceholderStr = "typename";
1477 else
1478 PlaceholderStr = "class";
1479
1480 if (TTP->getIdentifier()) {
1481 PlaceholderStr += ' ';
1482 PlaceholderStr += TTP->getIdentifier()->getName();
1483 }
1484
1485 HasDefaultArg = TTP->hasDefaultArgument();
1486 } else if (NonTypeTemplateParmDecl *NTTP
1487 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1488 if (NTTP->getIdentifier())
1489 PlaceholderStr = NTTP->getIdentifier()->getName();
1490 NTTP->getType().getAsStringInternal(PlaceholderStr,
1491 Context.PrintingPolicy);
1492 HasDefaultArg = NTTP->hasDefaultArgument();
1493 } else {
1494 assert(isa<TemplateTemplateParmDecl>(*P));
1495 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1496
1497 // Since putting the template argument list into the placeholder would
1498 // be very, very long, we just use an abbreviation.
1499 PlaceholderStr = "template<...> class";
1500 if (TTP->getIdentifier()) {
1501 PlaceholderStr += ' ';
1502 PlaceholderStr += TTP->getIdentifier()->getName();
1503 }
1504
1505 HasDefaultArg = TTP->hasDefaultArgument();
1506 }
1507
1508 if (HasDefaultArg) {
1509 // When we see an optional default argument, put that argument and
1510 // the remaining default arguments into a new, optional string.
1511 CodeCompletionString *Opt = new CodeCompletionString;
1512 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1513 CCStr = Opt;
1514 }
1515
1516 if (FirstParameter)
1517 FirstParameter = false;
1518 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001519 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001520
1521 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001522 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001523 }
1524}
1525
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001526/// \brief Add a qualifier to the given code-completion string, if the
1527/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001528static void
1529AddQualifierToCompletionString(CodeCompletionString *Result,
1530 NestedNameSpecifier *Qualifier,
1531 bool QualifierIsInformative,
1532 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001533 if (!Qualifier)
1534 return;
1535
1536 std::string PrintedNNS;
1537 {
1538 llvm::raw_string_ostream OS(PrintedNNS);
1539 Qualifier->print(OS, Context.PrintingPolicy);
1540 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001541 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001542 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001543 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001544 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001545}
1546
Douglas Gregora61a8792009-12-11 18:44:16 +00001547static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1548 FunctionDecl *Function) {
1549 const FunctionProtoType *Proto
1550 = Function->getType()->getAs<FunctionProtoType>();
1551 if (!Proto || !Proto->getTypeQuals())
1552 return;
1553
1554 std::string QualsStr;
1555 if (Proto->getTypeQuals() & Qualifiers::Const)
1556 QualsStr += " const";
1557 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1558 QualsStr += " volatile";
1559 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1560 QualsStr += " restrict";
1561 Result->AddInformativeChunk(QualsStr);
1562}
1563
Douglas Gregor86d9a522009-09-21 16:56:56 +00001564/// \brief If possible, create a new code completion string for the given
1565/// result.
1566///
1567/// \returns Either a new, heap-allocated code completion string describing
1568/// how to use this result, or NULL to indicate that the string or name of the
1569/// result is all that is needed.
1570CodeCompletionString *
1571CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001572 typedef CodeCompletionString::Chunk Chunk;
1573
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001574 if (Kind == RK_Pattern)
1575 return Pattern->Clone();
1576
1577 CodeCompletionString *Result = new CodeCompletionString;
1578
1579 if (Kind == RK_Keyword) {
1580 Result->AddTypedTextChunk(Keyword);
1581 return Result;
1582 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001583
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001584 if (Kind == RK_Macro) {
1585 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001586 assert(MI && "Not a macro?");
1587
1588 Result->AddTypedTextChunk(Macro->getName());
1589
1590 if (!MI->isFunctionLike())
1591 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001592
1593 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001594 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001595 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1596 A != AEnd; ++A) {
1597 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001598 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001599
1600 if (!MI->isVariadic() || A != AEnd - 1) {
1601 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001602 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001603 continue;
1604 }
1605
1606 // Variadic argument; cope with the different between GNU and C99
1607 // variadic macros, providing a single placeholder for the rest of the
1608 // arguments.
1609 if ((*A)->isStr("__VA_ARGS__"))
1610 Result->AddPlaceholderChunk("...");
1611 else {
1612 std::string Arg = (*A)->getName();
1613 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001614 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001615 }
1616 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001617 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001618 return Result;
1619 }
1620
1621 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001622 NamedDecl *ND = Declaration;
1623
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001624 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001625 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001626 Result->AddTextChunk("::");
1627 return Result;
1628 }
1629
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001630 AddResultTypeChunk(S.Context, ND, Result);
1631
Douglas Gregor86d9a522009-09-21 16:56:56 +00001632 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001633 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1634 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001635 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001636 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001637 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001638 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001639 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001640 return Result;
1641 }
1642
1643 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001644 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1645 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001646 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001647 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001648
1649 // Figure out which template parameters are deduced (or have default
1650 // arguments).
1651 llvm::SmallVector<bool, 16> Deduced;
1652 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1653 unsigned LastDeducibleArgument;
1654 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1655 --LastDeducibleArgument) {
1656 if (!Deduced[LastDeducibleArgument - 1]) {
1657 // C++0x: Figure out if the template argument has a default. If so,
1658 // the user doesn't need to type this argument.
1659 // FIXME: We need to abstract template parameters better!
1660 bool HasDefaultArg = false;
1661 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1662 LastDeducibleArgument - 1);
1663 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1664 HasDefaultArg = TTP->hasDefaultArgument();
1665 else if (NonTypeTemplateParmDecl *NTTP
1666 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1667 HasDefaultArg = NTTP->hasDefaultArgument();
1668 else {
1669 assert(isa<TemplateTemplateParmDecl>(Param));
1670 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001671 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001672 }
1673
1674 if (!HasDefaultArg)
1675 break;
1676 }
1677 }
1678
1679 if (LastDeducibleArgument) {
1680 // Some of the function template arguments cannot be deduced from a
1681 // function call, so we introduce an explicit template argument list
1682 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001683 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001684 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1685 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001686 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001687 }
1688
1689 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001690 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001691 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001692 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001693 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001694 return Result;
1695 }
1696
1697 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001698 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1699 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001700 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001701 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001702 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001703 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001704 return Result;
1705 }
1706
Douglas Gregor9630eb62009-11-17 16:44:22 +00001707 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001708 Selector Sel = Method->getSelector();
1709 if (Sel.isUnarySelector()) {
1710 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1711 return Result;
1712 }
1713
Douglas Gregord3c68542009-11-19 01:08:35 +00001714 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1715 SelName += ':';
1716 if (StartParameter == 0)
1717 Result->AddTypedTextChunk(SelName);
1718 else {
1719 Result->AddInformativeChunk(SelName);
1720
1721 // If there is only one parameter, and we're past it, add an empty
1722 // typed-text chunk since there is nothing to type.
1723 if (Method->param_size() == 1)
1724 Result->AddTypedTextChunk("");
1725 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001726 unsigned Idx = 0;
1727 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1728 PEnd = Method->param_end();
1729 P != PEnd; (void)++P, ++Idx) {
1730 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001731 std::string Keyword;
1732 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00001733 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001734 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1735 Keyword += II->getName().str();
1736 Keyword += ":";
Douglas Gregor4ad96852009-11-19 07:41:15 +00001737 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001738 Result->AddInformativeChunk(Keyword);
1739 } else if (Idx == StartParameter)
1740 Result->AddTypedTextChunk(Keyword);
1741 else
1742 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001743 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001744
1745 // If we're before the starting parameter, skip the placeholder.
1746 if (Idx < StartParameter)
1747 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001748
1749 std::string Arg;
1750 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1751 Arg = "(" + Arg + ")";
1752 if (IdentifierInfo *II = (*P)->getIdentifier())
1753 Arg += II->getName().str();
Douglas Gregor4ad96852009-11-19 07:41:15 +00001754 if (AllParametersAreInformative)
1755 Result->AddInformativeChunk(Arg);
1756 else
1757 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001758 }
1759
Douglas Gregor2a17af02009-12-23 00:21:46 +00001760 if (Method->isVariadic()) {
1761 if (AllParametersAreInformative)
1762 Result->AddInformativeChunk(", ...");
1763 else
1764 Result->AddPlaceholderChunk(", ...");
1765 }
1766
Douglas Gregor9630eb62009-11-17 16:44:22 +00001767 return Result;
1768 }
1769
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001770 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00001771 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1772 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001773
1774 Result->AddTypedTextChunk(ND->getNameAsString());
1775 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001776}
1777
Douglas Gregor86d802e2009-09-23 00:34:09 +00001778CodeCompletionString *
1779CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1780 unsigned CurrentArg,
1781 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001782 typedef CodeCompletionString::Chunk Chunk;
1783
Douglas Gregor86d802e2009-09-23 00:34:09 +00001784 CodeCompletionString *Result = new CodeCompletionString;
1785 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001786 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001787 const FunctionProtoType *Proto
1788 = dyn_cast<FunctionProtoType>(getFunctionType());
1789 if (!FDecl && !Proto) {
1790 // Function without a prototype. Just give the return type and a
1791 // highlighted ellipsis.
1792 const FunctionType *FT = getFunctionType();
1793 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001794 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001795 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1796 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1797 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001798 return Result;
1799 }
1800
1801 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001802 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00001803 else
1804 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001805 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001806
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001807 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001808 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1809 for (unsigned I = 0; I != NumParams; ++I) {
1810 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001811 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001812
1813 std::string ArgString;
1814 QualType ArgType;
1815
1816 if (FDecl) {
1817 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1818 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1819 } else {
1820 ArgType = Proto->getArgType(I);
1821 }
1822
1823 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1824
1825 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001826 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00001827 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001828 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001829 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001830 }
1831
1832 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001833 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001834 if (CurrentArg < NumParams)
1835 Result->AddTextChunk("...");
1836 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001837 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001838 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001839 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001840
1841 return Result;
1842}
1843
Douglas Gregor86d9a522009-09-21 16:56:56 +00001844namespace {
1845 struct SortCodeCompleteResult {
1846 typedef CodeCompleteConsumer::Result Result;
1847
Douglas Gregor6a684032009-09-28 03:51:44 +00001848 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001849 Selector XSel = X.getObjCSelector();
1850 Selector YSel = Y.getObjCSelector();
1851 if (!XSel.isNull() && !YSel.isNull()) {
1852 // We are comparing two selectors.
1853 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1854 if (N == 0)
1855 ++N;
1856 for (unsigned I = 0; I != N; ++I) {
1857 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1858 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1859 if (!XId || !YId)
1860 return XId && !YId;
1861
1862 switch (XId->getName().compare_lower(YId->getName())) {
1863 case -1: return true;
1864 case 1: return false;
1865 default: break;
1866 }
1867 }
1868
1869 return XSel.getNumArgs() < YSel.getNumArgs();
1870 }
1871
1872 // For non-selectors, order by kind.
1873 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00001874 return X.getNameKind() < Y.getNameKind();
1875
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001876 // Order identifiers by comparison of their lowercased names.
1877 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1878 return XId->getName().compare_lower(
1879 Y.getAsIdentifierInfo()->getName()) < 0;
1880
1881 // Order overloaded operators by the order in which they appear
1882 // in our list of operators.
1883 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1884 return XOp < Y.getCXXOverloadedOperator();
1885
1886 // Order C++0x user-defined literal operators lexically by their
1887 // lowercased suffixes.
1888 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1889 return XLit->getName().compare_lower(
1890 Y.getCXXLiteralIdentifier()->getName()) < 0;
1891
1892 // The only stable ordering we have is to turn the name into a
1893 // string and then compare the lower-case strings. This is
1894 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00001895 return llvm::StringRef(X.getAsString()).compare_lower(
1896 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00001897 }
1898
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001899 /// \brief Retrieve the name that should be used to order a result.
1900 ///
1901 /// If the name needs to be constructed as a string, that string will be
1902 /// saved into Saved and the returned StringRef will refer to it.
1903 static llvm::StringRef getOrderedName(const Result &R,
1904 std::string &Saved) {
1905 switch (R.Kind) {
1906 case Result::RK_Keyword:
1907 return R.Keyword;
1908
1909 case Result::RK_Pattern:
1910 return R.Pattern->getTypedText();
1911
1912 case Result::RK_Macro:
1913 return R.Macro->getName();
1914
1915 case Result::RK_Declaration:
1916 // Handle declarations below.
1917 break;
Douglas Gregor54f01612009-11-19 00:01:57 +00001918 }
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001919
1920 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor54f01612009-11-19 00:01:57 +00001921
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001922 // If the name is a simple identifier (by far the common case), or a
1923 // zero-argument selector, just return a reference to that identifier.
1924 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
1925 return Id->getName();
1926 if (Name.isObjCZeroArgSelector())
1927 if (IdentifierInfo *Id
1928 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
1929 return Id->getName();
1930
1931 Saved = Name.getAsString();
1932 return Saved;
1933 }
1934
1935 bool operator()(const Result &X, const Result &Y) const {
1936 std::string XSaved, YSaved;
1937 llvm::StringRef XStr = getOrderedName(X, XSaved);
1938 llvm::StringRef YStr = getOrderedName(Y, YSaved);
1939 int cmp = XStr.compare_lower(YStr);
1940 if (cmp)
1941 return cmp < 0;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001942
1943 // Non-hidden names precede hidden names.
1944 if (X.Hidden != Y.Hidden)
1945 return !X.Hidden;
1946
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001947 // Non-nested-name-specifiers precede nested-name-specifiers.
1948 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1949 return !X.StartsNestedNameSpecifier;
1950
Douglas Gregor86d9a522009-09-21 16:56:56 +00001951 return false;
1952 }
1953 };
1954}
1955
Douglas Gregorbca403c2010-01-13 23:51:12 +00001956static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001957 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001958 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1959 MEnd = PP.macro_end();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001960 M != MEnd; ++M)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001961 Results.MaybeAddResult(M->first);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001962 Results.ExitScope();
1963}
1964
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001965static void HandleCodeCompleteResults(Sema *S,
1966 CodeCompleteConsumer *CodeCompleter,
1967 CodeCompleteConsumer::Result *Results,
1968 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001969 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1970
1971 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001972 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00001973
1974 for (unsigned I = 0; I != NumResults; ++I)
1975 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001976}
1977
Douglas Gregor01dfea02010-01-10 23:08:15 +00001978void Sema::CodeCompleteOrdinaryName(Scope *S,
1979 CodeCompletionContext CompletionContext) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001980 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001981 ResultBuilder Results(*this);
1982
1983 // Determine how to filter results, e.g., so that the names of
1984 // values (functions, enumerators, function templates, etc.) are
1985 // only allowed where we can have an expression.
1986 switch (CompletionContext) {
1987 case CCC_Namespace:
1988 case CCC_Class:
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001989 case CCC_ObjCInterface:
1990 case CCC_ObjCImplementation:
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001991 case CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001992 case CCC_Template:
1993 case CCC_MemberTemplate:
1994 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
1995 break;
1996
1997 case CCC_Expression:
1998 case CCC_Statement:
1999 case CCC_ForInit:
2000 case CCC_Condition:
2001 Results.setFilter(&ResultBuilder::IsOrdinaryName);
2002 break;
2003 }
2004
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00002005 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2006 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002007
2008 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002009 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00002010 Results.ExitScope();
2011
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002012 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002013 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002014 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00002015}
2016
Douglas Gregor95ac6552009-11-18 01:29:26 +00002017static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00002018 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00002019 DeclContext *CurContext,
2020 ResultBuilder &Results) {
2021 typedef CodeCompleteConsumer::Result Result;
2022
2023 // Add properties in this container.
2024 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
2025 PEnd = Container->prop_end();
2026 P != PEnd;
2027 ++P)
2028 Results.MaybeAddResult(Result(*P, 0), CurContext);
2029
2030 // Add properties in referenced protocols.
2031 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
2032 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
2033 PEnd = Protocol->protocol_end();
2034 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002035 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002036 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00002037 if (AllowCategories) {
2038 // Look through categories.
2039 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
2040 Category; Category = Category->getNextClassCategory())
2041 AddObjCProperties(Category, AllowCategories, CurContext, Results);
2042 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002043
2044 // Look through protocols.
2045 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
2046 E = IFace->protocol_end();
2047 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002048 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002049
2050 // Look in the superclass.
2051 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00002052 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
2053 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002054 } else if (const ObjCCategoryDecl *Category
2055 = dyn_cast<ObjCCategoryDecl>(Container)) {
2056 // Look through protocols.
2057 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
2058 PEnd = Category->protocol_end();
2059 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00002060 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002061 }
2062}
2063
Douglas Gregor81b747b2009-09-17 21:32:03 +00002064void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
2065 SourceLocation OpLoc,
2066 bool IsArrow) {
2067 if (!BaseE || !CodeCompleter)
2068 return;
2069
Douglas Gregor86d9a522009-09-21 16:56:56 +00002070 typedef CodeCompleteConsumer::Result Result;
2071
Douglas Gregor81b747b2009-09-17 21:32:03 +00002072 Expr *Base = static_cast<Expr *>(BaseE);
2073 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002074
2075 if (IsArrow) {
2076 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2077 BaseType = Ptr->getPointeeType();
2078 else if (BaseType->isObjCObjectPointerType())
2079 /*Do nothing*/ ;
2080 else
2081 return;
2082 }
2083
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002084 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002085 Results.EnterNewScope();
2086 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2087 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002088 Results.allowNestedNameSpecifiers();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002089 CollectMemberLookupResults(Record->getDecl(), Record->getDecl(), Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002090
Douglas Gregor95ac6552009-11-18 01:29:26 +00002091 if (getLangOptions().CPlusPlus) {
2092 if (!Results.empty()) {
2093 // The "template" keyword can follow "->" or "." in the grammar.
2094 // However, we only want to suggest the template keyword if something
2095 // is dependent.
2096 bool IsDependent = BaseType->isDependentType();
2097 if (!IsDependent) {
2098 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2099 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2100 IsDependent = Ctx->isDependentContext();
2101 break;
2102 }
2103 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002104
Douglas Gregor95ac6552009-11-18 01:29:26 +00002105 if (IsDependent)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002106 Results.MaybeAddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002107 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002108 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002109 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2110 // Objective-C property reference.
2111
2112 // Add property results based on our interface.
2113 const ObjCObjectPointerType *ObjCPtr
2114 = BaseType->getAsObjCInterfacePointerType();
2115 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002116 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002117
2118 // Add properties from the protocols in a qualified interface.
2119 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2120 E = ObjCPtr->qual_end();
2121 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002122 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002123 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
2124 (!IsArrow && BaseType->isObjCInterfaceType())) {
2125 // Objective-C instance variable access.
2126 ObjCInterfaceDecl *Class = 0;
2127 if (const ObjCObjectPointerType *ObjCPtr
2128 = BaseType->getAs<ObjCObjectPointerType>())
2129 Class = ObjCPtr->getInterfaceDecl();
2130 else
2131 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
2132
2133 // Add all ivars from this class and its superclasses.
2134 for (; Class; Class = Class->getSuperClass()) {
2135 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
2136 IVarEnd = Class->ivar_end();
2137 IVar != IVarEnd; ++IVar)
2138 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
2139 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002140 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002141
2142 // FIXME: How do we cope with isa?
2143
2144 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002145
2146 // Add macros
2147 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002148 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002149
2150 // Hand off the results found for code completion.
2151 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002152}
2153
Douglas Gregor374929f2009-09-18 15:37:17 +00002154void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2155 if (!CodeCompleter)
2156 return;
2157
Douglas Gregor86d9a522009-09-21 16:56:56 +00002158 typedef CodeCompleteConsumer::Result Result;
2159 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00002160 switch ((DeclSpec::TST)TagSpec) {
2161 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002162 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00002163 break;
2164
2165 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002166 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00002167 break;
2168
2169 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002170 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002171 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00002172 break;
2173
2174 default:
2175 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2176 return;
2177 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002178
2179 ResultBuilder Results(*this, Filter);
Douglas Gregor45bcd432010-01-14 03:21:49 +00002180 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002181 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2182 LookupVisibleDecls(S, LookupTagName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002183
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002184 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002185 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002186 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002187}
2188
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002189void Sema::CodeCompleteCase(Scope *S) {
2190 if (getSwitchStack().empty() || !CodeCompleter)
2191 return;
2192
2193 SwitchStmt *Switch = getSwitchStack().back();
2194 if (!Switch->getCond()->getType()->isEnumeralType())
2195 return;
2196
2197 // Code-complete the cases of a switch statement over an enumeration type
2198 // by providing the list of
2199 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2200
2201 // Determine which enumerators we have already seen in the switch statement.
2202 // FIXME: Ideally, we would also be able to look *past* the code-completion
2203 // token, in case we are code-completing in the middle of the switch and not
2204 // at the end. However, we aren't able to do so at the moment.
2205 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002206 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002207 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2208 SC = SC->getNextSwitchCase()) {
2209 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2210 if (!Case)
2211 continue;
2212
2213 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2214 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2215 if (EnumConstantDecl *Enumerator
2216 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2217 // We look into the AST of the case statement to determine which
2218 // enumerator was named. Alternatively, we could compute the value of
2219 // the integral constant expression, then compare it against the
2220 // values of each enumerator. However, value-based approach would not
2221 // work as well with C++ templates where enumerators declared within a
2222 // template are type- and value-dependent.
2223 EnumeratorsSeen.insert(Enumerator);
2224
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002225 // If this is a qualified-id, keep track of the nested-name-specifier
2226 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002227 //
2228 // switch (TagD.getKind()) {
2229 // case TagDecl::TK_enum:
2230 // break;
2231 // case XXX
2232 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002233 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002234 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2235 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002236 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002237 }
2238 }
2239
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002240 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2241 // If there are no prior enumerators in C++, check whether we have to
2242 // qualify the names of the enumerators that we suggest, because they
2243 // may not be visible in this scope.
2244 Qualifier = getRequiredQualification(Context, CurContext,
2245 Enum->getDeclContext());
2246
2247 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2248 }
2249
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002250 // Add any enumerators that have not yet been mentioned.
2251 ResultBuilder Results(*this);
2252 Results.EnterNewScope();
2253 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2254 EEnd = Enum->enumerator_end();
2255 E != EEnd; ++E) {
2256 if (EnumeratorsSeen.count(*E))
2257 continue;
2258
Douglas Gregorbca403c2010-01-13 23:51:12 +00002259 Results.MaybeAddResult(CodeCompleteConsumer::Result(*E, Qualifier));
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002260 }
2261 Results.ExitScope();
2262
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002263 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002264 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002265 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002266}
2267
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002268namespace {
2269 struct IsBetterOverloadCandidate {
2270 Sema &S;
2271
2272 public:
2273 explicit IsBetterOverloadCandidate(Sema &S) : S(S) { }
2274
2275 bool
2276 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
2277 return S.isBetterOverloadCandidate(X, Y);
2278 }
2279 };
2280}
2281
2282void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2283 ExprTy **ArgsIn, unsigned NumArgs) {
2284 if (!CodeCompleter)
2285 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002286
2287 // When we're code-completing for a call, we fall back to ordinary
2288 // name code-completion whenever we can't produce specific
2289 // results. We may want to revisit this strategy in the future,
2290 // e.g., by merging the two kinds of results.
2291
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002292 Expr *Fn = (Expr *)FnIn;
2293 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002294
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002295 // Ignore type-dependent call expressions entirely.
2296 if (Fn->isTypeDependent() ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002297 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00002298 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002299 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002300 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002301
John McCall3b4294e2009-12-16 12:17:52 +00002302 // Build an overload candidate set based on the functions we find.
2303 OverloadCandidateSet CandidateSet;
2304
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002305 // FIXME: What if we're calling something that isn't a function declaration?
2306 // FIXME: What if we're calling a pseudo-destructor?
2307 // FIXME: What if we're calling a member function?
2308
John McCall3b4294e2009-12-16 12:17:52 +00002309 Expr *NakedFn = Fn->IgnoreParenCasts();
2310 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2311 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2312 /*PartialOverloading=*/ true);
2313 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2314 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
2315 if (FDecl)
2316 AddOverloadCandidate(FDecl, Args, NumArgs, CandidateSet,
2317 false, false, /*PartialOverloading*/ true);
2318 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002319
2320 // Sort the overload candidate set by placing the best overloads first.
2321 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
2322 IsBetterOverloadCandidate(*this));
2323
2324 // Add the remaining viable overload candidates as code-completion reslults.
Douglas Gregor05944382009-09-23 00:16:58 +00002325 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2326 llvm::SmallVector<ResultCandidate, 8> Results;
Anders Carlsson90756302009-09-22 17:29:51 +00002327
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002328 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2329 CandEnd = CandidateSet.end();
2330 Cand != CandEnd; ++Cand) {
2331 if (Cand->Viable)
Douglas Gregor05944382009-09-23 00:16:58 +00002332 Results.push_back(ResultCandidate(Cand->Function));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002333 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002334
2335 if (Results.empty())
Douglas Gregor01dfea02010-01-10 23:08:15 +00002336 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregoref96eac2009-12-11 19:06:04 +00002337 else
2338 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2339 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002340}
2341
Douglas Gregor81b747b2009-09-17 21:32:03 +00002342void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
2343 bool EnteringContext) {
2344 if (!SS.getScopeRep() || !CodeCompleter)
2345 return;
2346
Douglas Gregor86d9a522009-09-21 16:56:56 +00002347 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2348 if (!Ctx)
2349 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002350
2351 // Try to instantiate any non-dependent declaration contexts before
2352 // we look in them.
2353 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
2354 return;
2355
Douglas Gregor86d9a522009-09-21 16:56:56 +00002356 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002357 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2358 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002359
2360 // The "template" keyword can follow "::" in the grammar, but only
2361 // put it into the grammar if the nested-name-specifier is dependent.
2362 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2363 if (!Results.empty() && NNS->isDependent())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002364 Results.MaybeAddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002365
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002366 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002367 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002368 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002369}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002370
2371void Sema::CodeCompleteUsing(Scope *S) {
2372 if (!CodeCompleter)
2373 return;
2374
Douglas Gregor86d9a522009-09-21 16:56:56 +00002375 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002376 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002377
2378 // If we aren't in class scope, we could see the "namespace" keyword.
2379 if (!S->isClassScope())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002380 Results.MaybeAddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002381
2382 // After "using", we can see anything that would start a
2383 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002384 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2385 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002386 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002387
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002388 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002389 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002390 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002391}
2392
2393void Sema::CodeCompleteUsingDirective(Scope *S) {
2394 if (!CodeCompleter)
2395 return;
2396
Douglas Gregor86d9a522009-09-21 16:56:56 +00002397 // After "using namespace", we expect to see a namespace name or namespace
2398 // alias.
2399 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002400 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002401 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2402 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002403 Results.ExitScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002404 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002405 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002406 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002407}
2408
2409void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2410 if (!CodeCompleter)
2411 return;
2412
Douglas Gregor86d9a522009-09-21 16:56:56 +00002413 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2414 DeclContext *Ctx = (DeclContext *)S->getEntity();
2415 if (!S->getParent())
2416 Ctx = Context.getTranslationUnitDecl();
2417
2418 if (Ctx && Ctx->isFileContext()) {
2419 // We only want to see those namespaces that have already been defined
2420 // within this scope, because its likely that the user is creating an
2421 // extended namespace declaration. Keep track of the most recent
2422 // definition of each namespace.
2423 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2424 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2425 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2426 NS != NSEnd; ++NS)
2427 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2428
2429 // Add the most recent definition (or extended definition) of each
2430 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002431 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002432 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2433 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2434 NS != NSEnd; ++NS)
Douglas Gregor456c4a12009-09-21 20:12:40 +00002435 Results.MaybeAddResult(CodeCompleteConsumer::Result(NS->second, 0),
2436 CurContext);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002437 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002438 }
2439
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002440 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002441 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002442 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002443}
2444
2445void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2446 if (!CodeCompleter)
2447 return;
2448
Douglas Gregor86d9a522009-09-21 16:56:56 +00002449 // After "namespace", we expect to see a namespace or alias.
2450 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002451 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2452 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002453 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002454 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002455 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002456}
2457
Douglas Gregored8d3222009-09-18 20:05:18 +00002458void Sema::CodeCompleteOperatorName(Scope *S) {
2459 if (!CodeCompleter)
2460 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002461
2462 typedef CodeCompleteConsumer::Result Result;
2463 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002464 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00002465
Douglas Gregor86d9a522009-09-21 16:56:56 +00002466 // Add the names of overloadable operators.
2467#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2468 if (std::strcmp(Spelling, "?")) \
Douglas Gregorbca403c2010-01-13 23:51:12 +00002469 Results.MaybeAddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002470#include "clang/Basic/OperatorKinds.def"
2471
2472 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00002473 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002474 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2475 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002476
2477 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00002478 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002479 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002480
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002481 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002482 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002483 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00002484}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002485
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002486// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2487// true or false.
2488#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00002489static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002490 ResultBuilder &Results,
2491 bool NeedAt) {
2492 typedef CodeCompleteConsumer::Result Result;
2493 // Since we have an implementation, we can end it.
Douglas Gregorbca403c2010-01-13 23:51:12 +00002494 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002495
2496 CodeCompletionString *Pattern = 0;
2497 if (LangOpts.ObjC2) {
2498 // @dynamic
2499 Pattern = new CodeCompletionString;
2500 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2501 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2502 Pattern->AddPlaceholderChunk("property");
Douglas Gregorbca403c2010-01-13 23:51:12 +00002503 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002504
2505 // @synthesize
2506 Pattern = new CodeCompletionString;
2507 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2508 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2509 Pattern->AddPlaceholderChunk("property");
Douglas Gregorbca403c2010-01-13 23:51:12 +00002510 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002511 }
2512}
2513
Douglas Gregorbca403c2010-01-13 23:51:12 +00002514static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002515 ResultBuilder &Results,
2516 bool NeedAt) {
2517 typedef CodeCompleteConsumer::Result Result;
2518
2519 // Since we have an interface or protocol, we can end it.
Douglas Gregorbca403c2010-01-13 23:51:12 +00002520 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002521
2522 if (LangOpts.ObjC2) {
2523 // @property
Douglas Gregorbca403c2010-01-13 23:51:12 +00002524 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002525
2526 // @required
Douglas Gregorbca403c2010-01-13 23:51:12 +00002527 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002528
2529 // @optional
Douglas Gregorbca403c2010-01-13 23:51:12 +00002530 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002531 }
2532}
2533
Douglas Gregorbca403c2010-01-13 23:51:12 +00002534static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002535 typedef CodeCompleteConsumer::Result Result;
2536 CodeCompletionString *Pattern = 0;
2537
2538 // @class name ;
2539 Pattern = new CodeCompletionString;
2540 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2541 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2542 Pattern->AddPlaceholderChunk("identifier");
2543 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00002544 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002545
2546 // @interface name
2547 // FIXME: Could introduce the whole pattern, including superclasses and
2548 // such.
2549 Pattern = new CodeCompletionString;
2550 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2551 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2552 Pattern->AddPlaceholderChunk("class");
Douglas Gregorbca403c2010-01-13 23:51:12 +00002553 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002554
2555 // @protocol name
2556 Pattern = new CodeCompletionString;
2557 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2558 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2559 Pattern->AddPlaceholderChunk("protocol");
Douglas Gregorbca403c2010-01-13 23:51:12 +00002560 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002561
2562 // @implementation name
2563 Pattern = new CodeCompletionString;
2564 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2565 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2566 Pattern->AddPlaceholderChunk("class");
Douglas Gregorbca403c2010-01-13 23:51:12 +00002567 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002568
2569 // @compatibility_alias name
2570 Pattern = new CodeCompletionString;
2571 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2572 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2573 Pattern->AddPlaceholderChunk("alias");
2574 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2575 Pattern->AddPlaceholderChunk("class");
Douglas Gregorbca403c2010-01-13 23:51:12 +00002576 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002577}
2578
Douglas Gregorc464ae82009-12-07 09:27:33 +00002579void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2580 bool InInterface) {
2581 typedef CodeCompleteConsumer::Result Result;
2582 ResultBuilder Results(*this);
2583 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002584 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002585 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002586 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002587 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002588 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00002589 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00002590 Results.ExitScope();
2591 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2592}
2593
Douglas Gregorbca403c2010-01-13 23:51:12 +00002594static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002595 typedef CodeCompleteConsumer::Result Result;
2596 CodeCompletionString *Pattern = 0;
2597
2598 // @encode ( type-name )
2599 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002600 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002601 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2602 Pattern->AddPlaceholderChunk("type-name");
2603 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +00002604 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002605
2606 // @protocol ( protocol-name )
2607 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002608 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002609 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2610 Pattern->AddPlaceholderChunk("protocol-name");
2611 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +00002612 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002613
2614 // @selector ( selector )
2615 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002616 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002617 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2618 Pattern->AddPlaceholderChunk("selector");
2619 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregorbca403c2010-01-13 23:51:12 +00002620 Results.MaybeAddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002621}
2622
Douglas Gregorbca403c2010-01-13 23:51:12 +00002623static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002624 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002625 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002626
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002627 // @try { statements } @catch ( declaration ) { statements } @finally
2628 // { statements }
2629 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002630 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002631 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2632 Pattern->AddPlaceholderChunk("statements");
2633 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2634 Pattern->AddTextChunk("@catch");
2635 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2636 Pattern->AddPlaceholderChunk("parameter");
2637 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2638 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2639 Pattern->AddPlaceholderChunk("statements");
2640 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2641 Pattern->AddTextChunk("@finally");
2642 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2643 Pattern->AddPlaceholderChunk("statements");
2644 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorbca403c2010-01-13 23:51:12 +00002645 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002646
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002647 // @throw
2648 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002649 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00002650 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002651 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor834389b2010-01-12 06:38:28 +00002652 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregorbca403c2010-01-13 23:51:12 +00002653 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002654
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002655 // @synchronized ( expression ) { statements }
2656 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002657 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
Douglas Gregor834389b2010-01-12 06:38:28 +00002658 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002659 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2660 Pattern->AddPlaceholderChunk("expression");
2661 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2662 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2663 Pattern->AddPlaceholderChunk("statements");
2664 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregorbca403c2010-01-13 23:51:12 +00002665 Results.MaybeAddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002666}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002667
Douglas Gregorbca403c2010-01-13 23:51:12 +00002668static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002669 ResultBuilder &Results,
2670 bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002671 typedef CodeCompleteConsumer::Result Result;
Douglas Gregorbca403c2010-01-13 23:51:12 +00002672 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2673 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2674 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002675 if (LangOpts.ObjC2)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002676 Results.MaybeAddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002677}
2678
2679void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2680 ResultBuilder Results(*this);
2681 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002682 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002683 Results.ExitScope();
2684 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2685}
2686
2687void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002688 ResultBuilder Results(*this);
2689 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002690 AddObjCStatementResults(Results, false);
2691 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002692 Results.ExitScope();
2693 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2694}
2695
2696void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2697 ResultBuilder Results(*this);
2698 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002699 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002700 Results.ExitScope();
2701 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2702}
2703
Douglas Gregor988358f2009-11-19 00:14:45 +00002704/// \brief Determine whether the addition of the given flag to an Objective-C
2705/// property's attributes will cause a conflict.
2706static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2707 // Check if we've already added this flag.
2708 if (Attributes & NewFlag)
2709 return true;
2710
2711 Attributes |= NewFlag;
2712
2713 // Check for collisions with "readonly".
2714 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2715 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2716 ObjCDeclSpec::DQ_PR_assign |
2717 ObjCDeclSpec::DQ_PR_copy |
2718 ObjCDeclSpec::DQ_PR_retain)))
2719 return true;
2720
2721 // Check for more than one of { assign, copy, retain }.
2722 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2723 ObjCDeclSpec::DQ_PR_copy |
2724 ObjCDeclSpec::DQ_PR_retain);
2725 if (AssignCopyRetMask &&
2726 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2727 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2728 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2729 return true;
2730
2731 return false;
2732}
2733
Douglas Gregora93b1082009-11-18 23:08:07 +00002734void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00002735 if (!CodeCompleter)
2736 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00002737
Steve Naroffece8e712009-10-08 21:55:05 +00002738 unsigned Attributes = ODS.getPropertyAttributes();
2739
2740 typedef CodeCompleteConsumer::Result Result;
2741 ResultBuilder Results(*this);
2742 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00002743 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregorbca403c2010-01-13 23:51:12 +00002744 Results.MaybeAddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002745 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregorbca403c2010-01-13 23:51:12 +00002746 Results.MaybeAddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002747 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregorbca403c2010-01-13 23:51:12 +00002748 Results.MaybeAddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002749 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregorbca403c2010-01-13 23:51:12 +00002750 Results.MaybeAddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002751 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregorbca403c2010-01-13 23:51:12 +00002752 Results.MaybeAddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002753 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregorbca403c2010-01-13 23:51:12 +00002754 Results.MaybeAddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002755 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002756 CodeCompletionString *Setter = new CodeCompletionString;
2757 Setter->AddTypedTextChunk("setter");
2758 Setter->AddTextChunk(" = ");
2759 Setter->AddPlaceholderChunk("method");
Douglas Gregorbca403c2010-01-13 23:51:12 +00002760 Results.MaybeAddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00002761 }
Douglas Gregor988358f2009-11-19 00:14:45 +00002762 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002763 CodeCompletionString *Getter = new CodeCompletionString;
2764 Getter->AddTypedTextChunk("getter");
2765 Getter->AddTextChunk(" = ");
2766 Getter->AddPlaceholderChunk("method");
Douglas Gregorbca403c2010-01-13 23:51:12 +00002767 Results.MaybeAddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00002768 }
Steve Naroffece8e712009-10-08 21:55:05 +00002769 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002770 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00002771}
Steve Naroffc4df6d22009-11-07 02:08:14 +00002772
Douglas Gregor4ad96852009-11-19 07:41:15 +00002773/// \brief Descripts the kind of Objective-C method that we want to find
2774/// via code completion.
2775enum ObjCMethodKind {
2776 MK_Any, //< Any kind of method, provided it means other specified criteria.
2777 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2778 MK_OneArgSelector //< One-argument selector.
2779};
2780
2781static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2782 ObjCMethodKind WantKind,
2783 IdentifierInfo **SelIdents,
2784 unsigned NumSelIdents) {
2785 Selector Sel = Method->getSelector();
2786 if (NumSelIdents > Sel.getNumArgs())
2787 return false;
2788
2789 switch (WantKind) {
2790 case MK_Any: break;
2791 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2792 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2793 }
2794
2795 for (unsigned I = 0; I != NumSelIdents; ++I)
2796 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2797 return false;
2798
2799 return true;
2800}
2801
Douglas Gregor36ecb042009-11-17 23:22:23 +00002802/// \brief Add all of the Objective-C methods in the given Objective-C
2803/// container to the set of results.
2804///
2805/// The container will be a class, protocol, category, or implementation of
2806/// any of the above. This mether will recurse to include methods from
2807/// the superclasses of classes along with their categories, protocols, and
2808/// implementations.
2809///
2810/// \param Container the container in which we'll look to find methods.
2811///
2812/// \param WantInstance whether to add instance methods (only); if false, this
2813/// routine will add factory methods (only).
2814///
2815/// \param CurContext the context in which we're performing the lookup that
2816/// finds methods.
2817///
2818/// \param Results the structure into which we'll add results.
2819static void AddObjCMethods(ObjCContainerDecl *Container,
2820 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00002821 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00002822 IdentifierInfo **SelIdents,
2823 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00002824 DeclContext *CurContext,
2825 ResultBuilder &Results) {
2826 typedef CodeCompleteConsumer::Result Result;
2827 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2828 MEnd = Container->meth_end();
2829 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002830 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2831 // Check whether the selector identifiers we've been given are a
2832 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002833 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00002834 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002835
Douglas Gregord3c68542009-11-19 01:08:35 +00002836 Result R = Result(*M, 0);
2837 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002838 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00002839 Results.MaybeAddResult(R, CurContext);
2840 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00002841 }
2842
2843 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2844 if (!IFace)
2845 return;
2846
2847 // Add methods in protocols.
2848 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2849 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2850 E = Protocols.end();
2851 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002852 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00002853 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002854
2855 // Add methods in categories.
2856 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2857 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00002858 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2859 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002860
2861 // Add a categories protocol methods.
2862 const ObjCList<ObjCProtocolDecl> &Protocols
2863 = CatDecl->getReferencedProtocols();
2864 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2865 E = Protocols.end();
2866 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002867 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2868 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002869
2870 // Add methods in category implementations.
2871 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002872 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2873 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002874 }
2875
2876 // Add methods in superclass.
2877 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002878 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2879 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002880
2881 // Add methods in our implementation, if any.
2882 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002883 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2884 NumSelIdents, CurContext, Results);
2885}
2886
2887
2888void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2889 DeclPtrTy *Methods,
2890 unsigned NumMethods) {
2891 typedef CodeCompleteConsumer::Result Result;
2892
2893 // Try to find the interface where getters might live.
2894 ObjCInterfaceDecl *Class
2895 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2896 if (!Class) {
2897 if (ObjCCategoryDecl *Category
2898 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2899 Class = Category->getClassInterface();
2900
2901 if (!Class)
2902 return;
2903 }
2904
2905 // Find all of the potential getters.
2906 ResultBuilder Results(*this);
2907 Results.EnterNewScope();
2908
2909 // FIXME: We need to do this because Objective-C methods don't get
2910 // pushed into DeclContexts early enough. Argh!
2911 for (unsigned I = 0; I != NumMethods; ++I) {
2912 if (ObjCMethodDecl *Method
2913 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2914 if (Method->isInstanceMethod() &&
2915 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2916 Result R = Result(Method, 0);
2917 R.AllParametersAreInformative = true;
2918 Results.MaybeAddResult(R, CurContext);
2919 }
2920 }
2921
2922 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2923 Results.ExitScope();
2924 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2925}
2926
2927void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2928 DeclPtrTy *Methods,
2929 unsigned NumMethods) {
2930 typedef CodeCompleteConsumer::Result Result;
2931
2932 // Try to find the interface where setters might live.
2933 ObjCInterfaceDecl *Class
2934 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2935 if (!Class) {
2936 if (ObjCCategoryDecl *Category
2937 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2938 Class = Category->getClassInterface();
2939
2940 if (!Class)
2941 return;
2942 }
2943
2944 // Find all of the potential getters.
2945 ResultBuilder Results(*this);
2946 Results.EnterNewScope();
2947
2948 // FIXME: We need to do this because Objective-C methods don't get
2949 // pushed into DeclContexts early enough. Argh!
2950 for (unsigned I = 0; I != NumMethods; ++I) {
2951 if (ObjCMethodDecl *Method
2952 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2953 if (Method->isInstanceMethod() &&
2954 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2955 Result R = Result(Method, 0);
2956 R.AllParametersAreInformative = true;
2957 Results.MaybeAddResult(R, CurContext);
2958 }
2959 }
2960
2961 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2962
2963 Results.ExitScope();
2964 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00002965}
2966
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002967void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregord3c68542009-11-19 01:08:35 +00002968 SourceLocation FNameLoc,
2969 IdentifierInfo **SelIdents,
2970 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002971 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00002972 ObjCInterfaceDecl *CDecl = 0;
2973
Douglas Gregor24a069f2009-11-17 17:59:40 +00002974 if (FName->isStr("super")) {
2975 // We're sending a message to "super".
2976 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2977 // Figure out which interface we're in.
2978 CDecl = CurMethod->getClassInterface();
2979 if (!CDecl)
2980 return;
2981
2982 // Find the superclass of this class.
2983 CDecl = CDecl->getSuperClass();
2984 if (!CDecl)
2985 return;
2986
2987 if (CurMethod->isInstanceMethod()) {
2988 // We are inside an instance method, which means that the message
2989 // send [super ...] is actually calling an instance method on the
2990 // current object. Build the super expression and handle this like
2991 // an instance method.
2992 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2993 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2994 OwningExprResult Super
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002995 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregord3c68542009-11-19 01:08:35 +00002996 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2997 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002998 }
2999
3000 // Okay, we're calling a factory method in our superclass.
3001 }
3002 }
3003
3004 // If the given name refers to an interface type, retrieve the
3005 // corresponding declaration.
3006 if (!CDecl)
Douglas Gregor60b01cc2009-11-17 23:31:36 +00003007 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor24a069f2009-11-17 17:59:40 +00003008 QualType T = GetTypeFromParser(Ty, 0);
3009 if (!T.isNull())
3010 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
3011 CDecl = Interface->getDecl();
3012 }
3013
3014 if (!CDecl && FName->isStr("super")) {
3015 // "super" may be the name of a variable, in which case we are
3016 // probably calling an instance method.
John McCallf7a1a742009-11-24 19:00:30 +00003017 CXXScopeSpec SS;
3018 UnqualifiedId id;
3019 id.setIdentifier(FName, FNameLoc);
3020 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregord3c68542009-11-19 01:08:35 +00003021 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
3022 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00003023 }
3024
Douglas Gregor36ecb042009-11-17 23:22:23 +00003025 // Add all of the factory methods in this Objective-C class, its protocols,
3026 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00003027 ResultBuilder Results(*this);
3028 Results.EnterNewScope();
Douglas Gregor4ad96852009-11-19 07:41:15 +00003029 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
3030 Results);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003031 Results.ExitScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00003032
Steve Naroffc4df6d22009-11-07 02:08:14 +00003033 // This also suppresses remaining diagnostics.
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003034 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003035}
3036
Douglas Gregord3c68542009-11-19 01:08:35 +00003037void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
3038 IdentifierInfo **SelIdents,
3039 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00003040 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00003041
3042 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00003043
Douglas Gregor36ecb042009-11-17 23:22:23 +00003044 // If necessary, apply function/array conversion to the receiver.
3045 // C99 6.7.5.3p[7,8].
3046 DefaultFunctionArrayConversion(RecExpr);
3047 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00003048
Douglas Gregor36ecb042009-11-17 23:22:23 +00003049 if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType()) {
3050 // FIXME: We're messaging 'id'. Do we actually want to look up every method
3051 // in the universe?
3052 return;
3053 }
3054
Douglas Gregor36ecb042009-11-17 23:22:23 +00003055 // Build the set of methods we can see.
3056 ResultBuilder Results(*this);
3057 Results.EnterNewScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00003058
Douglas Gregorf74a4192009-11-18 00:06:18 +00003059 // Handle messages to Class. This really isn't a message to an instance
3060 // method, so we treat it the same way we would treat a message send to a
3061 // class method.
3062 if (ReceiverType->isObjCClassType() ||
3063 ReceiverType->isObjCQualifiedClassType()) {
3064 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3065 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003066 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3067 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003068 }
3069 }
3070 // Handle messages to a qualified ID ("id<foo>").
3071 else if (const ObjCObjectPointerType *QualID
3072 = ReceiverType->getAsObjCQualifiedIdType()) {
3073 // Search protocols for instance methods.
3074 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3075 E = QualID->qual_end();
3076 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003077 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3078 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003079 }
3080 // Handle messages to a pointer to interface type.
3081 else if (const ObjCObjectPointerType *IFacePtr
3082 = ReceiverType->getAsObjCInterfacePointerType()) {
3083 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003084 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3085 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003086
3087 // Search protocols for instance methods.
3088 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3089 E = IFacePtr->qual_end();
3090 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003091 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3092 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003093 }
3094
Steve Naroffc4df6d22009-11-07 02:08:14 +00003095 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003096 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003097}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003098
3099/// \brief Add all of the protocol declarations that we find in the given
3100/// (translation unit) context.
3101static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003102 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003103 ResultBuilder &Results) {
3104 typedef CodeCompleteConsumer::Result Result;
3105
3106 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3107 DEnd = Ctx->decls_end();
3108 D != DEnd; ++D) {
3109 // Record any protocols we find.
3110 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003111 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
3112 Results.MaybeAddResult(Result(Proto, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003113
3114 // Record any forward-declared protocols we find.
3115 if (ObjCForwardProtocolDecl *Forward
3116 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3117 for (ObjCForwardProtocolDecl::protocol_iterator
3118 P = Forward->protocol_begin(),
3119 PEnd = Forward->protocol_end();
3120 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003121 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
3122 Results.MaybeAddResult(Result(*P, 0), CurContext);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003123 }
3124 }
3125}
3126
3127void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3128 unsigned NumProtocols) {
3129 ResultBuilder Results(*this);
3130 Results.EnterNewScope();
3131
3132 // Tell the result set to ignore all of the protocols we have
3133 // already seen.
3134 for (unsigned I = 0; I != NumProtocols; ++I)
3135 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
3136 Results.Ignore(Protocol);
3137
3138 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003139 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3140 Results);
3141
3142 Results.ExitScope();
3143 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3144}
3145
3146void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3147 ResultBuilder Results(*this);
3148 Results.EnterNewScope();
3149
3150 // Add all protocols.
3151 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3152 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003153
3154 Results.ExitScope();
3155 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3156}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003157
3158/// \brief Add all of the Objective-C interface declarations that we find in
3159/// the given (translation unit) context.
3160static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3161 bool OnlyForwardDeclarations,
3162 bool OnlyUnimplemented,
3163 ResultBuilder &Results) {
3164 typedef CodeCompleteConsumer::Result Result;
3165
3166 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3167 DEnd = Ctx->decls_end();
3168 D != DEnd; ++D) {
3169 // Record any interfaces we find.
3170 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3171 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3172 (!OnlyUnimplemented || !Class->getImplementation()))
3173 Results.MaybeAddResult(Result(Class, 0), CurContext);
3174
3175 // Record any forward-declared interfaces we find.
3176 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3177 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3178 C != CEnd; ++C)
3179 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3180 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
3181 Results.MaybeAddResult(Result(C->getInterface(), 0), CurContext);
3182 }
3183 }
3184}
3185
3186void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3187 ResultBuilder Results(*this);
3188 Results.EnterNewScope();
3189
3190 // Add all classes.
3191 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3192 false, Results);
3193
3194 Results.ExitScope();
3195 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3196}
3197
3198void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
3199 ResultBuilder Results(*this);
3200 Results.EnterNewScope();
3201
3202 // Make sure that we ignore the class we're currently defining.
3203 NamedDecl *CurClass
3204 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003205 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003206 Results.Ignore(CurClass);
3207
3208 // Add all classes.
3209 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3210 false, Results);
3211
3212 Results.ExitScope();
3213 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3214}
3215
3216void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3217 ResultBuilder Results(*this);
3218 Results.EnterNewScope();
3219
3220 // Add all unimplemented classes.
3221 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3222 true, Results);
3223
3224 Results.ExitScope();
3225 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3226}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003227
3228void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
3229 IdentifierInfo *ClassName) {
3230 typedef CodeCompleteConsumer::Result Result;
3231
3232 ResultBuilder Results(*this);
3233
3234 // Ignore any categories we find that have already been implemented by this
3235 // interface.
3236 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3237 NamedDecl *CurClass
3238 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3239 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3240 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3241 Category = Category->getNextClassCategory())
3242 CategoryNames.insert(Category->getIdentifier());
3243
3244 // Add all of the categories we know about.
3245 Results.EnterNewScope();
3246 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3247 for (DeclContext::decl_iterator D = TU->decls_begin(),
3248 DEnd = TU->decls_end();
3249 D != DEnd; ++D)
3250 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3251 if (CategoryNames.insert(Category->getIdentifier()))
3252 Results.MaybeAddResult(Result(Category, 0), CurContext);
3253 Results.ExitScope();
3254
3255 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3256}
3257
3258void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
3259 IdentifierInfo *ClassName) {
3260 typedef CodeCompleteConsumer::Result Result;
3261
3262 // Find the corresponding interface. If we couldn't find the interface, the
3263 // program itself is ill-formed. However, we'll try to be helpful still by
3264 // providing the list of all of the categories we know about.
3265 NamedDecl *CurClass
3266 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3267 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3268 if (!Class)
3269 return CodeCompleteObjCInterfaceCategory(S, ClassName);
3270
3271 ResultBuilder Results(*this);
3272
3273 // Add all of the categories that have have corresponding interface
3274 // declarations in this class and any of its superclasses, except for
3275 // already-implemented categories in the class itself.
3276 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3277 Results.EnterNewScope();
3278 bool IgnoreImplemented = true;
3279 while (Class) {
3280 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3281 Category = Category->getNextClassCategory())
3282 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3283 CategoryNames.insert(Category->getIdentifier()))
3284 Results.MaybeAddResult(Result(Category, 0), CurContext);
3285
3286 Class = Class->getSuperClass();
3287 IgnoreImplemented = false;
3288 }
3289 Results.ExitScope();
3290
3291 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3292}
Douglas Gregor322328b2009-11-18 22:32:06 +00003293
Douglas Gregor424b2a52009-11-18 22:56:13 +00003294void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00003295 typedef CodeCompleteConsumer::Result Result;
3296 ResultBuilder Results(*this);
3297
3298 // Figure out where this @synthesize lives.
3299 ObjCContainerDecl *Container
3300 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3301 if (!Container ||
3302 (!isa<ObjCImplementationDecl>(Container) &&
3303 !isa<ObjCCategoryImplDecl>(Container)))
3304 return;
3305
3306 // Ignore any properties that have already been implemented.
3307 for (DeclContext::decl_iterator D = Container->decls_begin(),
3308 DEnd = Container->decls_end();
3309 D != DEnd; ++D)
3310 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3311 Results.Ignore(PropertyImpl->getPropertyDecl());
3312
3313 // Add any properties that we find.
3314 Results.EnterNewScope();
3315 if (ObjCImplementationDecl *ClassImpl
3316 = dyn_cast<ObjCImplementationDecl>(Container))
3317 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3318 Results);
3319 else
3320 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3321 false, CurContext, Results);
3322 Results.ExitScope();
3323
3324 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3325}
3326
3327void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3328 IdentifierInfo *PropertyName,
3329 DeclPtrTy ObjCImpDecl) {
3330 typedef CodeCompleteConsumer::Result Result;
3331 ResultBuilder Results(*this);
3332
3333 // Figure out where this @synthesize lives.
3334 ObjCContainerDecl *Container
3335 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3336 if (!Container ||
3337 (!isa<ObjCImplementationDecl>(Container) &&
3338 !isa<ObjCCategoryImplDecl>(Container)))
3339 return;
3340
3341 // Figure out which interface we're looking into.
3342 ObjCInterfaceDecl *Class = 0;
3343 if (ObjCImplementationDecl *ClassImpl
3344 = dyn_cast<ObjCImplementationDecl>(Container))
3345 Class = ClassImpl->getClassInterface();
3346 else
3347 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3348 ->getClassInterface();
3349
3350 // Add all of the instance variables in this class and its superclasses.
3351 Results.EnterNewScope();
3352 for(; Class; Class = Class->getSuperClass()) {
3353 // FIXME: We could screen the type of each ivar for compatibility with
3354 // the property, but is that being too paternal?
3355 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3356 IVarEnd = Class->ivar_end();
3357 IVar != IVarEnd; ++IVar)
3358 Results.MaybeAddResult(Result(*IVar, 0), CurContext);
3359 }
3360 Results.ExitScope();
3361
3362 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3363}