blob: df14aa7fc5a476006959beebbb84d93d8a9042e2 [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.
Douglas Gregor0cc84042010-01-14 15:47:35 +0000181 ///
182 /// \param InBaseClass whether the result was found in a base
183 /// class of the searched context.
184 void AddResult(Result R, DeclContext *CurContext, NamedDecl *Hiding,
185 bool InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000186
Douglas Gregora4477812010-01-14 16:01:26 +0000187 /// \brief Add a new non-declaration result to this result set.
188 void AddResult(Result R);
189
Douglas Gregor86d9a522009-09-21 16:56:56 +0000190 /// \brief Enter into a new scope.
191 void EnterNewScope();
192
193 /// \brief Exit from the current scope.
194 void ExitScope();
195
Douglas Gregor55385fe2009-11-18 04:19:12 +0000196 /// \brief Ignore this declaration, if it is seen again.
197 void Ignore(Decl *D) { AllDeclsFound.insert(D->getCanonicalDecl()); }
198
Douglas Gregor86d9a522009-09-21 16:56:56 +0000199 /// \name Name lookup predicates
200 ///
201 /// These predicates can be passed to the name lookup functions to filter the
202 /// results of name lookup. All of the predicates have the same type, so that
203 ///
204 //@{
Douglas Gregor791215b2009-09-21 20:51:25 +0000205 bool IsOrdinaryName(NamedDecl *ND) const;
Douglas Gregor01dfea02010-01-10 23:08:15 +0000206 bool IsOrdinaryNonValueName(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000207 bool IsNestedNameSpecifier(NamedDecl *ND) const;
208 bool IsEnum(NamedDecl *ND) const;
209 bool IsClassOrStruct(NamedDecl *ND) const;
210 bool IsUnion(NamedDecl *ND) const;
211 bool IsNamespace(NamedDecl *ND) const;
212 bool IsNamespaceOrAlias(NamedDecl *ND) const;
213 bool IsType(NamedDecl *ND) const;
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000214 bool IsMember(NamedDecl *ND) const;
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000215 bool IsObjCIvar(NamedDecl *ND) const;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000216 //@}
217 };
218}
219
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000220class ResultBuilder::ShadowMapEntry::iterator {
221 llvm::PointerUnion<NamedDecl*, const DeclIndexPair*> DeclOrIterator;
222 unsigned SingleDeclIndex;
223
224public:
225 typedef DeclIndexPair value_type;
226 typedef value_type reference;
227 typedef std::ptrdiff_t difference_type;
228 typedef std::input_iterator_tag iterator_category;
229
230 class pointer {
231 DeclIndexPair Value;
232
233 public:
234 pointer(const DeclIndexPair &Value) : Value(Value) { }
235
236 const DeclIndexPair *operator->() const {
237 return &Value;
238 }
239 };
240
241 iterator() : DeclOrIterator((NamedDecl *)0), SingleDeclIndex(0) { }
242
243 iterator(NamedDecl *SingleDecl, unsigned Index)
244 : DeclOrIterator(SingleDecl), SingleDeclIndex(Index) { }
245
246 iterator(const DeclIndexPair *Iterator)
247 : DeclOrIterator(Iterator), SingleDeclIndex(0) { }
248
249 iterator &operator++() {
250 if (DeclOrIterator.is<NamedDecl *>()) {
251 DeclOrIterator = (NamedDecl *)0;
252 SingleDeclIndex = 0;
253 return *this;
254 }
255
256 const DeclIndexPair *I = DeclOrIterator.get<const DeclIndexPair*>();
257 ++I;
258 DeclOrIterator = I;
259 return *this;
260 }
261
262 iterator operator++(int) {
263 iterator tmp(*this);
264 ++(*this);
265 return tmp;
266 }
267
268 reference operator*() const {
269 if (NamedDecl *ND = DeclOrIterator.dyn_cast<NamedDecl *>())
270 return reference(ND, SingleDeclIndex);
271
Douglas Gregord490f952009-12-06 21:27:58 +0000272 return *DeclOrIterator.get<const DeclIndexPair*>();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000273 }
274
275 pointer operator->() const {
276 return pointer(**this);
277 }
278
279 friend bool operator==(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000280 return X.DeclOrIterator.getOpaqueValue()
281 == Y.DeclOrIterator.getOpaqueValue() &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000282 X.SingleDeclIndex == Y.SingleDeclIndex;
283 }
284
285 friend bool operator!=(const iterator &X, const iterator &Y) {
Douglas Gregord490f952009-12-06 21:27:58 +0000286 return !(X == Y);
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000287 }
288};
289
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000290ResultBuilder::ShadowMapEntry::iterator
291ResultBuilder::ShadowMapEntry::begin() const {
292 if (DeclOrVector.isNull())
293 return iterator();
294
295 if (NamedDecl *ND = DeclOrVector.dyn_cast<NamedDecl *>())
296 return iterator(ND, SingleDeclIndex);
297
298 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->begin());
299}
300
301ResultBuilder::ShadowMapEntry::iterator
302ResultBuilder::ShadowMapEntry::end() const {
303 if (DeclOrVector.is<NamedDecl *>() || DeclOrVector.isNull())
304 return iterator();
305
306 return iterator(DeclOrVector.get<DeclIndexPairVector *>()->end());
307}
308
Douglas Gregor456c4a12009-09-21 20:12:40 +0000309/// \brief Compute the qualification required to get from the current context
310/// (\p CurContext) to the target context (\p TargetContext).
311///
312/// \param Context the AST context in which the qualification will be used.
313///
314/// \param CurContext the context where an entity is being named, which is
315/// typically based on the current scope.
316///
317/// \param TargetContext the context in which the named entity actually
318/// resides.
319///
320/// \returns a nested name specifier that refers into the target context, or
321/// NULL if no qualification is needed.
322static NestedNameSpecifier *
323getRequiredQualification(ASTContext &Context,
324 DeclContext *CurContext,
325 DeclContext *TargetContext) {
326 llvm::SmallVector<DeclContext *, 4> TargetParents;
327
328 for (DeclContext *CommonAncestor = TargetContext;
329 CommonAncestor && !CommonAncestor->Encloses(CurContext);
330 CommonAncestor = CommonAncestor->getLookupParent()) {
331 if (CommonAncestor->isTransparentContext() ||
332 CommonAncestor->isFunctionOrMethod())
333 continue;
334
335 TargetParents.push_back(CommonAncestor);
336 }
337
338 NestedNameSpecifier *Result = 0;
339 while (!TargetParents.empty()) {
340 DeclContext *Parent = TargetParents.back();
341 TargetParents.pop_back();
342
343 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Parent))
344 Result = NestedNameSpecifier::Create(Context, Result, Namespace);
345 else if (TagDecl *TD = dyn_cast<TagDecl>(Parent))
346 Result = NestedNameSpecifier::Create(Context, Result,
347 false,
348 Context.getTypeDeclType(TD).getTypePtr());
349 else
350 assert(Parent->isTranslationUnit());
Douglas Gregor0c8296d2009-11-07 00:00:49 +0000351 }
Douglas Gregor456c4a12009-09-21 20:12:40 +0000352 return Result;
353}
354
Douglas Gregor45bcd432010-01-14 03:21:49 +0000355bool ResultBuilder::isInterestingDecl(NamedDecl *ND,
356 bool &AsNestedNameSpecifier) const {
357 AsNestedNameSpecifier = false;
358
Douglas Gregore495b7f2010-01-14 00:20:49 +0000359 ND = ND->getUnderlyingDecl();
360 unsigned IDNS = ND->getIdentifierNamespace();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000361
362 // Skip unnamed entities.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000363 if (!ND->getDeclName())
364 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000365
366 // Friend declarations and declarations introduced due to friends are never
367 // added as results.
John McCall92b7f702010-03-11 07:50:04 +0000368 if (IDNS & (Decl::IDNS_OrdinaryFriend | Decl::IDNS_TagFriend))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000369 return false;
370
Douglas Gregor76282942009-12-11 17:31:05 +0000371 // Class template (partial) specializations are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000372 if (isa<ClassTemplateSpecializationDecl>(ND) ||
373 isa<ClassTemplatePartialSpecializationDecl>(ND))
374 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000375
Douglas Gregor76282942009-12-11 17:31:05 +0000376 // Using declarations themselves are never added as results.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000377 if (isa<UsingDecl>(ND))
378 return false;
379
380 // Some declarations have reserved names that we don't want to ever show.
381 if (const IdentifierInfo *Id = ND->getIdentifier()) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000382 // __va_list_tag is a freak of nature. Find it and skip it.
383 if (Id->isStr("__va_list_tag") || Id->isStr("__builtin_va_list"))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000384 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000385
Douglas Gregorf52cede2009-10-09 22:16:47 +0000386 // Filter out names reserved for the implementation (C99 7.1.3,
387 // C++ [lib.global.names]). Users don't need to see those.
Daniel Dunbare013d682009-10-18 20:26:12 +0000388 //
389 // FIXME: Add predicate for this.
Douglas Gregorf52cede2009-10-09 22:16:47 +0000390 if (Id->getLength() >= 2) {
Daniel Dunbare013d682009-10-18 20:26:12 +0000391 const char *Name = Id->getNameStart();
Douglas Gregorf52cede2009-10-09 22:16:47 +0000392 if (Name[0] == '_' &&
393 (Name[1] == '_' || (Name[1] >= 'A' && Name[1] <= 'Z')))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000394 return false;
Douglas Gregorf52cede2009-10-09 22:16:47 +0000395 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000396 }
Douglas Gregore495b7f2010-01-14 00:20:49 +0000397
Douglas Gregor86d9a522009-09-21 16:56:56 +0000398 // C++ constructors are never found by name lookup.
Douglas Gregore495b7f2010-01-14 00:20:49 +0000399 if (isa<CXXConstructorDecl>(ND))
400 return false;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000401
402 // Filter out any unwanted results.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000403 if (Filter && !(this->*Filter)(ND)) {
404 // Check whether it is interesting as a nested-name-specifier.
405 if (AllowNestedNameSpecifiers && SemaRef.getLangOptions().CPlusPlus &&
406 IsNestedNameSpecifier(ND) &&
407 (Filter != &ResultBuilder::IsMember ||
408 (isa<CXXRecordDecl>(ND) &&
409 cast<CXXRecordDecl>(ND)->isInjectedClassName()))) {
410 AsNestedNameSpecifier = true;
411 return true;
412 }
413
Douglas Gregore495b7f2010-01-14 00:20:49 +0000414 return false;
Douglas Gregor45bcd432010-01-14 03:21:49 +0000415 }
Douglas Gregor86d9a522009-09-21 16:56:56 +0000416
Douglas Gregore495b7f2010-01-14 00:20:49 +0000417 // ... then it must be interesting!
418 return true;
419}
420
Douglas Gregor6660d842010-01-14 00:41:07 +0000421bool ResultBuilder::CheckHiddenResult(Result &R, DeclContext *CurContext,
422 NamedDecl *Hiding) {
423 // In C, there is no way to refer to a hidden name.
424 // FIXME: This isn't true; we can find a tag name hidden by an ordinary
425 // name if we introduce the tag type.
426 if (!SemaRef.getLangOptions().CPlusPlus)
427 return true;
428
429 DeclContext *HiddenCtx = R.Declaration->getDeclContext()->getLookupContext();
430
431 // There is no way to qualify a name declared in a function or method.
432 if (HiddenCtx->isFunctionOrMethod())
433 return true;
434
435 if (HiddenCtx == Hiding->getDeclContext()->getLookupContext())
436 return true;
437
438 // We can refer to the result with the appropriate qualification. Do it.
439 R.Hidden = true;
440 R.QualifierIsInformative = false;
441
442 if (!R.Qualifier)
443 R.Qualifier = getRequiredQualification(SemaRef.Context,
444 CurContext,
445 R.Declaration->getDeclContext());
446 return false;
447}
448
Douglas Gregore495b7f2010-01-14 00:20:49 +0000449void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
450 assert(!ShadowMaps.empty() && "Must enter into a results scope");
451
452 if (R.Kind != Result::RK_Declaration) {
453 // For non-declaration results, just add the result.
454 Results.push_back(R);
455 return;
456 }
457
458 // Look through using declarations.
459 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
460 MaybeAddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext);
461 return;
462 }
463
464 Decl *CanonDecl = R.Declaration->getCanonicalDecl();
465 unsigned IDNS = CanonDecl->getIdentifierNamespace();
466
Douglas Gregor45bcd432010-01-14 03:21:49 +0000467 bool AsNestedNameSpecifier = false;
468 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregore495b7f2010-01-14 00:20:49 +0000469 return;
470
Douglas Gregor86d9a522009-09-21 16:56:56 +0000471 ShadowMap &SMap = ShadowMaps.back();
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000472 ShadowMapEntry::iterator I, IEnd;
473 ShadowMap::iterator NamePos = SMap.find(R.Declaration->getDeclName());
474 if (NamePos != SMap.end()) {
475 I = NamePos->second.begin();
476 IEnd = NamePos->second.end();
477 }
478
479 for (; I != IEnd; ++I) {
480 NamedDecl *ND = I->first;
481 unsigned Index = I->second;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000482 if (ND->getCanonicalDecl() == CanonDecl) {
483 // This is a redeclaration. Always pick the newer declaration.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000484 Results[Index].Declaration = R.Declaration;
485
Douglas Gregor86d9a522009-09-21 16:56:56 +0000486 // We're done.
487 return;
488 }
489 }
490
491 // This is a new declaration in this scope. However, check whether this
492 // declaration name is hidden by a similarly-named declaration in an outer
493 // scope.
494 std::list<ShadowMap>::iterator SM, SMEnd = ShadowMaps.end();
495 --SMEnd;
496 for (SM = ShadowMaps.begin(); SM != SMEnd; ++SM) {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000497 ShadowMapEntry::iterator I, IEnd;
498 ShadowMap::iterator NamePos = SM->find(R.Declaration->getDeclName());
499 if (NamePos != SM->end()) {
500 I = NamePos->second.begin();
501 IEnd = NamePos->second.end();
502 }
503 for (; I != IEnd; ++I) {
Douglas Gregor86d9a522009-09-21 16:56:56 +0000504 // A tag declaration does not hide a non-tag declaration.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000505 if (I->first->getIdentifierNamespace() == Decl::IDNS_Tag &&
Douglas Gregor86d9a522009-09-21 16:56:56 +0000506 (IDNS & (Decl::IDNS_Member | Decl::IDNS_Ordinary |
507 Decl::IDNS_ObjCProtocol)))
508 continue;
509
510 // Protocols are in distinct namespaces from everything else.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000511 if (((I->first->getIdentifierNamespace() & Decl::IDNS_ObjCProtocol)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000512 || (IDNS & Decl::IDNS_ObjCProtocol)) &&
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000513 I->first->getIdentifierNamespace() != IDNS)
Douglas Gregor86d9a522009-09-21 16:56:56 +0000514 continue;
515
516 // The newly-added result is hidden by an entry in the shadow map.
Douglas Gregor6660d842010-01-14 00:41:07 +0000517 if (CheckHiddenResult(R, CurContext, I->first))
Douglas Gregor86d9a522009-09-21 16:56:56 +0000518 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +0000519
520 break;
521 }
522 }
523
524 // Make sure that any given declaration only shows up in the result set once.
525 if (!AllDeclsFound.insert(CanonDecl))
526 return;
527
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000528 // If the filter is for nested-name-specifiers, then this result starts a
529 // nested-name-specifier.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000530 if (AsNestedNameSpecifier)
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000531 R.StartsNestedNameSpecifier = true;
532
Douglas Gregor0563c262009-09-22 23:15:58 +0000533 // If this result is supposed to have an informative qualifier, add one.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000534 if (R.QualifierIsInformative && !R.Qualifier &&
535 !R.StartsNestedNameSpecifier) {
Douglas Gregor0563c262009-09-22 23:15:58 +0000536 DeclContext *Ctx = R.Declaration->getDeclContext();
537 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
538 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
539 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
540 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
541 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
542 else
543 R.QualifierIsInformative = false;
544 }
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000545
Douglas Gregor86d9a522009-09-21 16:56:56 +0000546 // Insert this result into the set of results and into the current shadow
547 // map.
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000548 SMap[R.Declaration->getDeclName()].Add(R.Declaration, Results.size());
Douglas Gregor86d9a522009-09-21 16:56:56 +0000549 Results.push_back(R);
550}
551
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000552void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
Douglas Gregor0cc84042010-01-14 15:47:35 +0000553 NamedDecl *Hiding, bool InBaseClass = false) {
Douglas Gregora4477812010-01-14 16:01:26 +0000554 if (R.Kind != Result::RK_Declaration) {
555 // For non-declaration results, just add the result.
556 Results.push_back(R);
557 return;
558 }
559
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000560 // Look through using declarations.
561 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(R.Declaration)) {
562 AddResult(Result(Using->getTargetDecl(), R.Qualifier), CurContext, Hiding);
563 return;
564 }
565
Douglas Gregor45bcd432010-01-14 03:21:49 +0000566 bool AsNestedNameSpecifier = false;
567 if (!isInterestingDecl(R.Declaration, AsNestedNameSpecifier))
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000568 return;
569
570 if (Hiding && CheckHiddenResult(R, CurContext, Hiding))
571 return;
572
573 // Make sure that any given declaration only shows up in the result set once.
574 if (!AllDeclsFound.insert(R.Declaration->getCanonicalDecl()))
575 return;
576
577 // If the filter is for nested-name-specifiers, then this result starts a
578 // nested-name-specifier.
Douglas Gregor45bcd432010-01-14 03:21:49 +0000579 if (AsNestedNameSpecifier)
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000580 R.StartsNestedNameSpecifier = true;
Douglas Gregor0cc84042010-01-14 15:47:35 +0000581 else if (Filter == &ResultBuilder::IsMember && !R.Qualifier && InBaseClass &&
582 isa<CXXRecordDecl>(R.Declaration->getDeclContext()
583 ->getLookupContext()))
584 R.QualifierIsInformative = true;
585
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000586 // If this result is supposed to have an informative qualifier, add one.
587 if (R.QualifierIsInformative && !R.Qualifier &&
588 !R.StartsNestedNameSpecifier) {
589 DeclContext *Ctx = R.Declaration->getDeclContext();
590 if (NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
591 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, Namespace);
592 else if (TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
593 R.Qualifier = NestedNameSpecifier::Create(SemaRef.Context, 0, false,
Douglas Gregor45bcd432010-01-14 03:21:49 +0000594 SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000595 else
596 R.QualifierIsInformative = false;
597 }
598
599 // Insert this result into the set of results.
600 Results.push_back(R);
601}
602
Douglas Gregora4477812010-01-14 16:01:26 +0000603void ResultBuilder::AddResult(Result R) {
604 assert(R.Kind != Result::RK_Declaration &&
605 "Declaration results need more context");
606 Results.push_back(R);
607}
608
Douglas Gregor86d9a522009-09-21 16:56:56 +0000609/// \brief Enter into a new scope.
610void ResultBuilder::EnterNewScope() {
611 ShadowMaps.push_back(ShadowMap());
612}
613
614/// \brief Exit from the current scope.
615void ResultBuilder::ExitScope() {
Douglas Gregorfbcb5d62009-12-06 20:23:50 +0000616 for (ShadowMap::iterator E = ShadowMaps.back().begin(),
617 EEnd = ShadowMaps.back().end();
618 E != EEnd;
619 ++E)
620 E->second.Destroy();
621
Douglas Gregor86d9a522009-09-21 16:56:56 +0000622 ShadowMaps.pop_back();
623}
624
Douglas Gregor791215b2009-09-21 20:51:25 +0000625/// \brief Determines whether this given declaration will be found by
626/// ordinary name lookup.
627bool ResultBuilder::IsOrdinaryName(NamedDecl *ND) const {
628 unsigned IDNS = Decl::IDNS_Ordinary;
629 if (SemaRef.getLangOptions().CPlusPlus)
630 IDNS |= Decl::IDNS_Tag;
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000631 else if (SemaRef.getLangOptions().ObjC1 && isa<ObjCIvarDecl>(ND))
632 return true;
633
Douglas Gregor791215b2009-09-21 20:51:25 +0000634 return ND->getIdentifierNamespace() & IDNS;
635}
636
Douglas Gregor01dfea02010-01-10 23:08:15 +0000637/// \brief Determines whether this given declaration will be found by
638/// ordinary name lookup.
639bool ResultBuilder::IsOrdinaryNonValueName(NamedDecl *ND) const {
640 unsigned IDNS = Decl::IDNS_Ordinary;
641 if (SemaRef.getLangOptions().CPlusPlus)
642 IDNS |= Decl::IDNS_Tag;
643
644 return (ND->getIdentifierNamespace() & IDNS) &&
645 !isa<ValueDecl>(ND) && !isa<FunctionTemplateDecl>(ND);
646}
647
Douglas Gregor86d9a522009-09-21 16:56:56 +0000648/// \brief Determines whether the given declaration is suitable as the
649/// start of a C++ nested-name-specifier, e.g., a class or namespace.
650bool ResultBuilder::IsNestedNameSpecifier(NamedDecl *ND) const {
651 // Allow us to find class templates, too.
652 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
653 ND = ClassTemplate->getTemplatedDecl();
654
655 return SemaRef.isAcceptableNestedNameSpecifier(ND);
656}
657
658/// \brief Determines whether the given declaration is an enumeration.
659bool ResultBuilder::IsEnum(NamedDecl *ND) const {
660 return isa<EnumDecl>(ND);
661}
662
663/// \brief Determines whether the given declaration is a class or struct.
664bool ResultBuilder::IsClassOrStruct(NamedDecl *ND) const {
665 // Allow us to find class templates, too.
666 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
667 ND = ClassTemplate->getTemplatedDecl();
668
669 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
670 return RD->getTagKind() == TagDecl::TK_class ||
671 RD->getTagKind() == TagDecl::TK_struct;
672
673 return false;
674}
675
676/// \brief Determines whether the given declaration is a union.
677bool ResultBuilder::IsUnion(NamedDecl *ND) const {
678 // Allow us to find class templates, too.
679 if (ClassTemplateDecl *ClassTemplate = dyn_cast<ClassTemplateDecl>(ND))
680 ND = ClassTemplate->getTemplatedDecl();
681
682 if (RecordDecl *RD = dyn_cast<RecordDecl>(ND))
683 return RD->getTagKind() == TagDecl::TK_union;
684
685 return false;
686}
687
688/// \brief Determines whether the given declaration is a namespace.
689bool ResultBuilder::IsNamespace(NamedDecl *ND) const {
690 return isa<NamespaceDecl>(ND);
691}
692
693/// \brief Determines whether the given declaration is a namespace or
694/// namespace alias.
695bool ResultBuilder::IsNamespaceOrAlias(NamedDecl *ND) const {
696 return isa<NamespaceDecl>(ND) || isa<NamespaceAliasDecl>(ND);
697}
698
Douglas Gregor76282942009-12-11 17:31:05 +0000699/// \brief Determines whether the given declaration is a type.
Douglas Gregor86d9a522009-09-21 16:56:56 +0000700bool ResultBuilder::IsType(NamedDecl *ND) const {
701 return isa<TypeDecl>(ND);
702}
703
Douglas Gregor76282942009-12-11 17:31:05 +0000704/// \brief Determines which members of a class should be visible via
705/// "." or "->". Only value declarations, nested name specifiers, and
706/// using declarations thereof should show up.
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000707bool ResultBuilder::IsMember(NamedDecl *ND) const {
Douglas Gregor76282942009-12-11 17:31:05 +0000708 if (UsingShadowDecl *Using = dyn_cast<UsingShadowDecl>(ND))
709 ND = Using->getTargetDecl();
710
Douglas Gregorce821962009-12-11 18:14:22 +0000711 return isa<ValueDecl>(ND) || isa<FunctionTemplateDecl>(ND) ||
712 isa<ObjCPropertyDecl>(ND);
Douglas Gregoreb5758b2009-09-23 22:26:46 +0000713}
714
Douglas Gregor80f4f4c2010-01-14 16:08:12 +0000715/// \rief Determines whether the given declaration is an Objective-C
716/// instance variable.
717bool ResultBuilder::IsObjCIvar(NamedDecl *ND) const {
718 return isa<ObjCIvarDecl>(ND);
719}
720
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000721namespace {
722 /// \brief Visible declaration consumer that adds a code-completion result
723 /// for each visible declaration.
724 class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
725 ResultBuilder &Results;
726 DeclContext *CurContext;
727
728 public:
729 CodeCompletionDeclConsumer(ResultBuilder &Results, DeclContext *CurContext)
730 : Results(Results), CurContext(CurContext) { }
731
Douglas Gregor0cc84042010-01-14 15:47:35 +0000732 virtual void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, bool InBaseClass) {
733 Results.AddResult(ND, CurContext, Hiding, InBaseClass);
Douglas Gregor1ca6ae82010-01-14 01:09:38 +0000734 }
735 };
736}
737
Douglas Gregor86d9a522009-09-21 16:56:56 +0000738/// \brief Add type specifiers for the current language as keyword results.
Douglas Gregorbca403c2010-01-13 23:51:12 +0000739static void AddTypeSpecifierResults(const LangOptions &LangOpts,
Douglas Gregor86d9a522009-09-21 16:56:56 +0000740 ResultBuilder &Results) {
741 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +0000742 Results.AddResult(Result("short"));
743 Results.AddResult(Result("long"));
744 Results.AddResult(Result("signed"));
745 Results.AddResult(Result("unsigned"));
746 Results.AddResult(Result("void"));
747 Results.AddResult(Result("char"));
748 Results.AddResult(Result("int"));
749 Results.AddResult(Result("float"));
750 Results.AddResult(Result("double"));
751 Results.AddResult(Result("enum"));
752 Results.AddResult(Result("struct"));
753 Results.AddResult(Result("union"));
754 Results.AddResult(Result("const"));
755 Results.AddResult(Result("volatile"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000756
Douglas Gregor86d9a522009-09-21 16:56:56 +0000757 if (LangOpts.C99) {
758 // C99-specific
Douglas Gregora4477812010-01-14 16:01:26 +0000759 Results.AddResult(Result("_Complex"));
760 Results.AddResult(Result("_Imaginary"));
761 Results.AddResult(Result("_Bool"));
762 Results.AddResult(Result("restrict"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000763 }
764
765 if (LangOpts.CPlusPlus) {
766 // C++-specific
Douglas Gregora4477812010-01-14 16:01:26 +0000767 Results.AddResult(Result("bool"));
768 Results.AddResult(Result("class"));
769 Results.AddResult(Result("wchar_t"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000770
Douglas Gregor01dfea02010-01-10 23:08:15 +0000771 // typename qualified-id
772 CodeCompletionString *Pattern = new CodeCompletionString;
773 Pattern->AddTypedTextChunk("typename");
774 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
775 Pattern->AddPlaceholderChunk("qualified-id");
Douglas Gregora4477812010-01-14 16:01:26 +0000776 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000777
Douglas Gregor86d9a522009-09-21 16:56:56 +0000778 if (LangOpts.CPlusPlus0x) {
Douglas Gregora4477812010-01-14 16:01:26 +0000779 Results.AddResult(Result("auto"));
780 Results.AddResult(Result("char16_t"));
781 Results.AddResult(Result("char32_t"));
782 Results.AddResult(Result("decltype"));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000783 }
784 }
785
786 // GNU extensions
787 if (LangOpts.GNUMode) {
788 // FIXME: Enable when we actually support decimal floating point.
Douglas Gregora4477812010-01-14 16:01:26 +0000789 // Results.AddResult(Result("_Decimal32"));
790 // Results.AddResult(Result("_Decimal64"));
791 // Results.AddResult(Result("_Decimal128"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000792
793 CodeCompletionString *Pattern = new CodeCompletionString;
794 Pattern->AddTypedTextChunk("typeof");
795 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
796 Pattern->AddPlaceholderChunk("expression-or-type");
797 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +0000798 Results.AddResult(Result(Pattern));
Douglas Gregor86d9a522009-09-21 16:56:56 +0000799 }
800}
801
Douglas Gregor01dfea02010-01-10 23:08:15 +0000802static void AddStorageSpecifiers(Action::CodeCompletionContext CCC,
803 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000804 ResultBuilder &Results) {
805 typedef CodeCompleteConsumer::Result Result;
806 // Note: we don't suggest either "auto" or "register", because both
807 // are pointless as storage specifiers. Elsewhere, we suggest "auto"
808 // in C++0x as a type specifier.
Douglas Gregora4477812010-01-14 16:01:26 +0000809 Results.AddResult(Result("extern"));
810 Results.AddResult(Result("static"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000811}
812
813static void AddFunctionSpecifiers(Action::CodeCompletionContext CCC,
814 const LangOptions &LangOpts,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000815 ResultBuilder &Results) {
816 typedef CodeCompleteConsumer::Result Result;
817 switch (CCC) {
818 case Action::CCC_Class:
819 case Action::CCC_MemberTemplate:
820 if (LangOpts.CPlusPlus) {
Douglas Gregora4477812010-01-14 16:01:26 +0000821 Results.AddResult(Result("explicit"));
822 Results.AddResult(Result("friend"));
823 Results.AddResult(Result("mutable"));
824 Results.AddResult(Result("virtual"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000825 }
826 // Fall through
827
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000828 case Action::CCC_ObjCInterface:
829 case Action::CCC_ObjCImplementation:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000830 case Action::CCC_Namespace:
831 case Action::CCC_Template:
832 if (LangOpts.CPlusPlus || LangOpts.C99)
Douglas Gregora4477812010-01-14 16:01:26 +0000833 Results.AddResult(Result("inline"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000834 break;
835
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000836 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +0000837 case Action::CCC_Expression:
838 case Action::CCC_Statement:
839 case Action::CCC_ForInit:
840 case Action::CCC_Condition:
841 break;
842 }
843}
844
Douglas Gregorbca403c2010-01-13 23:51:12 +0000845static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt);
846static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt);
847static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000848 ResultBuilder &Results,
849 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000850static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000851 ResultBuilder &Results,
852 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000853static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000854 ResultBuilder &Results,
855 bool NeedAt);
Douglas Gregorbca403c2010-01-13 23:51:12 +0000856static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000857
Douglas Gregor01dfea02010-01-10 23:08:15 +0000858/// \brief Add language constructs that show up for "ordinary" names.
859static void AddOrdinaryNameResults(Action::CodeCompletionContext CCC,
860 Scope *S,
861 Sema &SemaRef,
Douglas Gregor01dfea02010-01-10 23:08:15 +0000862 ResultBuilder &Results) {
863 typedef CodeCompleteConsumer::Result Result;
864 switch (CCC) {
865 case Action::CCC_Namespace:
866 if (SemaRef.getLangOptions().CPlusPlus) {
867 // namespace <identifier> { }
868 CodeCompletionString *Pattern = new CodeCompletionString;
869 Pattern->AddTypedTextChunk("namespace");
870 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
871 Pattern->AddPlaceholderChunk("identifier");
872 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
873 Pattern->AddPlaceholderChunk("declarations");
874 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
875 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +0000876 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000877
878 // namespace identifier = identifier ;
879 Pattern = new CodeCompletionString;
880 Pattern->AddTypedTextChunk("namespace");
881 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
882 Pattern->AddPlaceholderChunk("identifier");
883 Pattern->AddChunk(CodeCompletionString::CK_Equal);
884 Pattern->AddPlaceholderChunk("identifier");
885 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +0000886 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000887
888 // Using directives
889 Pattern = new CodeCompletionString;
890 Pattern->AddTypedTextChunk("using");
891 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
892 Pattern->AddTextChunk("namespace");
893 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
894 Pattern->AddPlaceholderChunk("identifier");
895 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +0000896 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000897
898 // asm(string-literal)
899 Pattern = new CodeCompletionString;
900 Pattern->AddTypedTextChunk("asm");
901 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
902 Pattern->AddPlaceholderChunk("string-literal");
903 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
904 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +0000905 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000906
907 // Explicit template instantiation
908 Pattern = new CodeCompletionString;
909 Pattern->AddTypedTextChunk("template");
910 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
911 Pattern->AddPlaceholderChunk("declaration");
912 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +0000913 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000914 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000915
916 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +0000917 AddObjCTopLevelResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000918
Douglas Gregor01dfea02010-01-10 23:08:15 +0000919 // Fall through
920
921 case Action::CCC_Class:
Douglas Gregora4477812010-01-14 16:01:26 +0000922 Results.AddResult(Result("typedef"));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000923 if (SemaRef.getLangOptions().CPlusPlus) {
924 // Using declaration
925 CodeCompletionString *Pattern = new CodeCompletionString;
926 Pattern->AddTypedTextChunk("using");
927 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
928 Pattern->AddPlaceholderChunk("qualified-id");
929 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +0000930 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000931
932 // using typename qualified-id; (only in a dependent context)
933 if (SemaRef.CurContext->isDependentContext()) {
934 Pattern = new CodeCompletionString;
935 Pattern->AddTypedTextChunk("using");
936 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
937 Pattern->AddTextChunk("typename");
938 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
939 Pattern->AddPlaceholderChunk("qualified-id");
940 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +0000941 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000942 }
943
944 if (CCC == Action::CCC_Class) {
945 // public:
946 Pattern = new CodeCompletionString;
947 Pattern->AddTypedTextChunk("public");
948 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +0000949 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000950
951 // protected:
952 Pattern = new CodeCompletionString;
953 Pattern->AddTypedTextChunk("protected");
954 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +0000955 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000956
957 // private:
958 Pattern = new CodeCompletionString;
959 Pattern->AddTypedTextChunk("private");
960 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +0000961 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000962 }
963 }
964 // Fall through
965
966 case Action::CCC_Template:
967 case Action::CCC_MemberTemplate:
968 if (SemaRef.getLangOptions().CPlusPlus) {
969 // template < parameters >
970 CodeCompletionString *Pattern = new CodeCompletionString;
971 Pattern->AddTypedTextChunk("template");
972 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
973 Pattern->AddPlaceholderChunk("parameters");
974 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
Douglas Gregora4477812010-01-14 16:01:26 +0000975 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +0000976 }
977
Douglas Gregorbca403c2010-01-13 23:51:12 +0000978 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
979 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +0000980 break;
981
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000982 case Action::CCC_ObjCInterface:
Douglas Gregorbca403c2010-01-13 23:51:12 +0000983 AddObjCInterfaceResults(SemaRef.getLangOptions(), Results, true);
984 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
985 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000986 break;
987
988 case Action::CCC_ObjCImplementation:
Douglas Gregorbca403c2010-01-13 23:51:12 +0000989 AddObjCImplementationResults(SemaRef.getLangOptions(), Results, true);
990 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
991 AddFunctionSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregorb6ac2452010-01-13 21:24:21 +0000992 break;
993
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000994 case Action::CCC_ObjCInstanceVariableList:
Douglas Gregorbca403c2010-01-13 23:51:12 +0000995 AddObjCVisibilityResults(SemaRef.getLangOptions(), Results, true);
Douglas Gregorc38c3e12010-01-13 21:54:15 +0000996 break;
997
Douglas Gregor01dfea02010-01-10 23:08:15 +0000998 case Action::CCC_Statement: {
Douglas Gregora4477812010-01-14 16:01:26 +0000999 Results.AddResult(Result("typedef"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001000
1001 CodeCompletionString *Pattern = 0;
1002 if (SemaRef.getLangOptions().CPlusPlus) {
1003 Pattern = new CodeCompletionString;
1004 Pattern->AddTypedTextChunk("try");
1005 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1006 Pattern->AddPlaceholderChunk("statements");
1007 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1008 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1009 Pattern->AddTextChunk("catch");
1010 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1011 Pattern->AddPlaceholderChunk("declaration");
1012 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1013 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1014 Pattern->AddPlaceholderChunk("statements");
1015 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1016 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001017 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001018 }
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001019 if (SemaRef.getLangOptions().ObjC1)
Douglas Gregorbca403c2010-01-13 23:51:12 +00001020 AddObjCStatementResults(Results, true);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001021
Douglas Gregor01dfea02010-01-10 23:08:15 +00001022 // if (condition) { statements }
1023 Pattern = new CodeCompletionString;
1024 Pattern->AddTypedTextChunk("if");
1025 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1026 if (SemaRef.getLangOptions().CPlusPlus)
1027 Pattern->AddPlaceholderChunk("condition");
1028 else
1029 Pattern->AddPlaceholderChunk("expression");
1030 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1031 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1032 Pattern->AddPlaceholderChunk("statements");
1033 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1034 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001035 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001036
1037 // switch (condition) { }
1038 Pattern = new CodeCompletionString;
1039 Pattern->AddTypedTextChunk("switch");
1040 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1041 if (SemaRef.getLangOptions().CPlusPlus)
1042 Pattern->AddPlaceholderChunk("condition");
1043 else
1044 Pattern->AddPlaceholderChunk("expression");
1045 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1046 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1047 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1048 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001049 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001050
1051 // Switch-specific statements.
1052 if (!SemaRef.getSwitchStack().empty()) {
1053 // case expression:
1054 Pattern = new CodeCompletionString;
1055 Pattern->AddTypedTextChunk("case");
1056 Pattern->AddPlaceholderChunk("expression");
1057 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001058 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001059
1060 // default:
1061 Pattern = new CodeCompletionString;
1062 Pattern->AddTypedTextChunk("default");
1063 Pattern->AddChunk(CodeCompletionString::CK_Colon);
Douglas Gregora4477812010-01-14 16:01:26 +00001064 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001065 }
1066
1067 /// while (condition) { statements }
1068 Pattern = new CodeCompletionString;
1069 Pattern->AddTypedTextChunk("while");
1070 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1071 if (SemaRef.getLangOptions().CPlusPlus)
1072 Pattern->AddPlaceholderChunk("condition");
1073 else
1074 Pattern->AddPlaceholderChunk("expression");
1075 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1076 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1077 Pattern->AddPlaceholderChunk("statements");
1078 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1079 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001080 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001081
1082 // do { statements } while ( expression );
1083 Pattern = new CodeCompletionString;
1084 Pattern->AddTypedTextChunk("do");
1085 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1086 Pattern->AddPlaceholderChunk("statements");
1087 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1088 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
1089 Pattern->AddTextChunk("while");
1090 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1091 Pattern->AddPlaceholderChunk("expression");
1092 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1093 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +00001094 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001095
1096 // for ( for-init-statement ; condition ; expression ) { statements }
1097 Pattern = new CodeCompletionString;
1098 Pattern->AddTypedTextChunk("for");
1099 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1100 if (SemaRef.getLangOptions().CPlusPlus || SemaRef.getLangOptions().C99)
1101 Pattern->AddPlaceholderChunk("init-statement");
1102 else
1103 Pattern->AddPlaceholderChunk("init-expression");
1104 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1105 Pattern->AddPlaceholderChunk("condition");
1106 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
1107 Pattern->AddPlaceholderChunk("inc-expression");
1108 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
1109 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
1110 Pattern->AddPlaceholderChunk("statements");
1111 Pattern->AddChunk(CodeCompletionString::CK_VerticalSpace);
1112 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00001113 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001114
1115 if (S->getContinueParent()) {
1116 // continue ;
1117 Pattern = new CodeCompletionString;
1118 Pattern->AddTypedTextChunk("continue");
1119 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +00001120 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001121 }
1122
1123 if (S->getBreakParent()) {
1124 // break ;
1125 Pattern = new CodeCompletionString;
1126 Pattern->AddTypedTextChunk("break");
1127 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +00001128 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001129 }
1130
1131 // "return expression ;" or "return ;", depending on whether we
1132 // know the function is void or not.
1133 bool isVoid = false;
1134 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(SemaRef.CurContext))
1135 isVoid = Function->getResultType()->isVoidType();
1136 else if (ObjCMethodDecl *Method
1137 = dyn_cast<ObjCMethodDecl>(SemaRef.CurContext))
1138 isVoid = Method->getResultType()->isVoidType();
Douglas Gregor9ea9bdb2010-03-01 23:15:13 +00001139 else if (SemaRef.getCurBlock() &&
1140 !SemaRef.getCurBlock()->ReturnType.isNull())
1141 isVoid = SemaRef.getCurBlock()->ReturnType->isVoidType();
Douglas Gregor01dfea02010-01-10 23:08:15 +00001142 Pattern = new CodeCompletionString;
1143 Pattern->AddTypedTextChunk("return");
Douglas Gregor93298002010-02-18 04:06:48 +00001144 if (!isVoid) {
1145 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001146 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor93298002010-02-18 04:06:48 +00001147 }
Douglas Gregor01dfea02010-01-10 23:08:15 +00001148 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +00001149 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001150
1151 // goto identifier ;
1152 Pattern = new CodeCompletionString;
1153 Pattern->AddTypedTextChunk("goto");
1154 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1155 Pattern->AddPlaceholderChunk("identifier");
1156 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +00001157 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001158
1159 // Using directives
1160 Pattern = new CodeCompletionString;
1161 Pattern->AddTypedTextChunk("using");
1162 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1163 Pattern->AddTextChunk("namespace");
1164 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1165 Pattern->AddPlaceholderChunk("identifier");
1166 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +00001167 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001168 }
1169
1170 // Fall through (for statement expressions).
1171 case Action::CCC_ForInit:
1172 case Action::CCC_Condition:
Douglas Gregorbca403c2010-01-13 23:51:12 +00001173 AddStorageSpecifiers(CCC, SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001174 // Fall through: conditions and statements can have expressions.
1175
1176 case Action::CCC_Expression: {
1177 CodeCompletionString *Pattern = 0;
1178 if (SemaRef.getLangOptions().CPlusPlus) {
1179 // 'this', if we're in a non-static member function.
1180 if (CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(SemaRef.CurContext))
1181 if (!Method->isStatic())
Douglas Gregora4477812010-01-14 16:01:26 +00001182 Results.AddResult(Result("this"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001183
1184 // true, false
Douglas Gregora4477812010-01-14 16:01:26 +00001185 Results.AddResult(Result("true"));
1186 Results.AddResult(Result("false"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001187
1188 // dynamic_cast < type-id > ( expression )
1189 Pattern = new CodeCompletionString;
1190 Pattern->AddTypedTextChunk("dynamic_cast");
1191 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1192 Pattern->AddPlaceholderChunk("type-id");
1193 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1194 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1195 Pattern->AddPlaceholderChunk("expression");
1196 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001197 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001198
1199 // static_cast < type-id > ( expression )
1200 Pattern = new CodeCompletionString;
1201 Pattern->AddTypedTextChunk("static_cast");
1202 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1203 Pattern->AddPlaceholderChunk("type-id");
1204 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1205 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1206 Pattern->AddPlaceholderChunk("expression");
1207 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001208 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001209
1210 // reinterpret_cast < type-id > ( expression )
1211 Pattern = new CodeCompletionString;
1212 Pattern->AddTypedTextChunk("reinterpret_cast");
1213 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1214 Pattern->AddPlaceholderChunk("type-id");
1215 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1216 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1217 Pattern->AddPlaceholderChunk("expression");
1218 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001219 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001220
1221 // const_cast < type-id > ( expression )
1222 Pattern = new CodeCompletionString;
1223 Pattern->AddTypedTextChunk("const_cast");
1224 Pattern->AddChunk(CodeCompletionString::CK_LeftAngle);
1225 Pattern->AddPlaceholderChunk("type-id");
1226 Pattern->AddChunk(CodeCompletionString::CK_RightAngle);
1227 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1228 Pattern->AddPlaceholderChunk("expression");
1229 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001230 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001231
1232 // typeid ( expression-or-type )
1233 Pattern = new CodeCompletionString;
1234 Pattern->AddTypedTextChunk("typeid");
1235 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1236 Pattern->AddPlaceholderChunk("expression-or-type");
1237 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001238 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001239
1240 // new T ( ... )
1241 Pattern = new CodeCompletionString;
1242 Pattern->AddTypedTextChunk("new");
1243 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1244 Pattern->AddPlaceholderChunk("type-id");
1245 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1246 Pattern->AddPlaceholderChunk("expressions");
1247 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001248 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001249
1250 // new T [ ] ( ... )
1251 Pattern = new CodeCompletionString;
1252 Pattern->AddTypedTextChunk("new");
1253 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1254 Pattern->AddPlaceholderChunk("type-id");
1255 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1256 Pattern->AddPlaceholderChunk("size");
1257 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1258 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1259 Pattern->AddPlaceholderChunk("expressions");
1260 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001261 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001262
1263 // delete expression
1264 Pattern = new CodeCompletionString;
1265 Pattern->AddTypedTextChunk("delete");
1266 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1267 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00001268 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001269
1270 // delete [] expression
1271 Pattern = new CodeCompletionString;
1272 Pattern->AddTypedTextChunk("delete");
1273 Pattern->AddChunk(CodeCompletionString::CK_LeftBracket);
1274 Pattern->AddChunk(CodeCompletionString::CK_RightBracket);
1275 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1276 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00001277 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001278
1279 // throw expression
1280 Pattern = new CodeCompletionString;
1281 Pattern->AddTypedTextChunk("throw");
1282 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
1283 Pattern->AddPlaceholderChunk("expression");
Douglas Gregora4477812010-01-14 16:01:26 +00001284 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001285 }
1286
1287 if (SemaRef.getLangOptions().ObjC1) {
1288 // Add "super", if we're in an Objective-C class with a superclass.
1289 if (ObjCMethodDecl *Method = SemaRef.getCurMethodDecl())
1290 if (Method->getClassInterface()->getSuperClass())
Douglas Gregora4477812010-01-14 16:01:26 +00001291 Results.AddResult(Result("super"));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001292
Douglas Gregorbca403c2010-01-13 23:51:12 +00001293 AddObjCExpressionResults(Results, true);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001294 }
1295
1296 // sizeof expression
1297 Pattern = new CodeCompletionString;
1298 Pattern->AddTypedTextChunk("sizeof");
1299 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
1300 Pattern->AddPlaceholderChunk("expression-or-type");
1301 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00001302 Results.AddResult(Result(Pattern));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001303 break;
1304 }
1305 }
1306
Douglas Gregorbca403c2010-01-13 23:51:12 +00001307 AddTypeSpecifierResults(SemaRef.getLangOptions(), Results);
Douglas Gregor01dfea02010-01-10 23:08:15 +00001308
1309 if (SemaRef.getLangOptions().CPlusPlus)
Douglas Gregora4477812010-01-14 16:01:26 +00001310 Results.AddResult(Result("operator"));
Douglas Gregor01dfea02010-01-10 23:08:15 +00001311}
1312
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001313/// \brief If the given declaration has an associated type, add it as a result
1314/// type chunk.
1315static void AddResultTypeChunk(ASTContext &Context,
1316 NamedDecl *ND,
1317 CodeCompletionString *Result) {
1318 if (!ND)
1319 return;
1320
1321 // Determine the type of the declaration (if it has a type).
1322 QualType T;
1323 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND))
1324 T = Function->getResultType();
1325 else if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND))
1326 T = Method->getResultType();
1327 else if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND))
1328 T = FunTmpl->getTemplatedDecl()->getResultType();
1329 else if (EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND))
1330 T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
1331 else if (isa<UnresolvedUsingValueDecl>(ND)) {
1332 /* Do nothing: ignore unresolved using declarations*/
1333 } else if (ValueDecl *Value = dyn_cast<ValueDecl>(ND))
1334 T = Value->getType();
1335 else if (ObjCPropertyDecl *Property = dyn_cast<ObjCPropertyDecl>(ND))
1336 T = Property->getType();
1337
1338 if (T.isNull() || Context.hasSameType(T, Context.DependentTy))
1339 return;
1340
Douglas Gregor84139d62010-04-05 21:25:31 +00001341 PrintingPolicy Policy(Context.PrintingPolicy);
1342 Policy.AnonymousTagLocations = false;
1343
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001344 std::string TypeStr;
Douglas Gregor84139d62010-04-05 21:25:31 +00001345 T.getAsStringInternal(TypeStr, Policy);
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001346 Result->AddResultTypeChunk(TypeStr);
1347}
1348
Douglas Gregor86d9a522009-09-21 16:56:56 +00001349/// \brief Add function parameter chunks to the given code completion string.
1350static void AddFunctionParameterChunks(ASTContext &Context,
1351 FunctionDecl *Function,
1352 CodeCompletionString *Result) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001353 typedef CodeCompletionString::Chunk Chunk;
1354
Douglas Gregor86d9a522009-09-21 16:56:56 +00001355 CodeCompletionString *CCStr = Result;
1356
1357 for (unsigned P = 0, N = Function->getNumParams(); P != N; ++P) {
1358 ParmVarDecl *Param = Function->getParamDecl(P);
1359
1360 if (Param->hasDefaultArg()) {
1361 // When we see an optional default argument, put that argument and
1362 // the remaining default arguments into a new, optional string.
1363 CodeCompletionString *Opt = new CodeCompletionString;
1364 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1365 CCStr = Opt;
1366 }
1367
1368 if (P != 0)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001369 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001370
1371 // Format the placeholder string.
1372 std::string PlaceholderStr;
1373 if (Param->getIdentifier())
1374 PlaceholderStr = Param->getIdentifier()->getName();
1375
1376 Param->getType().getAsStringInternal(PlaceholderStr,
1377 Context.PrintingPolicy);
1378
1379 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001380 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001381 }
Douglas Gregorb3d45252009-09-22 21:42:17 +00001382
1383 if (const FunctionProtoType *Proto
1384 = Function->getType()->getAs<FunctionProtoType>())
1385 if (Proto->isVariadic())
1386 CCStr->AddPlaceholderChunk(", ...");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001387}
1388
1389/// \brief Add template parameter chunks to the given code completion string.
1390static void AddTemplateParameterChunks(ASTContext &Context,
1391 TemplateDecl *Template,
1392 CodeCompletionString *Result,
1393 unsigned MaxParameters = 0) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001394 typedef CodeCompletionString::Chunk Chunk;
1395
Douglas Gregor86d9a522009-09-21 16:56:56 +00001396 CodeCompletionString *CCStr = Result;
1397 bool FirstParameter = true;
1398
1399 TemplateParameterList *Params = Template->getTemplateParameters();
1400 TemplateParameterList::iterator PEnd = Params->end();
1401 if (MaxParameters)
1402 PEnd = Params->begin() + MaxParameters;
1403 for (TemplateParameterList::iterator P = Params->begin(); P != PEnd; ++P) {
1404 bool HasDefaultArg = false;
1405 std::string PlaceholderStr;
1406 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*P)) {
1407 if (TTP->wasDeclaredWithTypename())
1408 PlaceholderStr = "typename";
1409 else
1410 PlaceholderStr = "class";
1411
1412 if (TTP->getIdentifier()) {
1413 PlaceholderStr += ' ';
1414 PlaceholderStr += TTP->getIdentifier()->getName();
1415 }
1416
1417 HasDefaultArg = TTP->hasDefaultArgument();
1418 } else if (NonTypeTemplateParmDecl *NTTP
1419 = dyn_cast<NonTypeTemplateParmDecl>(*P)) {
1420 if (NTTP->getIdentifier())
1421 PlaceholderStr = NTTP->getIdentifier()->getName();
1422 NTTP->getType().getAsStringInternal(PlaceholderStr,
1423 Context.PrintingPolicy);
1424 HasDefaultArg = NTTP->hasDefaultArgument();
1425 } else {
1426 assert(isa<TemplateTemplateParmDecl>(*P));
1427 TemplateTemplateParmDecl *TTP = cast<TemplateTemplateParmDecl>(*P);
1428
1429 // Since putting the template argument list into the placeholder would
1430 // be very, very long, we just use an abbreviation.
1431 PlaceholderStr = "template<...> class";
1432 if (TTP->getIdentifier()) {
1433 PlaceholderStr += ' ';
1434 PlaceholderStr += TTP->getIdentifier()->getName();
1435 }
1436
1437 HasDefaultArg = TTP->hasDefaultArgument();
1438 }
1439
1440 if (HasDefaultArg) {
1441 // When we see an optional default argument, put that argument and
1442 // the remaining default arguments into a new, optional string.
1443 CodeCompletionString *Opt = new CodeCompletionString;
1444 CCStr->AddOptionalChunk(std::auto_ptr<CodeCompletionString>(Opt));
1445 CCStr = Opt;
1446 }
1447
1448 if (FirstParameter)
1449 FirstParameter = false;
1450 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001451 CCStr->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001452
1453 // Add the placeholder string.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001454 CCStr->AddPlaceholderChunk(PlaceholderStr);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001455 }
1456}
1457
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001458/// \brief Add a qualifier to the given code-completion string, if the
1459/// provided nested-name-specifier is non-NULL.
Douglas Gregora61a8792009-12-11 18:44:16 +00001460static void
1461AddQualifierToCompletionString(CodeCompletionString *Result,
1462 NestedNameSpecifier *Qualifier,
1463 bool QualifierIsInformative,
1464 ASTContext &Context) {
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001465 if (!Qualifier)
1466 return;
1467
1468 std::string PrintedNNS;
1469 {
1470 llvm::raw_string_ostream OS(PrintedNNS);
1471 Qualifier->print(OS, Context.PrintingPolicy);
1472 }
Douglas Gregor0563c262009-09-22 23:15:58 +00001473 if (QualifierIsInformative)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001474 Result->AddInformativeChunk(PrintedNNS);
Douglas Gregor0563c262009-09-22 23:15:58 +00001475 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001476 Result->AddTextChunk(PrintedNNS);
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00001477}
1478
Douglas Gregora61a8792009-12-11 18:44:16 +00001479static void AddFunctionTypeQualsToCompletionString(CodeCompletionString *Result,
1480 FunctionDecl *Function) {
1481 const FunctionProtoType *Proto
1482 = Function->getType()->getAs<FunctionProtoType>();
1483 if (!Proto || !Proto->getTypeQuals())
1484 return;
1485
1486 std::string QualsStr;
1487 if (Proto->getTypeQuals() & Qualifiers::Const)
1488 QualsStr += " const";
1489 if (Proto->getTypeQuals() & Qualifiers::Volatile)
1490 QualsStr += " volatile";
1491 if (Proto->getTypeQuals() & Qualifiers::Restrict)
1492 QualsStr += " restrict";
1493 Result->AddInformativeChunk(QualsStr);
1494}
1495
Douglas Gregor86d9a522009-09-21 16:56:56 +00001496/// \brief If possible, create a new code completion string for the given
1497/// result.
1498///
1499/// \returns Either a new, heap-allocated code completion string describing
1500/// how to use this result, or NULL to indicate that the string or name of the
1501/// result is all that is needed.
1502CodeCompletionString *
1503CodeCompleteConsumer::Result::CreateCodeCompletionString(Sema &S) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001504 typedef CodeCompletionString::Chunk Chunk;
1505
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001506 if (Kind == RK_Pattern)
1507 return Pattern->Clone();
1508
1509 CodeCompletionString *Result = new CodeCompletionString;
1510
1511 if (Kind == RK_Keyword) {
1512 Result->AddTypedTextChunk(Keyword);
1513 return Result;
1514 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00001515
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001516 if (Kind == RK_Macro) {
1517 MacroInfo *MI = S.PP.getMacroInfo(Macro);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001518 assert(MI && "Not a macro?");
1519
1520 Result->AddTypedTextChunk(Macro->getName());
1521
1522 if (!MI->isFunctionLike())
1523 return Result;
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001524
1525 // Format a function-like macro with placeholders for the arguments.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001526 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001527 for (MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
1528 A != AEnd; ++A) {
1529 if (A != MI->arg_begin())
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001530 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001531
1532 if (!MI->isVariadic() || A != AEnd - 1) {
1533 // Non-variadic argument.
Benjamin Kramer660cc182009-11-29 20:18:50 +00001534 Result->AddPlaceholderChunk((*A)->getName());
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001535 continue;
1536 }
1537
1538 // Variadic argument; cope with the different between GNU and C99
1539 // variadic macros, providing a single placeholder for the rest of the
1540 // arguments.
1541 if ((*A)->isStr("__VA_ARGS__"))
1542 Result->AddPlaceholderChunk("...");
1543 else {
1544 std::string Arg = (*A)->getName();
1545 Arg += "...";
Benjamin Kramer660cc182009-11-29 20:18:50 +00001546 Result->AddPlaceholderChunk(Arg);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001547 }
1548 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001549 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001550 return Result;
1551 }
1552
1553 assert(Kind == RK_Declaration && "Missed a macro kind?");
Douglas Gregor86d9a522009-09-21 16:56:56 +00001554 NamedDecl *ND = Declaration;
1555
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001556 if (StartsNestedNameSpecifier) {
Benjamin Kramer660cc182009-11-29 20:18:50 +00001557 Result->AddTypedTextChunk(ND->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001558 Result->AddTextChunk("::");
1559 return Result;
1560 }
1561
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001562 AddResultTypeChunk(S.Context, ND, Result);
1563
Douglas Gregor86d9a522009-09-21 16:56:56 +00001564 if (FunctionDecl *Function = dyn_cast<FunctionDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001565 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1566 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001567 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001568 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001569 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001570 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001571 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001572 return Result;
1573 }
1574
1575 if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001576 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1577 S.Context);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001578 FunctionDecl *Function = FunTmpl->getTemplatedDecl();
Benjamin Kramer660cc182009-11-29 20:18:50 +00001579 Result->AddTypedTextChunk(Function->getNameAsString());
Douglas Gregor86d9a522009-09-21 16:56:56 +00001580
1581 // Figure out which template parameters are deduced (or have default
1582 // arguments).
1583 llvm::SmallVector<bool, 16> Deduced;
1584 S.MarkDeducedTemplateParameters(FunTmpl, Deduced);
1585 unsigned LastDeducibleArgument;
1586 for (LastDeducibleArgument = Deduced.size(); LastDeducibleArgument > 0;
1587 --LastDeducibleArgument) {
1588 if (!Deduced[LastDeducibleArgument - 1]) {
1589 // C++0x: Figure out if the template argument has a default. If so,
1590 // the user doesn't need to type this argument.
1591 // FIXME: We need to abstract template parameters better!
1592 bool HasDefaultArg = false;
1593 NamedDecl *Param = FunTmpl->getTemplateParameters()->getParam(
1594 LastDeducibleArgument - 1);
1595 if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
1596 HasDefaultArg = TTP->hasDefaultArgument();
1597 else if (NonTypeTemplateParmDecl *NTTP
1598 = dyn_cast<NonTypeTemplateParmDecl>(Param))
1599 HasDefaultArg = NTTP->hasDefaultArgument();
1600 else {
1601 assert(isa<TemplateTemplateParmDecl>(Param));
1602 HasDefaultArg
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001603 = cast<TemplateTemplateParmDecl>(Param)->hasDefaultArgument();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001604 }
1605
1606 if (!HasDefaultArg)
1607 break;
1608 }
1609 }
1610
1611 if (LastDeducibleArgument) {
1612 // Some of the function template arguments cannot be deduced from a
1613 // function call, so we introduce an explicit template argument list
1614 // containing all of the arguments up to the first deducible argument.
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001615 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001616 AddTemplateParameterChunks(S.Context, FunTmpl, Result,
1617 LastDeducibleArgument);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001618 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001619 }
1620
1621 // Add the function parameters
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001622 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001623 AddFunctionParameterChunks(S.Context, Function, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001624 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregora61a8792009-12-11 18:44:16 +00001625 AddFunctionTypeQualsToCompletionString(Result, Function);
Douglas Gregor86d9a522009-09-21 16:56:56 +00001626 return Result;
1627 }
1628
1629 if (TemplateDecl *Template = dyn_cast<TemplateDecl>(ND)) {
Douglas Gregor0563c262009-09-22 23:15:58 +00001630 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1631 S.Context);
Benjamin Kramer660cc182009-11-29 20:18:50 +00001632 Result->AddTypedTextChunk(Template->getNameAsString());
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001633 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001634 AddTemplateParameterChunks(S.Context, Template, Result);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001635 Result->AddChunk(Chunk(CodeCompletionString::CK_RightAngle));
Douglas Gregor86d9a522009-09-21 16:56:56 +00001636 return Result;
1637 }
1638
Douglas Gregor9630eb62009-11-17 16:44:22 +00001639 if (ObjCMethodDecl *Method = dyn_cast<ObjCMethodDecl>(ND)) {
Douglas Gregor9630eb62009-11-17 16:44:22 +00001640 Selector Sel = Method->getSelector();
1641 if (Sel.isUnarySelector()) {
1642 Result->AddTypedTextChunk(Sel.getIdentifierInfoForSlot(0)->getName());
1643 return Result;
1644 }
1645
Douglas Gregord3c68542009-11-19 01:08:35 +00001646 std::string SelName = Sel.getIdentifierInfoForSlot(0)->getName().str();
1647 SelName += ':';
1648 if (StartParameter == 0)
1649 Result->AddTypedTextChunk(SelName);
1650 else {
1651 Result->AddInformativeChunk(SelName);
1652
1653 // If there is only one parameter, and we're past it, add an empty
1654 // typed-text chunk since there is nothing to type.
1655 if (Method->param_size() == 1)
1656 Result->AddTypedTextChunk("");
1657 }
Douglas Gregor9630eb62009-11-17 16:44:22 +00001658 unsigned Idx = 0;
1659 for (ObjCMethodDecl::param_iterator P = Method->param_begin(),
1660 PEnd = Method->param_end();
1661 P != PEnd; (void)++P, ++Idx) {
1662 if (Idx > 0) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001663 std::string Keyword;
1664 if (Idx > StartParameter)
Douglas Gregor834389b2010-01-12 06:38:28 +00001665 Result->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001666 if (IdentifierInfo *II = Sel.getIdentifierInfoForSlot(Idx))
1667 Keyword += II->getName().str();
1668 Keyword += ":";
Douglas Gregor4ad96852009-11-19 07:41:15 +00001669 if (Idx < StartParameter || AllParametersAreInformative) {
Douglas Gregord3c68542009-11-19 01:08:35 +00001670 Result->AddInformativeChunk(Keyword);
1671 } else if (Idx == StartParameter)
1672 Result->AddTypedTextChunk(Keyword);
1673 else
1674 Result->AddTextChunk(Keyword);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001675 }
Douglas Gregord3c68542009-11-19 01:08:35 +00001676
1677 // If we're before the starting parameter, skip the placeholder.
1678 if (Idx < StartParameter)
1679 continue;
Douglas Gregor9630eb62009-11-17 16:44:22 +00001680
1681 std::string Arg;
1682 (*P)->getType().getAsStringInternal(Arg, S.Context.PrintingPolicy);
1683 Arg = "(" + Arg + ")";
1684 if (IdentifierInfo *II = (*P)->getIdentifier())
1685 Arg += II->getName().str();
Douglas Gregor4ad96852009-11-19 07:41:15 +00001686 if (AllParametersAreInformative)
1687 Result->AddInformativeChunk(Arg);
1688 else
1689 Result->AddPlaceholderChunk(Arg);
Douglas Gregor9630eb62009-11-17 16:44:22 +00001690 }
1691
Douglas Gregor2a17af02009-12-23 00:21:46 +00001692 if (Method->isVariadic()) {
1693 if (AllParametersAreInformative)
1694 Result->AddInformativeChunk(", ...");
1695 else
1696 Result->AddPlaceholderChunk(", ...");
1697 }
1698
Douglas Gregor9630eb62009-11-17 16:44:22 +00001699 return Result;
1700 }
1701
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001702 if (Qualifier)
Douglas Gregor0563c262009-09-22 23:15:58 +00001703 AddQualifierToCompletionString(Result, Qualifier, QualifierIsInformative,
1704 S.Context);
Douglas Gregor2b4074f2009-12-01 05:55:20 +00001705
1706 Result->AddTypedTextChunk(ND->getNameAsString());
1707 return Result;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001708}
1709
Douglas Gregor86d802e2009-09-23 00:34:09 +00001710CodeCompletionString *
1711CodeCompleteConsumer::OverloadCandidate::CreateSignatureString(
1712 unsigned CurrentArg,
1713 Sema &S) const {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001714 typedef CodeCompletionString::Chunk Chunk;
1715
Douglas Gregor86d802e2009-09-23 00:34:09 +00001716 CodeCompletionString *Result = new CodeCompletionString;
1717 FunctionDecl *FDecl = getFunction();
Douglas Gregorff5ce6e2009-12-18 18:53:37 +00001718 AddResultTypeChunk(S.Context, FDecl, Result);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001719 const FunctionProtoType *Proto
1720 = dyn_cast<FunctionProtoType>(getFunctionType());
1721 if (!FDecl && !Proto) {
1722 // Function without a prototype. Just give the return type and a
1723 // highlighted ellipsis.
1724 const FunctionType *FT = getFunctionType();
1725 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001726 FT->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001727 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
1728 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
1729 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001730 return Result;
1731 }
1732
1733 if (FDecl)
Benjamin Kramer660cc182009-11-29 20:18:50 +00001734 Result->AddTextChunk(FDecl->getNameAsString());
Douglas Gregor86d802e2009-09-23 00:34:09 +00001735 else
1736 Result->AddTextChunk(
Benjamin Kramer660cc182009-11-29 20:18:50 +00001737 Proto->getResultType().getAsString(S.Context.PrintingPolicy));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001738
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001739 Result->AddChunk(Chunk(CodeCompletionString::CK_LeftParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001740 unsigned NumParams = FDecl? FDecl->getNumParams() : Proto->getNumArgs();
1741 for (unsigned I = 0; I != NumParams; ++I) {
1742 if (I)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001743 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001744
1745 std::string ArgString;
1746 QualType ArgType;
1747
1748 if (FDecl) {
1749 ArgString = FDecl->getParamDecl(I)->getNameAsString();
1750 ArgType = FDecl->getParamDecl(I)->getOriginalType();
1751 } else {
1752 ArgType = Proto->getArgType(I);
1753 }
1754
1755 ArgType.getAsStringInternal(ArgString, S.Context.PrintingPolicy);
1756
1757 if (I == CurrentArg)
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001758 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter,
Benjamin Kramer660cc182009-11-29 20:18:50 +00001759 ArgString));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001760 else
Benjamin Kramer660cc182009-11-29 20:18:50 +00001761 Result->AddTextChunk(ArgString);
Douglas Gregor86d802e2009-09-23 00:34:09 +00001762 }
1763
1764 if (Proto && Proto->isVariadic()) {
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001765 Result->AddChunk(Chunk(CodeCompletionString::CK_Comma));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001766 if (CurrentArg < NumParams)
1767 Result->AddTextChunk("...");
1768 else
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001769 Result->AddChunk(Chunk(CodeCompletionString::CK_CurrentParameter, "..."));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001770 }
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001771 Result->AddChunk(Chunk(CodeCompletionString::CK_RightParen));
Douglas Gregor86d802e2009-09-23 00:34:09 +00001772
1773 return Result;
1774}
1775
Douglas Gregor86d9a522009-09-21 16:56:56 +00001776namespace {
1777 struct SortCodeCompleteResult {
1778 typedef CodeCompleteConsumer::Result Result;
1779
Douglas Gregor6a684032009-09-28 03:51:44 +00001780 bool isEarlierDeclarationName(DeclarationName X, DeclarationName Y) const {
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001781 Selector XSel = X.getObjCSelector();
1782 Selector YSel = Y.getObjCSelector();
1783 if (!XSel.isNull() && !YSel.isNull()) {
1784 // We are comparing two selectors.
1785 unsigned N = std::min(XSel.getNumArgs(), YSel.getNumArgs());
1786 if (N == 0)
1787 ++N;
1788 for (unsigned I = 0; I != N; ++I) {
1789 IdentifierInfo *XId = XSel.getIdentifierInfoForSlot(I);
1790 IdentifierInfo *YId = YSel.getIdentifierInfoForSlot(I);
1791 if (!XId || !YId)
1792 return XId && !YId;
1793
1794 switch (XId->getName().compare_lower(YId->getName())) {
1795 case -1: return true;
1796 case 1: return false;
1797 default: break;
1798 }
1799 }
1800
1801 return XSel.getNumArgs() < YSel.getNumArgs();
1802 }
1803
1804 // For non-selectors, order by kind.
1805 if (X.getNameKind() != Y.getNameKind())
Douglas Gregor6a684032009-09-28 03:51:44 +00001806 return X.getNameKind() < Y.getNameKind();
1807
Douglas Gregor2b0cc122009-12-05 09:08:56 +00001808 // Order identifiers by comparison of their lowercased names.
1809 if (IdentifierInfo *XId = X.getAsIdentifierInfo())
1810 return XId->getName().compare_lower(
1811 Y.getAsIdentifierInfo()->getName()) < 0;
1812
1813 // Order overloaded operators by the order in which they appear
1814 // in our list of operators.
1815 if (OverloadedOperatorKind XOp = X.getCXXOverloadedOperator())
1816 return XOp < Y.getCXXOverloadedOperator();
1817
1818 // Order C++0x user-defined literal operators lexically by their
1819 // lowercased suffixes.
1820 if (IdentifierInfo *XLit = X.getCXXLiteralIdentifier())
1821 return XLit->getName().compare_lower(
1822 Y.getCXXLiteralIdentifier()->getName()) < 0;
1823
1824 // The only stable ordering we have is to turn the name into a
1825 // string and then compare the lower-case strings. This is
1826 // inefficient, but thankfully does not happen too often.
Benjamin Kramer0e7049f2009-12-05 10:22:15 +00001827 return llvm::StringRef(X.getAsString()).compare_lower(
1828 Y.getAsString()) < 0;
Douglas Gregor6a684032009-09-28 03:51:44 +00001829 }
1830
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001831 /// \brief Retrieve the name that should be used to order a result.
1832 ///
1833 /// If the name needs to be constructed as a string, that string will be
1834 /// saved into Saved and the returned StringRef will refer to it.
1835 static llvm::StringRef getOrderedName(const Result &R,
1836 std::string &Saved) {
1837 switch (R.Kind) {
1838 case Result::RK_Keyword:
1839 return R.Keyword;
1840
1841 case Result::RK_Pattern:
1842 return R.Pattern->getTypedText();
1843
1844 case Result::RK_Macro:
1845 return R.Macro->getName();
1846
1847 case Result::RK_Declaration:
1848 // Handle declarations below.
1849 break;
Douglas Gregor54f01612009-11-19 00:01:57 +00001850 }
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001851
1852 DeclarationName Name = R.Declaration->getDeclName();
Douglas Gregor54f01612009-11-19 00:01:57 +00001853
Douglas Gregorab0b4f12010-01-13 23:24:38 +00001854 // If the name is a simple identifier (by far the common case), or a
1855 // zero-argument selector, just return a reference to that identifier.
1856 if (IdentifierInfo *Id = Name.getAsIdentifierInfo())
1857 return Id->getName();
1858 if (Name.isObjCZeroArgSelector())
1859 if (IdentifierInfo *Id
1860 = Name.getObjCSelector().getIdentifierInfoForSlot(0))
1861 return Id->getName();
1862
1863 Saved = Name.getAsString();
1864 return Saved;
1865 }
1866
1867 bool operator()(const Result &X, const Result &Y) const {
1868 std::string XSaved, YSaved;
1869 llvm::StringRef XStr = getOrderedName(X, XSaved);
1870 llvm::StringRef YStr = getOrderedName(Y, YSaved);
1871 int cmp = XStr.compare_lower(YStr);
1872 if (cmp)
1873 return cmp < 0;
Douglas Gregor86d9a522009-09-21 16:56:56 +00001874
1875 // Non-hidden names precede hidden names.
1876 if (X.Hidden != Y.Hidden)
1877 return !X.Hidden;
1878
Douglas Gregoreb5758b2009-09-23 22:26:46 +00001879 // Non-nested-name-specifiers precede nested-name-specifiers.
1880 if (X.StartsNestedNameSpecifier != Y.StartsNestedNameSpecifier)
1881 return !X.StartsNestedNameSpecifier;
1882
Douglas Gregor86d9a522009-09-21 16:56:56 +00001883 return false;
1884 }
1885 };
1886}
1887
Douglas Gregorbca403c2010-01-13 23:51:12 +00001888static void AddMacroResults(Preprocessor &PP, ResultBuilder &Results) {
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001889 Results.EnterNewScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001890 for (Preprocessor::macro_iterator M = PP.macro_begin(),
1891 MEnd = PP.macro_end();
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001892 M != MEnd; ++M)
Douglas Gregora4477812010-01-14 16:01:26 +00001893 Results.AddResult(M->first);
Douglas Gregor3f7c7f42009-10-30 16:50:04 +00001894 Results.ExitScope();
1895}
1896
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001897static void HandleCodeCompleteResults(Sema *S,
1898 CodeCompleteConsumer *CodeCompleter,
1899 CodeCompleteConsumer::Result *Results,
1900 unsigned NumResults) {
Douglas Gregor86d9a522009-09-21 16:56:56 +00001901 std::stable_sort(Results, Results + NumResults, SortCodeCompleteResult());
1902
1903 if (CodeCompleter)
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001904 CodeCompleter->ProcessCodeCompleteResults(*S, Results, NumResults);
Douglas Gregor54f01612009-11-19 00:01:57 +00001905
1906 for (unsigned I = 0; I != NumResults; ++I)
1907 Results[I].Destroy();
Douglas Gregor86d9a522009-09-21 16:56:56 +00001908}
1909
Douglas Gregor01dfea02010-01-10 23:08:15 +00001910void Sema::CodeCompleteOrdinaryName(Scope *S,
1911 CodeCompletionContext CompletionContext) {
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001912 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor01dfea02010-01-10 23:08:15 +00001913 ResultBuilder Results(*this);
1914
1915 // Determine how to filter results, e.g., so that the names of
1916 // values (functions, enumerators, function templates, etc.) are
1917 // only allowed where we can have an expression.
1918 switch (CompletionContext) {
1919 case CCC_Namespace:
1920 case CCC_Class:
Douglas Gregorb6ac2452010-01-13 21:24:21 +00001921 case CCC_ObjCInterface:
1922 case CCC_ObjCImplementation:
Douglas Gregorc38c3e12010-01-13 21:54:15 +00001923 case CCC_ObjCInstanceVariableList:
Douglas Gregor01dfea02010-01-10 23:08:15 +00001924 case CCC_Template:
1925 case CCC_MemberTemplate:
1926 Results.setFilter(&ResultBuilder::IsOrdinaryNonValueName);
1927 break;
1928
1929 case CCC_Expression:
1930 case CCC_Statement:
1931 case CCC_ForInit:
1932 case CCC_Condition:
1933 Results.setFilter(&ResultBuilder::IsOrdinaryName);
1934 break;
1935 }
1936
Douglas Gregor1ca6ae82010-01-14 01:09:38 +00001937 CodeCompletionDeclConsumer Consumer(Results, CurContext);
1938 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001939
1940 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00001941 AddOrdinaryNameResults(CompletionContext, S, *this, Results);
Douglas Gregor2a7925c2009-12-07 09:54:55 +00001942 Results.ExitScope();
1943
Douglas Gregor0c8296d2009-11-07 00:00:49 +00001944 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00001945 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00001946 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor791215b2009-09-21 20:51:25 +00001947}
1948
Douglas Gregor95ac6552009-11-18 01:29:26 +00001949static void AddObjCProperties(ObjCContainerDecl *Container,
Douglas Gregor322328b2009-11-18 22:32:06 +00001950 bool AllowCategories,
Douglas Gregor95ac6552009-11-18 01:29:26 +00001951 DeclContext *CurContext,
1952 ResultBuilder &Results) {
1953 typedef CodeCompleteConsumer::Result Result;
1954
1955 // Add properties in this container.
1956 for (ObjCContainerDecl::prop_iterator P = Container->prop_begin(),
1957 PEnd = Container->prop_end();
1958 P != PEnd;
1959 ++P)
1960 Results.MaybeAddResult(Result(*P, 0), CurContext);
1961
1962 // Add properties in referenced protocols.
1963 if (ObjCProtocolDecl *Protocol = dyn_cast<ObjCProtocolDecl>(Container)) {
1964 for (ObjCProtocolDecl::protocol_iterator P = Protocol->protocol_begin(),
1965 PEnd = Protocol->protocol_end();
1966 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001967 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001968 } else if (ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container)){
Douglas Gregor322328b2009-11-18 22:32:06 +00001969 if (AllowCategories) {
1970 // Look through categories.
1971 for (ObjCCategoryDecl *Category = IFace->getCategoryList();
1972 Category; Category = Category->getNextClassCategory())
1973 AddObjCProperties(Category, AllowCategories, CurContext, Results);
1974 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00001975
1976 // Look through protocols.
1977 for (ObjCInterfaceDecl::protocol_iterator I = IFace->protocol_begin(),
1978 E = IFace->protocol_end();
1979 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00001980 AddObjCProperties(*I, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001981
1982 // Look in the superclass.
1983 if (IFace->getSuperClass())
Douglas Gregor322328b2009-11-18 22:32:06 +00001984 AddObjCProperties(IFace->getSuperClass(), AllowCategories, CurContext,
1985 Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001986 } else if (const ObjCCategoryDecl *Category
1987 = dyn_cast<ObjCCategoryDecl>(Container)) {
1988 // Look through protocols.
1989 for (ObjCInterfaceDecl::protocol_iterator P = Category->protocol_begin(),
1990 PEnd = Category->protocol_end();
1991 P != PEnd; ++P)
Douglas Gregor322328b2009-11-18 22:32:06 +00001992 AddObjCProperties(*P, AllowCategories, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00001993 }
1994}
1995
Douglas Gregor81b747b2009-09-17 21:32:03 +00001996void Sema::CodeCompleteMemberReferenceExpr(Scope *S, ExprTy *BaseE,
1997 SourceLocation OpLoc,
1998 bool IsArrow) {
1999 if (!BaseE || !CodeCompleter)
2000 return;
2001
Douglas Gregor86d9a522009-09-21 16:56:56 +00002002 typedef CodeCompleteConsumer::Result Result;
2003
Douglas Gregor81b747b2009-09-17 21:32:03 +00002004 Expr *Base = static_cast<Expr *>(BaseE);
2005 QualType BaseType = Base->getType();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002006
2007 if (IsArrow) {
2008 if (const PointerType *Ptr = BaseType->getAs<PointerType>())
2009 BaseType = Ptr->getPointeeType();
2010 else if (BaseType->isObjCObjectPointerType())
2011 /*Do nothing*/ ;
2012 else
2013 return;
2014 }
2015
Douglas Gregoreb5758b2009-09-23 22:26:46 +00002016 ResultBuilder Results(*this, &ResultBuilder::IsMember);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002017 Results.EnterNewScope();
2018 if (const RecordType *Record = BaseType->getAs<RecordType>()) {
2019 // Access to a C/C++ class, struct, or union.
Douglas Gregor45bcd432010-01-14 03:21:49 +00002020 Results.allowNestedNameSpecifiers();
Douglas Gregor0cc84042010-01-14 15:47:35 +00002021 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2022 LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002023
Douglas Gregor95ac6552009-11-18 01:29:26 +00002024 if (getLangOptions().CPlusPlus) {
2025 if (!Results.empty()) {
2026 // The "template" keyword can follow "->" or "." in the grammar.
2027 // However, we only want to suggest the template keyword if something
2028 // is dependent.
2029 bool IsDependent = BaseType->isDependentType();
2030 if (!IsDependent) {
2031 for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
2032 if (DeclContext *Ctx = (DeclContext *)DepScope->getEntity()) {
2033 IsDependent = Ctx->isDependentContext();
2034 break;
2035 }
2036 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002037
Douglas Gregor95ac6552009-11-18 01:29:26 +00002038 if (IsDependent)
Douglas Gregora4477812010-01-14 16:01:26 +00002039 Results.AddResult(Result("template"));
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002040 }
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002041 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002042 } else if (!IsArrow && BaseType->getAsObjCInterfacePointerType()) {
2043 // Objective-C property reference.
2044
2045 // Add property results based on our interface.
2046 const ObjCObjectPointerType *ObjCPtr
2047 = BaseType->getAsObjCInterfacePointerType();
2048 assert(ObjCPtr && "Non-NULL pointer guaranteed above!");
Douglas Gregor322328b2009-11-18 22:32:06 +00002049 AddObjCProperties(ObjCPtr->getInterfaceDecl(), true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002050
2051 // Add properties from the protocols in a qualified interface.
2052 for (ObjCObjectPointerType::qual_iterator I = ObjCPtr->qual_begin(),
2053 E = ObjCPtr->qual_end();
2054 I != E; ++I)
Douglas Gregor322328b2009-11-18 22:32:06 +00002055 AddObjCProperties(*I, true, CurContext, Results);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002056 } else if ((IsArrow && BaseType->isObjCObjectPointerType()) ||
2057 (!IsArrow && BaseType->isObjCInterfaceType())) {
2058 // Objective-C instance variable access.
2059 ObjCInterfaceDecl *Class = 0;
2060 if (const ObjCObjectPointerType *ObjCPtr
2061 = BaseType->getAs<ObjCObjectPointerType>())
2062 Class = ObjCPtr->getInterfaceDecl();
2063 else
2064 Class = BaseType->getAs<ObjCInterfaceType>()->getDecl();
2065
2066 // Add all ivars from this class and its superclasses.
Douglas Gregor80f4f4c2010-01-14 16:08:12 +00002067 if (Class) {
2068 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2069 Results.setFilter(&ResultBuilder::IsObjCIvar);
2070 LookupVisibleDecls(Class, LookupMemberName, Consumer);
Douglas Gregor95ac6552009-11-18 01:29:26 +00002071 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002072 }
Douglas Gregor95ac6552009-11-18 01:29:26 +00002073
2074 // FIXME: How do we cope with isa?
2075
2076 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002077
2078 // Add macros
2079 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002080 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002081
2082 // Hand off the results found for code completion.
2083 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002084}
2085
Douglas Gregor374929f2009-09-18 15:37:17 +00002086void Sema::CodeCompleteTag(Scope *S, unsigned TagSpec) {
2087 if (!CodeCompleter)
2088 return;
2089
Douglas Gregor86d9a522009-09-21 16:56:56 +00002090 typedef CodeCompleteConsumer::Result Result;
2091 ResultBuilder::LookupFilter Filter = 0;
Douglas Gregor374929f2009-09-18 15:37:17 +00002092 switch ((DeclSpec::TST)TagSpec) {
2093 case DeclSpec::TST_enum:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002094 Filter = &ResultBuilder::IsEnum;
Douglas Gregor374929f2009-09-18 15:37:17 +00002095 break;
2096
2097 case DeclSpec::TST_union:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002098 Filter = &ResultBuilder::IsUnion;
Douglas Gregor374929f2009-09-18 15:37:17 +00002099 break;
2100
2101 case DeclSpec::TST_struct:
Douglas Gregor374929f2009-09-18 15:37:17 +00002102 case DeclSpec::TST_class:
Douglas Gregor86d9a522009-09-21 16:56:56 +00002103 Filter = &ResultBuilder::IsClassOrStruct;
Douglas Gregor374929f2009-09-18 15:37:17 +00002104 break;
2105
2106 default:
2107 assert(false && "Unknown type specifier kind in CodeCompleteTag");
2108 return;
2109 }
Douglas Gregor86d9a522009-09-21 16:56:56 +00002110
2111 ResultBuilder Results(*this, Filter);
Douglas Gregor45bcd432010-01-14 03:21:49 +00002112 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002113 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2114 LookupVisibleDecls(S, LookupTagName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002115
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002116 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002117 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002118 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor374929f2009-09-18 15:37:17 +00002119}
2120
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002121void Sema::CodeCompleteCase(Scope *S) {
2122 if (getSwitchStack().empty() || !CodeCompleter)
2123 return;
2124
2125 SwitchStmt *Switch = getSwitchStack().back();
2126 if (!Switch->getCond()->getType()->isEnumeralType())
2127 return;
2128
2129 // Code-complete the cases of a switch statement over an enumeration type
2130 // by providing the list of
2131 EnumDecl *Enum = Switch->getCond()->getType()->getAs<EnumType>()->getDecl();
2132
2133 // Determine which enumerators we have already seen in the switch statement.
2134 // FIXME: Ideally, we would also be able to look *past* the code-completion
2135 // token, in case we are code-completing in the middle of the switch and not
2136 // at the end. However, we aren't able to do so at the moment.
2137 llvm::SmallPtrSet<EnumConstantDecl *, 8> EnumeratorsSeen;
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002138 NestedNameSpecifier *Qualifier = 0;
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002139 for (SwitchCase *SC = Switch->getSwitchCaseList(); SC;
2140 SC = SC->getNextSwitchCase()) {
2141 CaseStmt *Case = dyn_cast<CaseStmt>(SC);
2142 if (!Case)
2143 continue;
2144
2145 Expr *CaseVal = Case->getLHS()->IgnoreParenCasts();
2146 if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(CaseVal))
2147 if (EnumConstantDecl *Enumerator
2148 = dyn_cast<EnumConstantDecl>(DRE->getDecl())) {
2149 // We look into the AST of the case statement to determine which
2150 // enumerator was named. Alternatively, we could compute the value of
2151 // the integral constant expression, then compare it against the
2152 // values of each enumerator. However, value-based approach would not
2153 // work as well with C++ templates where enumerators declared within a
2154 // template are type- and value-dependent.
2155 EnumeratorsSeen.insert(Enumerator);
2156
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002157 // If this is a qualified-id, keep track of the nested-name-specifier
2158 // so that we can reproduce it as part of code completion, e.g.,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002159 //
2160 // switch (TagD.getKind()) {
2161 // case TagDecl::TK_enum:
2162 // break;
2163 // case XXX
2164 //
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002165 // At the XXX, our completions are TagDecl::TK_union,
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002166 // TagDecl::TK_struct, and TagDecl::TK_class, rather than TK_union,
2167 // TK_struct, and TK_class.
Douglas Gregora2813ce2009-10-23 18:54:35 +00002168 Qualifier = DRE->getQualifier();
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002169 }
2170 }
2171
Douglas Gregorb9d0ef72009-09-21 19:57:38 +00002172 if (getLangOptions().CPlusPlus && !Qualifier && EnumeratorsSeen.empty()) {
2173 // If there are no prior enumerators in C++, check whether we have to
2174 // qualify the names of the enumerators that we suggest, because they
2175 // may not be visible in this scope.
2176 Qualifier = getRequiredQualification(Context, CurContext,
2177 Enum->getDeclContext());
2178
2179 // FIXME: Scoped enums need to start with "EnumDecl" as the context!
2180 }
2181
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002182 // Add any enumerators that have not yet been mentioned.
2183 ResultBuilder Results(*this);
2184 Results.EnterNewScope();
2185 for (EnumDecl::enumerator_iterator E = Enum->enumerator_begin(),
2186 EEnd = Enum->enumerator_end();
2187 E != EEnd; ++E) {
2188 if (EnumeratorsSeen.count(*E))
2189 continue;
2190
Douglas Gregor608300b2010-01-14 16:14:35 +00002191 Results.AddResult(CodeCompleteConsumer::Result(*E, Qualifier),
2192 CurContext, 0, false);
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002193 }
2194 Results.ExitScope();
2195
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002196 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002197 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002198 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor3e1005f2009-09-21 18:10:23 +00002199}
2200
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002201namespace {
2202 struct IsBetterOverloadCandidate {
2203 Sema &S;
John McCall5769d612010-02-08 23:07:23 +00002204 SourceLocation Loc;
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002205
2206 public:
John McCall5769d612010-02-08 23:07:23 +00002207 explicit IsBetterOverloadCandidate(Sema &S, SourceLocation Loc)
2208 : S(S), Loc(Loc) { }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002209
2210 bool
2211 operator()(const OverloadCandidate &X, const OverloadCandidate &Y) const {
John McCall5769d612010-02-08 23:07:23 +00002212 return S.isBetterOverloadCandidate(X, Y, Loc);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002213 }
2214 };
2215}
2216
2217void Sema::CodeCompleteCall(Scope *S, ExprTy *FnIn,
2218 ExprTy **ArgsIn, unsigned NumArgs) {
2219 if (!CodeCompleter)
2220 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002221
2222 // When we're code-completing for a call, we fall back to ordinary
2223 // name code-completion whenever we can't produce specific
2224 // results. We may want to revisit this strategy in the future,
2225 // e.g., by merging the two kinds of results.
2226
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002227 Expr *Fn = (Expr *)FnIn;
2228 Expr **Args = (Expr **)ArgsIn;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002229
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002230 // Ignore type-dependent call expressions entirely.
2231 if (Fn->isTypeDependent() ||
Douglas Gregoref96eac2009-12-11 19:06:04 +00002232 Expr::hasAnyTypeDependentArguments(Args, NumArgs)) {
Douglas Gregor01dfea02010-01-10 23:08:15 +00002233 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002234 return;
Douglas Gregoref96eac2009-12-11 19:06:04 +00002235 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002236
John McCall3b4294e2009-12-16 12:17:52 +00002237 // Build an overload candidate set based on the functions we find.
John McCall5769d612010-02-08 23:07:23 +00002238 SourceLocation Loc = Fn->getExprLoc();
2239 OverloadCandidateSet CandidateSet(Loc);
John McCall3b4294e2009-12-16 12:17:52 +00002240
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002241 // FIXME: What if we're calling something that isn't a function declaration?
2242 // FIXME: What if we're calling a pseudo-destructor?
2243 // FIXME: What if we're calling a member function?
2244
Douglas Gregorc0265402010-01-21 15:46:19 +00002245 typedef CodeCompleteConsumer::OverloadCandidate ResultCandidate;
2246 llvm::SmallVector<ResultCandidate, 8> Results;
2247
John McCall3b4294e2009-12-16 12:17:52 +00002248 Expr *NakedFn = Fn->IgnoreParenCasts();
2249 if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(NakedFn))
2250 AddOverloadedCallCandidates(ULE, Args, NumArgs, CandidateSet,
2251 /*PartialOverloading=*/ true);
2252 else if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(NakedFn)) {
2253 FunctionDecl *FDecl = dyn_cast<FunctionDecl>(DRE->getDecl());
Douglas Gregorc0265402010-01-21 15:46:19 +00002254 if (FDecl) {
2255 if (!FDecl->getType()->getAs<FunctionProtoType>())
2256 Results.push_back(ResultCandidate(FDecl));
2257 else
John McCall86820f52010-01-26 01:37:31 +00002258 // FIXME: access?
John McCall9aa472c2010-03-19 07:35:19 +00002259 AddOverloadCandidate(FDecl, DeclAccessPair::make(FDecl, AS_none),
2260 Args, NumArgs, CandidateSet,
Douglas Gregorc0265402010-01-21 15:46:19 +00002261 false, false, /*PartialOverloading*/ true);
2262 }
John McCall3b4294e2009-12-16 12:17:52 +00002263 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002264
Douglas Gregorc0265402010-01-21 15:46:19 +00002265 if (!CandidateSet.empty()) {
2266 // Sort the overload candidate set by placing the best overloads first.
2267 std::stable_sort(CandidateSet.begin(), CandidateSet.end(),
John McCall5769d612010-02-08 23:07:23 +00002268 IsBetterOverloadCandidate(*this, Loc));
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002269
Douglas Gregorc0265402010-01-21 15:46:19 +00002270 // Add the remaining viable overload candidates as code-completion reslults.
2271 for (OverloadCandidateSet::iterator Cand = CandidateSet.begin(),
2272 CandEnd = CandidateSet.end();
2273 Cand != CandEnd; ++Cand) {
2274 if (Cand->Viable)
2275 Results.push_back(ResultCandidate(Cand->Function));
2276 }
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002277 }
Douglas Gregoref96eac2009-12-11 19:06:04 +00002278
2279 if (Results.empty())
Douglas Gregor01dfea02010-01-10 23:08:15 +00002280 CodeCompleteOrdinaryName(S, CCC_Expression);
Douglas Gregoref96eac2009-12-11 19:06:04 +00002281 else
2282 CodeCompleter->ProcessOverloadCandidates(*this, NumArgs, Results.data(),
2283 Results.size());
Douglas Gregor9c6a0e92009-09-22 15:41:20 +00002284}
2285
Douglas Gregor81b747b2009-09-17 21:32:03 +00002286void Sema::CodeCompleteQualifiedId(Scope *S, const CXXScopeSpec &SS,
2287 bool EnteringContext) {
2288 if (!SS.getScopeRep() || !CodeCompleter)
2289 return;
2290
Douglas Gregor86d9a522009-09-21 16:56:56 +00002291 DeclContext *Ctx = computeDeclContext(SS, EnteringContext);
2292 if (!Ctx)
2293 return;
Douglas Gregord1cd31a2009-12-11 18:28:39 +00002294
2295 // Try to instantiate any non-dependent declaration contexts before
2296 // we look in them.
2297 if (!isDependentScopeSpecifier(SS) && RequireCompleteDeclContext(SS))
2298 return;
2299
Douglas Gregor86d9a522009-09-21 16:56:56 +00002300 ResultBuilder Results(*this);
Douglas Gregordef91072010-01-14 03:35:48 +00002301 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2302 LookupVisibleDecls(Ctx, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002303
2304 // The "template" keyword can follow "::" in the grammar, but only
2305 // put it into the grammar if the nested-name-specifier is dependent.
2306 NestedNameSpecifier *NNS = (NestedNameSpecifier *)SS.getScopeRep();
2307 if (!Results.empty() && NNS->isDependent())
Douglas Gregora4477812010-01-14 16:01:26 +00002308 Results.AddResult("template");
Douglas Gregor86d9a522009-09-21 16:56:56 +00002309
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002310 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002311 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002312 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor81b747b2009-09-17 21:32:03 +00002313}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002314
2315void Sema::CodeCompleteUsing(Scope *S) {
2316 if (!CodeCompleter)
2317 return;
2318
Douglas Gregor86d9a522009-09-21 16:56:56 +00002319 ResultBuilder Results(*this, &ResultBuilder::IsNestedNameSpecifier);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002320 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002321
2322 // If we aren't in class scope, we could see the "namespace" keyword.
2323 if (!S->isClassScope())
Douglas Gregora4477812010-01-14 16:01:26 +00002324 Results.AddResult(CodeCompleteConsumer::Result("namespace"));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002325
2326 // After "using", we can see anything that would start a
2327 // nested-name-specifier.
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002328 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2329 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002330 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002331
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002332 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002333 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002334 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002335}
2336
2337void Sema::CodeCompleteUsingDirective(Scope *S) {
2338 if (!CodeCompleter)
2339 return;
2340
Douglas Gregor86d9a522009-09-21 16:56:56 +00002341 // After "using namespace", we expect to see a namespace name or namespace
2342 // alias.
2343 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002344 Results.EnterNewScope();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002345 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2346 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002347 Results.ExitScope();
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002348 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002349 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002350 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002351}
2352
2353void Sema::CodeCompleteNamespaceDecl(Scope *S) {
2354 if (!CodeCompleter)
2355 return;
2356
Douglas Gregor86d9a522009-09-21 16:56:56 +00002357 ResultBuilder Results(*this, &ResultBuilder::IsNamespace);
2358 DeclContext *Ctx = (DeclContext *)S->getEntity();
2359 if (!S->getParent())
2360 Ctx = Context.getTranslationUnitDecl();
2361
2362 if (Ctx && Ctx->isFileContext()) {
2363 // We only want to see those namespaces that have already been defined
2364 // within this scope, because its likely that the user is creating an
2365 // extended namespace declaration. Keep track of the most recent
2366 // definition of each namespace.
2367 std::map<NamespaceDecl *, NamespaceDecl *> OrigToLatest;
2368 for (DeclContext::specific_decl_iterator<NamespaceDecl>
2369 NS(Ctx->decls_begin()), NSEnd(Ctx->decls_end());
2370 NS != NSEnd; ++NS)
2371 OrigToLatest[NS->getOriginalNamespace()] = *NS;
2372
2373 // Add the most recent definition (or extended definition) of each
2374 // namespace to the list of results.
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002375 Results.EnterNewScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002376 for (std::map<NamespaceDecl *, NamespaceDecl *>::iterator
2377 NS = OrigToLatest.begin(), NSEnd = OrigToLatest.end();
2378 NS != NSEnd; ++NS)
Douglas Gregor608300b2010-01-14 16:14:35 +00002379 Results.AddResult(CodeCompleteConsumer::Result(NS->second, 0),
2380 CurContext, 0, false);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002381 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002382 }
2383
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002384 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002385 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002386 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002387}
2388
2389void Sema::CodeCompleteNamespaceAliasDecl(Scope *S) {
2390 if (!CodeCompleter)
2391 return;
2392
Douglas Gregor86d9a522009-09-21 16:56:56 +00002393 // After "namespace", we expect to see a namespace or alias.
2394 ResultBuilder Results(*this, &ResultBuilder::IsNamespaceOrAlias);
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002395 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2396 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002397 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002398 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002399 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002400}
2401
Douglas Gregored8d3222009-09-18 20:05:18 +00002402void Sema::CodeCompleteOperatorName(Scope *S) {
2403 if (!CodeCompleter)
2404 return;
Douglas Gregor86d9a522009-09-21 16:56:56 +00002405
2406 typedef CodeCompleteConsumer::Result Result;
2407 ResultBuilder Results(*this, &ResultBuilder::IsType);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002408 Results.EnterNewScope();
Douglas Gregored8d3222009-09-18 20:05:18 +00002409
Douglas Gregor86d9a522009-09-21 16:56:56 +00002410 // Add the names of overloadable operators.
2411#define OVERLOADED_OPERATOR(Name,Spelling,Token,Unary,Binary,MemberOnly) \
2412 if (std::strcmp(Spelling, "?")) \
Douglas Gregora4477812010-01-14 16:01:26 +00002413 Results.AddResult(Result(Spelling));
Douglas Gregor86d9a522009-09-21 16:56:56 +00002414#include "clang/Basic/OperatorKinds.def"
2415
2416 // Add any type names visible from the current scope
Douglas Gregor45bcd432010-01-14 03:21:49 +00002417 Results.allowNestedNameSpecifiers();
Douglas Gregor5d2fc402010-01-14 03:27:13 +00002418 CodeCompletionDeclConsumer Consumer(Results, CurContext);
2419 LookupVisibleDecls(S, LookupOrdinaryName, Consumer);
Douglas Gregor86d9a522009-09-21 16:56:56 +00002420
2421 // Add any type specifiers
Douglas Gregorbca403c2010-01-13 23:51:12 +00002422 AddTypeSpecifierResults(getLangOptions(), Results);
Douglas Gregor8e0a0e42009-09-22 23:31:26 +00002423 Results.ExitScope();
Douglas Gregor86d9a522009-09-21 16:56:56 +00002424
Douglas Gregor0c8296d2009-11-07 00:00:49 +00002425 if (CodeCompleter->includeMacros())
Douglas Gregorbca403c2010-01-13 23:51:12 +00002426 AddMacroResults(PP, Results);
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002427 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Douglas Gregored8d3222009-09-18 20:05:18 +00002428}
Douglas Gregor49f40bd2009-09-18 19:03:04 +00002429
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002430// Macro that expands to @Keyword or Keyword, depending on whether NeedAt is
2431// true or false.
2432#define OBJC_AT_KEYWORD_NAME(NeedAt,Keyword) NeedAt? "@" #Keyword : #Keyword
Douglas Gregorbca403c2010-01-13 23:51:12 +00002433static void AddObjCImplementationResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002434 ResultBuilder &Results,
2435 bool NeedAt) {
2436 typedef CodeCompleteConsumer::Result Result;
2437 // Since we have an implementation, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00002438 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002439
2440 CodeCompletionString *Pattern = 0;
2441 if (LangOpts.ObjC2) {
2442 // @dynamic
2443 Pattern = new CodeCompletionString;
2444 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,dynamic));
2445 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2446 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002447 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002448
2449 // @synthesize
2450 Pattern = new CodeCompletionString;
2451 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synthesize));
2452 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2453 Pattern->AddPlaceholderChunk("property");
Douglas Gregora4477812010-01-14 16:01:26 +00002454 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002455 }
2456}
2457
Douglas Gregorbca403c2010-01-13 23:51:12 +00002458static void AddObjCInterfaceResults(const LangOptions &LangOpts,
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002459 ResultBuilder &Results,
2460 bool NeedAt) {
2461 typedef CodeCompleteConsumer::Result Result;
2462
2463 // Since we have an interface or protocol, we can end it.
Douglas Gregora4477812010-01-14 16:01:26 +00002464 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,end)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002465
2466 if (LangOpts.ObjC2) {
2467 // @property
Douglas Gregora4477812010-01-14 16:01:26 +00002468 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,property)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002469
2470 // @required
Douglas Gregora4477812010-01-14 16:01:26 +00002471 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,required)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002472
2473 // @optional
Douglas Gregora4477812010-01-14 16:01:26 +00002474 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,optional)));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002475 }
2476}
2477
Douglas Gregorbca403c2010-01-13 23:51:12 +00002478static void AddObjCTopLevelResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002479 typedef CodeCompleteConsumer::Result Result;
2480 CodeCompletionString *Pattern = 0;
2481
2482 // @class name ;
2483 Pattern = new CodeCompletionString;
2484 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,class));
2485 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2486 Pattern->AddPlaceholderChunk("identifier");
2487 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +00002488 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002489
2490 // @interface name
2491 // FIXME: Could introduce the whole pattern, including superclasses and
2492 // such.
2493 Pattern = new CodeCompletionString;
2494 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,interface));
2495 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2496 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002497 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002498
2499 // @protocol name
2500 Pattern = new CodeCompletionString;
2501 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
2502 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2503 Pattern->AddPlaceholderChunk("protocol");
Douglas Gregora4477812010-01-14 16:01:26 +00002504 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002505
2506 // @implementation name
2507 Pattern = new CodeCompletionString;
2508 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,implementation));
2509 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2510 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002511 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002512
2513 // @compatibility_alias name
2514 Pattern = new CodeCompletionString;
2515 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,compatibility_alias));
2516 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2517 Pattern->AddPlaceholderChunk("alias");
2518 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
2519 Pattern->AddPlaceholderChunk("class");
Douglas Gregora4477812010-01-14 16:01:26 +00002520 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002521}
2522
Douglas Gregorc464ae82009-12-07 09:27:33 +00002523void Sema::CodeCompleteObjCAtDirective(Scope *S, DeclPtrTy ObjCImpDecl,
2524 bool InInterface) {
2525 typedef CodeCompleteConsumer::Result Result;
2526 ResultBuilder Results(*this);
2527 Results.EnterNewScope();
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002528 if (ObjCImpDecl)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002529 AddObjCImplementationResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002530 else if (InInterface)
Douglas Gregorbca403c2010-01-13 23:51:12 +00002531 AddObjCInterfaceResults(getLangOptions(), Results, false);
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002532 else
Douglas Gregorbca403c2010-01-13 23:51:12 +00002533 AddObjCTopLevelResults(Results, false);
Douglas Gregorc464ae82009-12-07 09:27:33 +00002534 Results.ExitScope();
2535 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2536}
2537
Douglas Gregorbca403c2010-01-13 23:51:12 +00002538static void AddObjCExpressionResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002539 typedef CodeCompleteConsumer::Result Result;
2540 CodeCompletionString *Pattern = 0;
2541
2542 // @encode ( type-name )
2543 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002544 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,encode));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002545 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2546 Pattern->AddPlaceholderChunk("type-name");
2547 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002548 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002549
2550 // @protocol ( protocol-name )
2551 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002552 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,protocol));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002553 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2554 Pattern->AddPlaceholderChunk("protocol-name");
2555 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002556 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002557
2558 // @selector ( selector )
2559 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002560 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,selector));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002561 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2562 Pattern->AddPlaceholderChunk("selector");
2563 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
Douglas Gregora4477812010-01-14 16:01:26 +00002564 Results.AddResult(Result(Pattern));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002565}
2566
Douglas Gregorbca403c2010-01-13 23:51:12 +00002567static void AddObjCStatementResults(ResultBuilder &Results, bool NeedAt) {
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002568 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002569 CodeCompletionString *Pattern = 0;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002570
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002571 // @try { statements } @catch ( declaration ) { statements } @finally
2572 // { statements }
2573 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002574 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,try));
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002575 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2576 Pattern->AddPlaceholderChunk("statements");
2577 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2578 Pattern->AddTextChunk("@catch");
2579 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2580 Pattern->AddPlaceholderChunk("parameter");
2581 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2582 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2583 Pattern->AddPlaceholderChunk("statements");
2584 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
2585 Pattern->AddTextChunk("@finally");
2586 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2587 Pattern->AddPlaceholderChunk("statements");
2588 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00002589 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002590
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002591 // @throw
2592 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002593 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,throw));
Douglas Gregor834389b2010-01-12 06:38:28 +00002594 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002595 Pattern->AddPlaceholderChunk("expression");
Douglas Gregor834389b2010-01-12 06:38:28 +00002596 Pattern->AddChunk(CodeCompletionString::CK_SemiColon);
Douglas Gregora4477812010-01-14 16:01:26 +00002597 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002598
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002599 // @synchronized ( expression ) { statements }
2600 Pattern = new CodeCompletionString;
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002601 Pattern->AddTypedTextChunk(OBJC_AT_KEYWORD_NAME(NeedAt,synchronized));
Douglas Gregor834389b2010-01-12 06:38:28 +00002602 Pattern->AddChunk(CodeCompletionString::CK_HorizontalSpace);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002603 Pattern->AddChunk(CodeCompletionString::CK_LeftParen);
2604 Pattern->AddPlaceholderChunk("expression");
2605 Pattern->AddChunk(CodeCompletionString::CK_RightParen);
2606 Pattern->AddChunk(CodeCompletionString::CK_LeftBrace);
2607 Pattern->AddPlaceholderChunk("statements");
2608 Pattern->AddChunk(CodeCompletionString::CK_RightBrace);
Douglas Gregora4477812010-01-14 16:01:26 +00002609 Results.AddResult(Result(Pattern));
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002610}
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002611
Douglas Gregorbca403c2010-01-13 23:51:12 +00002612static void AddObjCVisibilityResults(const LangOptions &LangOpts,
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002613 ResultBuilder &Results,
2614 bool NeedAt) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002615 typedef CodeCompleteConsumer::Result Result;
Douglas Gregora4477812010-01-14 16:01:26 +00002616 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,private)));
2617 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,protected)));
2618 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,public)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002619 if (LangOpts.ObjC2)
Douglas Gregora4477812010-01-14 16:01:26 +00002620 Results.AddResult(Result(OBJC_AT_KEYWORD_NAME(NeedAt,package)));
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002621}
2622
2623void Sema::CodeCompleteObjCAtVisibility(Scope *S) {
2624 ResultBuilder Results(*this);
2625 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002626 AddObjCVisibilityResults(getLangOptions(), Results, false);
Douglas Gregorc38c3e12010-01-13 21:54:15 +00002627 Results.ExitScope();
2628 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2629}
2630
2631void Sema::CodeCompleteObjCAtStatement(Scope *S) {
Douglas Gregorb6ac2452010-01-13 21:24:21 +00002632 ResultBuilder Results(*this);
2633 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002634 AddObjCStatementResults(Results, false);
2635 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002636 Results.ExitScope();
2637 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2638}
2639
2640void Sema::CodeCompleteObjCAtExpression(Scope *S) {
2641 ResultBuilder Results(*this);
2642 Results.EnterNewScope();
Douglas Gregorbca403c2010-01-13 23:51:12 +00002643 AddObjCExpressionResults(Results, false);
Douglas Gregor9a0c85e2009-12-07 09:51:25 +00002644 Results.ExitScope();
2645 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
2646}
2647
Douglas Gregor988358f2009-11-19 00:14:45 +00002648/// \brief Determine whether the addition of the given flag to an Objective-C
2649/// property's attributes will cause a conflict.
2650static bool ObjCPropertyFlagConflicts(unsigned Attributes, unsigned NewFlag) {
2651 // Check if we've already added this flag.
2652 if (Attributes & NewFlag)
2653 return true;
2654
2655 Attributes |= NewFlag;
2656
2657 // Check for collisions with "readonly".
2658 if ((Attributes & ObjCDeclSpec::DQ_PR_readonly) &&
2659 (Attributes & (ObjCDeclSpec::DQ_PR_readwrite |
2660 ObjCDeclSpec::DQ_PR_assign |
2661 ObjCDeclSpec::DQ_PR_copy |
2662 ObjCDeclSpec::DQ_PR_retain)))
2663 return true;
2664
2665 // Check for more than one of { assign, copy, retain }.
2666 unsigned AssignCopyRetMask = Attributes & (ObjCDeclSpec::DQ_PR_assign |
2667 ObjCDeclSpec::DQ_PR_copy |
2668 ObjCDeclSpec::DQ_PR_retain);
2669 if (AssignCopyRetMask &&
2670 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_assign &&
2671 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_copy &&
2672 AssignCopyRetMask != ObjCDeclSpec::DQ_PR_retain)
2673 return true;
2674
2675 return false;
2676}
2677
Douglas Gregora93b1082009-11-18 23:08:07 +00002678void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) {
Steve Naroffece8e712009-10-08 21:55:05 +00002679 if (!CodeCompleter)
2680 return;
Douglas Gregord3c68542009-11-19 01:08:35 +00002681
Steve Naroffece8e712009-10-08 21:55:05 +00002682 unsigned Attributes = ODS.getPropertyAttributes();
2683
2684 typedef CodeCompleteConsumer::Result Result;
2685 ResultBuilder Results(*this);
2686 Results.EnterNewScope();
Douglas Gregor988358f2009-11-19 00:14:45 +00002687 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readonly))
Douglas Gregora4477812010-01-14 16:01:26 +00002688 Results.AddResult(CodeCompleteConsumer::Result("readonly"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002689 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_assign))
Douglas Gregora4477812010-01-14 16:01:26 +00002690 Results.AddResult(CodeCompleteConsumer::Result("assign"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002691 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_readwrite))
Douglas Gregora4477812010-01-14 16:01:26 +00002692 Results.AddResult(CodeCompleteConsumer::Result("readwrite"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002693 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_retain))
Douglas Gregora4477812010-01-14 16:01:26 +00002694 Results.AddResult(CodeCompleteConsumer::Result("retain"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002695 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_copy))
Douglas Gregora4477812010-01-14 16:01:26 +00002696 Results.AddResult(CodeCompleteConsumer::Result("copy"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002697 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_nonatomic))
Douglas Gregora4477812010-01-14 16:01:26 +00002698 Results.AddResult(CodeCompleteConsumer::Result("nonatomic"));
Douglas Gregor988358f2009-11-19 00:14:45 +00002699 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_setter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002700 CodeCompletionString *Setter = new CodeCompletionString;
2701 Setter->AddTypedTextChunk("setter");
2702 Setter->AddTextChunk(" = ");
2703 Setter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00002704 Results.AddResult(CodeCompleteConsumer::Result(Setter));
Douglas Gregor54f01612009-11-19 00:01:57 +00002705 }
Douglas Gregor988358f2009-11-19 00:14:45 +00002706 if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_getter)) {
Douglas Gregor54f01612009-11-19 00:01:57 +00002707 CodeCompletionString *Getter = new CodeCompletionString;
2708 Getter->AddTypedTextChunk("getter");
2709 Getter->AddTextChunk(" = ");
2710 Getter->AddPlaceholderChunk("method");
Douglas Gregora4477812010-01-14 16:01:26 +00002711 Results.AddResult(CodeCompleteConsumer::Result(Getter));
Douglas Gregor54f01612009-11-19 00:01:57 +00002712 }
Steve Naroffece8e712009-10-08 21:55:05 +00002713 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002714 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffece8e712009-10-08 21:55:05 +00002715}
Steve Naroffc4df6d22009-11-07 02:08:14 +00002716
Douglas Gregor4ad96852009-11-19 07:41:15 +00002717/// \brief Descripts the kind of Objective-C method that we want to find
2718/// via code completion.
2719enum ObjCMethodKind {
2720 MK_Any, //< Any kind of method, provided it means other specified criteria.
2721 MK_ZeroArgSelector, //< Zero-argument (unary) selector.
2722 MK_OneArgSelector //< One-argument selector.
2723};
2724
2725static bool isAcceptableObjCMethod(ObjCMethodDecl *Method,
2726 ObjCMethodKind WantKind,
2727 IdentifierInfo **SelIdents,
2728 unsigned NumSelIdents) {
2729 Selector Sel = Method->getSelector();
2730 if (NumSelIdents > Sel.getNumArgs())
2731 return false;
2732
2733 switch (WantKind) {
2734 case MK_Any: break;
2735 case MK_ZeroArgSelector: return Sel.isUnarySelector();
2736 case MK_OneArgSelector: return Sel.getNumArgs() == 1;
2737 }
2738
2739 for (unsigned I = 0; I != NumSelIdents; ++I)
2740 if (SelIdents[I] != Sel.getIdentifierInfoForSlot(I))
2741 return false;
2742
2743 return true;
2744}
2745
Douglas Gregor36ecb042009-11-17 23:22:23 +00002746/// \brief Add all of the Objective-C methods in the given Objective-C
2747/// container to the set of results.
2748///
2749/// The container will be a class, protocol, category, or implementation of
2750/// any of the above. This mether will recurse to include methods from
2751/// the superclasses of classes along with their categories, protocols, and
2752/// implementations.
2753///
2754/// \param Container the container in which we'll look to find methods.
2755///
2756/// \param WantInstance whether to add instance methods (only); if false, this
2757/// routine will add factory methods (only).
2758///
2759/// \param CurContext the context in which we're performing the lookup that
2760/// finds methods.
2761///
2762/// \param Results the structure into which we'll add results.
2763static void AddObjCMethods(ObjCContainerDecl *Container,
2764 bool WantInstanceMethods,
Douglas Gregor4ad96852009-11-19 07:41:15 +00002765 ObjCMethodKind WantKind,
Douglas Gregord3c68542009-11-19 01:08:35 +00002766 IdentifierInfo **SelIdents,
2767 unsigned NumSelIdents,
Douglas Gregor36ecb042009-11-17 23:22:23 +00002768 DeclContext *CurContext,
2769 ResultBuilder &Results) {
2770 typedef CodeCompleteConsumer::Result Result;
2771 for (ObjCContainerDecl::method_iterator M = Container->meth_begin(),
2772 MEnd = Container->meth_end();
2773 M != MEnd; ++M) {
Douglas Gregord3c68542009-11-19 01:08:35 +00002774 if ((*M)->isInstanceMethod() == WantInstanceMethods) {
2775 // Check whether the selector identifiers we've been given are a
2776 // subset of the identifiers for this particular method.
Douglas Gregor4ad96852009-11-19 07:41:15 +00002777 if (!isAcceptableObjCMethod(*M, WantKind, SelIdents, NumSelIdents))
Douglas Gregord3c68542009-11-19 01:08:35 +00002778 continue;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002779
Douglas Gregord3c68542009-11-19 01:08:35 +00002780 Result R = Result(*M, 0);
2781 R.StartParameter = NumSelIdents;
Douglas Gregor4ad96852009-11-19 07:41:15 +00002782 R.AllParametersAreInformative = (WantKind != MK_Any);
Douglas Gregord3c68542009-11-19 01:08:35 +00002783 Results.MaybeAddResult(R, CurContext);
2784 }
Douglas Gregor36ecb042009-11-17 23:22:23 +00002785 }
2786
2787 ObjCInterfaceDecl *IFace = dyn_cast<ObjCInterfaceDecl>(Container);
2788 if (!IFace)
2789 return;
2790
2791 // Add methods in protocols.
2792 const ObjCList<ObjCProtocolDecl> &Protocols= IFace->getReferencedProtocols();
2793 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2794 E = Protocols.end();
2795 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002796 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents, NumSelIdents,
Douglas Gregord3c68542009-11-19 01:08:35 +00002797 CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002798
2799 // Add methods in categories.
2800 for (ObjCCategoryDecl *CatDecl = IFace->getCategoryList(); CatDecl;
2801 CatDecl = CatDecl->getNextClassCategory()) {
Douglas Gregor4ad96852009-11-19 07:41:15 +00002802 AddObjCMethods(CatDecl, WantInstanceMethods, WantKind, SelIdents,
2803 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002804
2805 // Add a categories protocol methods.
2806 const ObjCList<ObjCProtocolDecl> &Protocols
2807 = CatDecl->getReferencedProtocols();
2808 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
2809 E = Protocols.end();
2810 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00002811 AddObjCMethods(*I, WantInstanceMethods, WantKind, SelIdents,
2812 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002813
2814 // Add methods in category implementations.
2815 if (ObjCCategoryImplDecl *Impl = CatDecl->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002816 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2817 NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002818 }
2819
2820 // Add methods in superclass.
2821 if (IFace->getSuperClass())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002822 AddObjCMethods(IFace->getSuperClass(), WantInstanceMethods, WantKind,
2823 SelIdents, NumSelIdents, CurContext, Results);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002824
2825 // Add methods in our implementation, if any.
2826 if (ObjCImplementationDecl *Impl = IFace->getImplementation())
Douglas Gregor4ad96852009-11-19 07:41:15 +00002827 AddObjCMethods(Impl, WantInstanceMethods, WantKind, SelIdents,
2828 NumSelIdents, CurContext, Results);
2829}
2830
2831
2832void Sema::CodeCompleteObjCPropertyGetter(Scope *S, DeclPtrTy ClassDecl,
2833 DeclPtrTy *Methods,
2834 unsigned NumMethods) {
2835 typedef CodeCompleteConsumer::Result Result;
2836
2837 // Try to find the interface where getters might live.
2838 ObjCInterfaceDecl *Class
2839 = dyn_cast_or_null<ObjCInterfaceDecl>(ClassDecl.getAs<Decl>());
2840 if (!Class) {
2841 if (ObjCCategoryDecl *Category
2842 = dyn_cast_or_null<ObjCCategoryDecl>(ClassDecl.getAs<Decl>()))
2843 Class = Category->getClassInterface();
2844
2845 if (!Class)
2846 return;
2847 }
2848
2849 // Find all of the potential getters.
2850 ResultBuilder Results(*this);
2851 Results.EnterNewScope();
2852
2853 // FIXME: We need to do this because Objective-C methods don't get
2854 // pushed into DeclContexts early enough. Argh!
2855 for (unsigned I = 0; I != NumMethods; ++I) {
2856 if (ObjCMethodDecl *Method
2857 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2858 if (Method->isInstanceMethod() &&
2859 isAcceptableObjCMethod(Method, MK_ZeroArgSelector, 0, 0)) {
2860 Result R = Result(Method, 0);
2861 R.AllParametersAreInformative = true;
2862 Results.MaybeAddResult(R, CurContext);
2863 }
2864 }
2865
2866 AddObjCMethods(Class, true, MK_ZeroArgSelector, 0, 0, CurContext, Results);
2867 Results.ExitScope();
2868 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
2869}
2870
2871void Sema::CodeCompleteObjCPropertySetter(Scope *S, DeclPtrTy ObjCImplDecl,
2872 DeclPtrTy *Methods,
2873 unsigned NumMethods) {
2874 typedef CodeCompleteConsumer::Result Result;
2875
2876 // Try to find the interface where setters might live.
2877 ObjCInterfaceDecl *Class
2878 = dyn_cast_or_null<ObjCInterfaceDecl>(ObjCImplDecl.getAs<Decl>());
2879 if (!Class) {
2880 if (ObjCCategoryDecl *Category
2881 = dyn_cast_or_null<ObjCCategoryDecl>(ObjCImplDecl.getAs<Decl>()))
2882 Class = Category->getClassInterface();
2883
2884 if (!Class)
2885 return;
2886 }
2887
2888 // Find all of the potential getters.
2889 ResultBuilder Results(*this);
2890 Results.EnterNewScope();
2891
2892 // FIXME: We need to do this because Objective-C methods don't get
2893 // pushed into DeclContexts early enough. Argh!
2894 for (unsigned I = 0; I != NumMethods; ++I) {
2895 if (ObjCMethodDecl *Method
2896 = dyn_cast_or_null<ObjCMethodDecl>(Methods[I].getAs<Decl>()))
2897 if (Method->isInstanceMethod() &&
2898 isAcceptableObjCMethod(Method, MK_OneArgSelector, 0, 0)) {
2899 Result R = Result(Method, 0);
2900 R.AllParametersAreInformative = true;
2901 Results.MaybeAddResult(R, CurContext);
2902 }
2903 }
2904
2905 AddObjCMethods(Class, true, MK_OneArgSelector, 0, 0, CurContext, Results);
2906
2907 Results.ExitScope();
2908 HandleCodeCompleteResults(this, CodeCompleter,Results.data(),Results.size());
Douglas Gregor36ecb042009-11-17 23:22:23 +00002909}
2910
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002911void Sema::CodeCompleteObjCClassMessage(Scope *S, IdentifierInfo *FName,
Douglas Gregord3c68542009-11-19 01:08:35 +00002912 SourceLocation FNameLoc,
2913 IdentifierInfo **SelIdents,
2914 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002915 typedef CodeCompleteConsumer::Result Result;
Douglas Gregor24a069f2009-11-17 17:59:40 +00002916 ObjCInterfaceDecl *CDecl = 0;
2917
Douglas Gregor24a069f2009-11-17 17:59:40 +00002918 if (FName->isStr("super")) {
2919 // We're sending a message to "super".
2920 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
2921 // Figure out which interface we're in.
2922 CDecl = CurMethod->getClassInterface();
2923 if (!CDecl)
2924 return;
2925
2926 // Find the superclass of this class.
2927 CDecl = CDecl->getSuperClass();
2928 if (!CDecl)
2929 return;
2930
2931 if (CurMethod->isInstanceMethod()) {
2932 // We are inside an instance method, which means that the message
2933 // send [super ...] is actually calling an instance method on the
2934 // current object. Build the super expression and handle this like
2935 // an instance method.
2936 QualType SuperTy = Context.getObjCInterfaceType(CDecl);
2937 SuperTy = Context.getObjCObjectPointerType(SuperTy);
2938 OwningExprResult Super
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002939 = Owned(new (Context) ObjCSuperExpr(FNameLoc, SuperTy));
Douglas Gregord3c68542009-11-19 01:08:35 +00002940 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2941 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002942 }
2943
2944 // Okay, we're calling a factory method in our superclass.
2945 }
2946 }
2947
2948 // If the given name refers to an interface type, retrieve the
2949 // corresponding declaration.
2950 if (!CDecl)
Douglas Gregor60b01cc2009-11-17 23:31:36 +00002951 if (TypeTy *Ty = getTypeName(*FName, FNameLoc, S, 0, false)) {
Douglas Gregor24a069f2009-11-17 17:59:40 +00002952 QualType T = GetTypeFromParser(Ty, 0);
2953 if (!T.isNull())
2954 if (const ObjCInterfaceType *Interface = T->getAs<ObjCInterfaceType>())
2955 CDecl = Interface->getDecl();
2956 }
2957
2958 if (!CDecl && FName->isStr("super")) {
2959 // "super" may be the name of a variable, in which case we are
2960 // probably calling an instance method.
John McCallf7a1a742009-11-24 19:00:30 +00002961 CXXScopeSpec SS;
2962 UnqualifiedId id;
2963 id.setIdentifier(FName, FNameLoc);
2964 OwningExprResult Super = ActOnIdExpression(S, SS, id, false, false);
Douglas Gregord3c68542009-11-19 01:08:35 +00002965 return CodeCompleteObjCInstanceMessage(S, (Expr *)Super.get(),
2966 SelIdents, NumSelIdents);
Douglas Gregor24a069f2009-11-17 17:59:40 +00002967 }
2968
Douglas Gregor36ecb042009-11-17 23:22:23 +00002969 // Add all of the factory methods in this Objective-C class, its protocols,
2970 // superclasses, categories, implementation, etc.
Steve Naroffc4df6d22009-11-07 02:08:14 +00002971 ResultBuilder Results(*this);
2972 Results.EnterNewScope();
Douglas Gregor4ad96852009-11-19 07:41:15 +00002973 AddObjCMethods(CDecl, false, MK_Any, SelIdents, NumSelIdents, CurContext,
2974 Results);
Steve Naroffc4df6d22009-11-07 02:08:14 +00002975 Results.ExitScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00002976
Steve Naroffc4df6d22009-11-07 02:08:14 +00002977 // This also suppresses remaining diagnostics.
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00002978 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00002979}
2980
Douglas Gregord3c68542009-11-19 01:08:35 +00002981void Sema::CodeCompleteObjCInstanceMessage(Scope *S, ExprTy *Receiver,
2982 IdentifierInfo **SelIdents,
2983 unsigned NumSelIdents) {
Steve Naroffc4df6d22009-11-07 02:08:14 +00002984 typedef CodeCompleteConsumer::Result Result;
Steve Naroffc4df6d22009-11-07 02:08:14 +00002985
2986 Expr *RecExpr = static_cast<Expr *>(Receiver);
Steve Naroffc4df6d22009-11-07 02:08:14 +00002987
Douglas Gregor36ecb042009-11-17 23:22:23 +00002988 // If necessary, apply function/array conversion to the receiver.
2989 // C99 6.7.5.3p[7,8].
Douglas Gregora873dfc2010-02-03 00:27:59 +00002990 DefaultFunctionArrayLvalueConversion(RecExpr);
Douglas Gregor36ecb042009-11-17 23:22:23 +00002991 QualType ReceiverType = RecExpr->getType();
Steve Naroffc4df6d22009-11-07 02:08:14 +00002992
Douglas Gregor36ecb042009-11-17 23:22:23 +00002993 if (ReceiverType->isObjCIdType() || ReceiverType->isBlockPointerType()) {
2994 // FIXME: We're messaging 'id'. Do we actually want to look up every method
2995 // in the universe?
2996 return;
2997 }
2998
Douglas Gregor36ecb042009-11-17 23:22:23 +00002999 // Build the set of methods we can see.
3000 ResultBuilder Results(*this);
3001 Results.EnterNewScope();
Douglas Gregor36ecb042009-11-17 23:22:23 +00003002
Douglas Gregorf74a4192009-11-18 00:06:18 +00003003 // Handle messages to Class. This really isn't a message to an instance
3004 // method, so we treat it the same way we would treat a message send to a
3005 // class method.
3006 if (ReceiverType->isObjCClassType() ||
3007 ReceiverType->isObjCQualifiedClassType()) {
3008 if (ObjCMethodDecl *CurMethod = getCurMethodDecl()) {
3009 if (ObjCInterfaceDecl *ClassDecl = CurMethod->getClassInterface())
Douglas Gregor4ad96852009-11-19 07:41:15 +00003010 AddObjCMethods(ClassDecl, false, MK_Any, SelIdents, NumSelIdents,
3011 CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003012 }
3013 }
3014 // Handle messages to a qualified ID ("id<foo>").
3015 else if (const ObjCObjectPointerType *QualID
3016 = ReceiverType->getAsObjCQualifiedIdType()) {
3017 // Search protocols for instance methods.
3018 for (ObjCObjectPointerType::qual_iterator I = QualID->qual_begin(),
3019 E = QualID->qual_end();
3020 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003021 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3022 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003023 }
3024 // Handle messages to a pointer to interface type.
3025 else if (const ObjCObjectPointerType *IFacePtr
3026 = ReceiverType->getAsObjCInterfacePointerType()) {
3027 // Search the class, its superclasses, etc., for instance methods.
Douglas Gregor4ad96852009-11-19 07:41:15 +00003028 AddObjCMethods(IFacePtr->getInterfaceDecl(), true, MK_Any, SelIdents,
3029 NumSelIdents, CurContext, Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003030
3031 // Search protocols for instance methods.
3032 for (ObjCObjectPointerType::qual_iterator I = IFacePtr->qual_begin(),
3033 E = IFacePtr->qual_end();
3034 I != E; ++I)
Douglas Gregor4ad96852009-11-19 07:41:15 +00003035 AddObjCMethods(*I, true, MK_Any, SelIdents, NumSelIdents, CurContext,
3036 Results);
Douglas Gregorf74a4192009-11-18 00:06:18 +00003037 }
3038
Steve Naroffc4df6d22009-11-07 02:08:14 +00003039 Results.ExitScope();
Daniel Dunbar3a2838d2009-11-13 08:58:20 +00003040 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
Steve Naroffc4df6d22009-11-07 02:08:14 +00003041}
Douglas Gregor55385fe2009-11-18 04:19:12 +00003042
3043/// \brief Add all of the protocol declarations that we find in the given
3044/// (translation unit) context.
3045static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
Douglas Gregor083128f2009-11-18 04:49:41 +00003046 bool OnlyForwardDeclarations,
Douglas Gregor55385fe2009-11-18 04:19:12 +00003047 ResultBuilder &Results) {
3048 typedef CodeCompleteConsumer::Result Result;
3049
3050 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3051 DEnd = Ctx->decls_end();
3052 D != DEnd; ++D) {
3053 // Record any protocols we find.
3054 if (ObjCProtocolDecl *Proto = dyn_cast<ObjCProtocolDecl>(*D))
Douglas Gregor083128f2009-11-18 04:49:41 +00003055 if (!OnlyForwardDeclarations || Proto->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003056 Results.AddResult(Result(Proto, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003057
3058 // Record any forward-declared protocols we find.
3059 if (ObjCForwardProtocolDecl *Forward
3060 = dyn_cast<ObjCForwardProtocolDecl>(*D)) {
3061 for (ObjCForwardProtocolDecl::protocol_iterator
3062 P = Forward->protocol_begin(),
3063 PEnd = Forward->protocol_end();
3064 P != PEnd; ++P)
Douglas Gregor083128f2009-11-18 04:49:41 +00003065 if (!OnlyForwardDeclarations || (*P)->isForwardDecl())
Douglas Gregor608300b2010-01-14 16:14:35 +00003066 Results.AddResult(Result(*P, 0), CurContext, 0, false);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003067 }
3068 }
3069}
3070
3071void Sema::CodeCompleteObjCProtocolReferences(IdentifierLocPair *Protocols,
3072 unsigned NumProtocols) {
3073 ResultBuilder Results(*this);
3074 Results.EnterNewScope();
3075
3076 // Tell the result set to ignore all of the protocols we have
3077 // already seen.
3078 for (unsigned I = 0; I != NumProtocols; ++I)
3079 if (ObjCProtocolDecl *Protocol = LookupProtocol(Protocols[I].first))
3080 Results.Ignore(Protocol);
3081
3082 // Add all protocols.
Douglas Gregor083128f2009-11-18 04:49:41 +00003083 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, false,
3084 Results);
3085
3086 Results.ExitScope();
3087 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3088}
3089
3090void Sema::CodeCompleteObjCProtocolDecl(Scope *) {
3091 ResultBuilder Results(*this);
3092 Results.EnterNewScope();
3093
3094 // Add all protocols.
3095 AddProtocolResults(Context.getTranslationUnitDecl(), CurContext, true,
3096 Results);
Douglas Gregor55385fe2009-11-18 04:19:12 +00003097
3098 Results.ExitScope();
3099 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3100}
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003101
3102/// \brief Add all of the Objective-C interface declarations that we find in
3103/// the given (translation unit) context.
3104static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
3105 bool OnlyForwardDeclarations,
3106 bool OnlyUnimplemented,
3107 ResultBuilder &Results) {
3108 typedef CodeCompleteConsumer::Result Result;
3109
3110 for (DeclContext::decl_iterator D = Ctx->decls_begin(),
3111 DEnd = Ctx->decls_end();
3112 D != DEnd; ++D) {
3113 // Record any interfaces we find.
3114 if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(*D))
3115 if ((!OnlyForwardDeclarations || Class->isForwardDecl()) &&
3116 (!OnlyUnimplemented || !Class->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003117 Results.AddResult(Result(Class, 0), CurContext, 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003118
3119 // Record any forward-declared interfaces we find.
3120 if (ObjCClassDecl *Forward = dyn_cast<ObjCClassDecl>(*D)) {
3121 for (ObjCClassDecl::iterator C = Forward->begin(), CEnd = Forward->end();
3122 C != CEnd; ++C)
3123 if ((!OnlyForwardDeclarations || C->getInterface()->isForwardDecl()) &&
3124 (!OnlyUnimplemented || !C->getInterface()->getImplementation()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003125 Results.AddResult(Result(C->getInterface(), 0), CurContext,
3126 0, false);
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003127 }
3128 }
3129}
3130
3131void Sema::CodeCompleteObjCInterfaceDecl(Scope *S) {
3132 ResultBuilder Results(*this);
3133 Results.EnterNewScope();
3134
3135 // Add all classes.
3136 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, true,
3137 false, Results);
3138
3139 Results.ExitScope();
3140 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3141}
3142
3143void Sema::CodeCompleteObjCSuperclass(Scope *S, IdentifierInfo *ClassName) {
3144 ResultBuilder Results(*this);
3145 Results.EnterNewScope();
3146
3147 // Make sure that we ignore the class we're currently defining.
3148 NamedDecl *CurClass
3149 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003150 if (CurClass && isa<ObjCInterfaceDecl>(CurClass))
Douglas Gregor3b49aca2009-11-18 16:26:39 +00003151 Results.Ignore(CurClass);
3152
3153 // Add all classes.
3154 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3155 false, Results);
3156
3157 Results.ExitScope();
3158 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3159}
3160
3161void Sema::CodeCompleteObjCImplementationDecl(Scope *S) {
3162 ResultBuilder Results(*this);
3163 Results.EnterNewScope();
3164
3165 // Add all unimplemented classes.
3166 AddInterfaceResults(Context.getTranslationUnitDecl(), CurContext, false,
3167 true, Results);
3168
3169 Results.ExitScope();
3170 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3171}
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003172
3173void Sema::CodeCompleteObjCInterfaceCategory(Scope *S,
3174 IdentifierInfo *ClassName) {
3175 typedef CodeCompleteConsumer::Result Result;
3176
3177 ResultBuilder Results(*this);
3178
3179 // Ignore any categories we find that have already been implemented by this
3180 // interface.
3181 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3182 NamedDecl *CurClass
3183 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3184 if (ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass))
3185 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3186 Category = Category->getNextClassCategory())
3187 CategoryNames.insert(Category->getIdentifier());
3188
3189 // Add all of the categories we know about.
3190 Results.EnterNewScope();
3191 TranslationUnitDecl *TU = Context.getTranslationUnitDecl();
3192 for (DeclContext::decl_iterator D = TU->decls_begin(),
3193 DEnd = TU->decls_end();
3194 D != DEnd; ++D)
3195 if (ObjCCategoryDecl *Category = dyn_cast<ObjCCategoryDecl>(*D))
3196 if (CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003197 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003198 Results.ExitScope();
3199
3200 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3201}
3202
3203void Sema::CodeCompleteObjCImplementationCategory(Scope *S,
3204 IdentifierInfo *ClassName) {
3205 typedef CodeCompleteConsumer::Result Result;
3206
3207 // Find the corresponding interface. If we couldn't find the interface, the
3208 // program itself is ill-formed. However, we'll try to be helpful still by
3209 // providing the list of all of the categories we know about.
3210 NamedDecl *CurClass
3211 = LookupSingleName(TUScope, ClassName, LookupOrdinaryName);
3212 ObjCInterfaceDecl *Class = dyn_cast_or_null<ObjCInterfaceDecl>(CurClass);
3213 if (!Class)
3214 return CodeCompleteObjCInterfaceCategory(S, ClassName);
3215
3216 ResultBuilder Results(*this);
3217
3218 // Add all of the categories that have have corresponding interface
3219 // declarations in this class and any of its superclasses, except for
3220 // already-implemented categories in the class itself.
3221 llvm::SmallPtrSet<IdentifierInfo *, 16> CategoryNames;
3222 Results.EnterNewScope();
3223 bool IgnoreImplemented = true;
3224 while (Class) {
3225 for (ObjCCategoryDecl *Category = Class->getCategoryList(); Category;
3226 Category = Category->getNextClassCategory())
3227 if ((!IgnoreImplemented || !Category->getImplementation()) &&
3228 CategoryNames.insert(Category->getIdentifier()))
Douglas Gregor608300b2010-01-14 16:14:35 +00003229 Results.AddResult(Result(Category, 0), CurContext, 0, false);
Douglas Gregor33ced0b2009-11-18 19:08:43 +00003230
3231 Class = Class->getSuperClass();
3232 IgnoreImplemented = false;
3233 }
3234 Results.ExitScope();
3235
3236 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3237}
Douglas Gregor322328b2009-11-18 22:32:06 +00003238
Douglas Gregor424b2a52009-11-18 22:56:13 +00003239void Sema::CodeCompleteObjCPropertyDefinition(Scope *S, DeclPtrTy ObjCImpDecl) {
Douglas Gregor322328b2009-11-18 22:32:06 +00003240 typedef CodeCompleteConsumer::Result Result;
3241 ResultBuilder Results(*this);
3242
3243 // Figure out where this @synthesize lives.
3244 ObjCContainerDecl *Container
3245 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3246 if (!Container ||
3247 (!isa<ObjCImplementationDecl>(Container) &&
3248 !isa<ObjCCategoryImplDecl>(Container)))
3249 return;
3250
3251 // Ignore any properties that have already been implemented.
3252 for (DeclContext::decl_iterator D = Container->decls_begin(),
3253 DEnd = Container->decls_end();
3254 D != DEnd; ++D)
3255 if (ObjCPropertyImplDecl *PropertyImpl = dyn_cast<ObjCPropertyImplDecl>(*D))
3256 Results.Ignore(PropertyImpl->getPropertyDecl());
3257
3258 // Add any properties that we find.
3259 Results.EnterNewScope();
3260 if (ObjCImplementationDecl *ClassImpl
3261 = dyn_cast<ObjCImplementationDecl>(Container))
3262 AddObjCProperties(ClassImpl->getClassInterface(), false, CurContext,
3263 Results);
3264 else
3265 AddObjCProperties(cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl(),
3266 false, CurContext, Results);
3267 Results.ExitScope();
3268
3269 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3270}
3271
3272void Sema::CodeCompleteObjCPropertySynthesizeIvar(Scope *S,
3273 IdentifierInfo *PropertyName,
3274 DeclPtrTy ObjCImpDecl) {
3275 typedef CodeCompleteConsumer::Result Result;
3276 ResultBuilder Results(*this);
3277
3278 // Figure out where this @synthesize lives.
3279 ObjCContainerDecl *Container
3280 = dyn_cast_or_null<ObjCContainerDecl>(ObjCImpDecl.getAs<Decl>());
3281 if (!Container ||
3282 (!isa<ObjCImplementationDecl>(Container) &&
3283 !isa<ObjCCategoryImplDecl>(Container)))
3284 return;
3285
3286 // Figure out which interface we're looking into.
3287 ObjCInterfaceDecl *Class = 0;
3288 if (ObjCImplementationDecl *ClassImpl
3289 = dyn_cast<ObjCImplementationDecl>(Container))
3290 Class = ClassImpl->getClassInterface();
3291 else
3292 Class = cast<ObjCCategoryImplDecl>(Container)->getCategoryDecl()
3293 ->getClassInterface();
3294
3295 // Add all of the instance variables in this class and its superclasses.
3296 Results.EnterNewScope();
3297 for(; Class; Class = Class->getSuperClass()) {
3298 // FIXME: We could screen the type of each ivar for compatibility with
3299 // the property, but is that being too paternal?
3300 for (ObjCInterfaceDecl::ivar_iterator IVar = Class->ivar_begin(),
3301 IVarEnd = Class->ivar_end();
3302 IVar != IVarEnd; ++IVar)
Douglas Gregor608300b2010-01-14 16:14:35 +00003303 Results.AddResult(Result(*IVar, 0), CurContext, 0, false);
Douglas Gregor322328b2009-11-18 22:32:06 +00003304 }
3305 Results.ExitScope();
3306
3307 HandleCodeCompleteResults(this, CodeCompleter, Results.data(),Results.size());
3308}